copyied importexport from trunk

This commit is contained in:
Ralf Becker 2010-09-05 16:00:01 +00:00
commit 961b7a4284
54 changed files with 5147 additions and 0 deletions

View File

@ -0,0 +1,59 @@
= importexport =
Importexport is a framework for egroupware to handle imports and exports.
The idea behind importexport is to have a common userinterface in all apps
regarding import and export stuff AND to have common backends whitch
handle the stuff. Importexport can nothing without the plugins of the
applications and its specific definitions.
== plugins ==
Attending importeport framework with you application is pretty easy.
You just need to have your plugins in files which start with
class.import_<name> or
class.export_<name>
in
EGW_INCLUDE_ROOT/YourApp/importexport/
These pulugins only need to implement the corresponding interface
EGW_INCLUDE_ROOT/importexport/inc/class.iface_import_plugin.inc.php or
EGW_INCLUDE_ROOT/importexport/inc/class.iface_export_plugin.inc.php
Thats all, pretty easy, isn't it?
== definitions ==
The bases of all imports and exports is the '''definition'''.
A definition defines all nessesary parameters to perform the desired action.
Moreover definitions can be stored and thus the same import / export can be redone
by loading the definition. Definitions are also reachable by the importexport
'''command line interface'''.
An important point is, that the ACLs for import/export actions are given by the definitions.
That means, that your plugin can not work w.o. a definition. However, your plugin don't
need to parse that definition. This is up to you.
Definitions can be created in admin->importexport->define{im|ex}ports. They are stored
in the databasae but could be {im|ex}ported itselve.
Definitions (as xml files) residing in the folder <yourapp/importexport/definitions>
will be imported at apps installation time automatically.
== import ==
== export ==
Starting an export is as easy as just putting a button in your app with:
onClick="importexport.uiexport.export_dialog&appname=<appname>&have_selection=<{true|false}>"
If parameter "have_selection" if true, export askes (javascript) opener.get_selection();to retreave
a list of identifiers of selected records.
NOTE: javascript function get_selection() is the only function which is not part of an interface yet.
==Discussion of interfaces==
To make live easy there are several general plugins which can be found
EGW_INCLUDE_ROOT/importexport/inc/import_...
EGW_INCLUDE_ROOT/importexport/inc/export_...

164
importexport/importexport_cli.php Executable file
View File

@ -0,0 +1,164 @@
#!/usr/bin/php -q
<?php
/**
* eGroupWare - importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
$path_to_egroupware = realpath(dirname(__FILE__).'/..');
$usage = "usage:
--definition <name of definition> Name of definition
--file <name of file> File to import / for export
--user <eGW username> eGroupWare username for action
--password <password for user> users password
--domain <domain name> eGroupWare domain
--dry-run no real action, just console output
\n";
if (php_sapi_name() != 'cli') {
die('This script only runs form command line');
}
// Include PEAR::Console_Getopt
require_once 'Console/Getopt.php';
// Define exit codes for errors
define('HEADER_NOT_FOUND',9);
define('NO_ARGS',10);
define('INVALID_OPTION',11);
// Reading the incoming arguments - same as $argv
$args = Console_Getopt::readPHPArgv();
// Make sure we got them (for non CLI binaries)
if (PEAR::isError($args)) {
fwrite(STDERR,"importexport_cli: ".$args->getMessage()."\n".$usage);
exit(NO_ARGS);
}
// Short options
$short_opts = 'f:d:';
// Long options
$long_opts = array(
'definition=',
'file=',
'user=',
'password=',
'domain=',
'dry-run',
);
// Convert the arguments to options - check for the first argument
if ( realpath($_SERVER['argv'][0]) == __FILE__ ) {
$options = Console_Getopt::getOpt($args,$short_opts,$long_opts);
} else {
$options = Console_Getopt::getOpt2($args,$short_opts,$long_opts);
}
// Check the options are valid
if (PEAR::isError($options)) {
fwrite(STDERR,"importexport_cli: ".$options->getMessage()."\n".$usage."\n");
exit(INVALID_OPTION);
}
$domain = 'default';
$dryrun = false;
foreach ($options[0] as $option) {
switch ($option[0]) {
case '--file' :
$file = $option[1];
break;
case '--definition' :
$definition = $option[1];
break;
case '--domain' :
$domain = $option[1];
break;
case '--user' :
$user = $option[1];
break;
case '--password' :
$password = $option[1];
break;
case '--dry-run' :
$dryrun = true;
break;
default :
fwrite (STDERR,$usage."\n");
exit(INVALID_OPTION);
}
}
// check file
if ( !$user || !$password ) {
fwrite(STDERR,'importexport_cli: You have to supply a username / password'."\n".$usage);
exit(INVALID_OPTION);
}
$GLOBALS['egw_info']['flags'] = array(
'disable_Template_class' => True,
'noheader' => True,
'nonavbar' => True,
'currentapp' => 'importexport',
'autocreate_session_callback' => 'import_export_access',
'login' => $user,
'passwd' => $password,
'noapi' => True,
);
if (!is_readable($path_to_egroupware.'/header.inc.php'))
{
fwrite(STDERR,"importexport.php: Could not find '$path_to_egroupware/header.inc.php', exiting !!!\n");
exit(HEADER_NOT_FOUND);
}
include($path_to_egroupware.'/header.inc.php');
unset($GLOBALS['egw_info']['flags']['noapi']);
// check domain
$db_type = $GLOBALS['egw_domain'][$domain]['db_type'];
if (!isset($GLOBALS['egw_domain'][$domain]) || empty($db_type))
{
fwrite(STDERR,"importexport_cli: ". $domain. ' is not a valid domain name'."\n");
exit(INVALID_OPTION);
}
$GLOBALS['egw_info']['server']['sessions_type'] = 'db'; // no php4-sessions availible for cgi
include(EGW_API_INC.'/functions.inc.php');
// check file
if (!is_readable($file))
{
fwrite(STDERR,"importexport_cli: ". $file. ' is not readable'."\n");
exit(INVALID_OPTION);
}
$definition = new importexport_definition($definition);
if( $definition->get_identifier() < 1 ) {
fwrite(STDERR,"importexport_cli: Definition not found! \n");
exit(INVALID_OPTION);
}
$GLOBALS['egw_info']['flags']['currentapp'] = $definition->application;
$definition->plugin_options['dry_run'] = $dryrun;
$type = $definition->type;
$po = new $definition->plugin;
$resource = fopen( $file, 'r' );
$po->$type( $resource, $definition );
$GLOBALS['egw']->common->phpgw_exit();
function import_export_access(&$account)
{
$account['login'] = $GLOBALS['egw_info']['flags']['login'];
$account['passwd'] = $GLOBALS['egw_info']['flags']['passwd'];
$account['passwd_type'] = 'text';
return true;
}

Binary file not shown.

View File

@ -0,0 +1,73 @@
<?php
/**
* eGroupWare - importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
if (!defined('IMPORTEXPORT_APP'))
{
define('IMPORTEXPORT_APP','importexport');
}
class importexport_admin_prefs_sidebox_hooks
{
static function all_hooks($args)
{
$appname = IMPORTEXPORT_APP;
$location = is_array($args) ? $args['location'] : $args;
if ($GLOBALS['egw_info']['user']['apps']['preferences'] && $location != 'admin')
{
$file = array(
array(
'text' => 'Import',
'link' => "javascript:egw_openWindowCentered2('".
egw::link('/index.php','menuaction=importexport.importexport_import_ui.import_dialog',false).
"','_blank',850,440,'yes')",
'icon' => 'import'
),
array(
'text' => 'Export',
'link' => "javascript:egw_openWindowCentered2('".
egw::link('/index.php','menuaction=importexport.importexport_export_ui.export_dialog',false).
"','_blank',850,440,'yes')",
'icon' => 'export'
),
);
if ($location == 'preferences')
{
display_section($appname,$file);
}
else
{
display_sidebox($appname,lang($appname),$file);
}
}
if ($GLOBALS['egw_info']['user']['apps']['admin'] && $location != 'preferences')
{
$file = Array(
'Import definitions' => egw::link('/index.php','menuaction=importexport.importexport_definitions_ui.import_definition'),
'Define imports|exports' => egw::link('/index.php',array(
'menuaction' => 'importexport.importexport_definitions_ui.index',
)),
'Schedule' => egw::link('/index.php', array(
'menuaction' => 'importexport.importexport_schedule_ui.index'
)),
);
if ($location == 'admin')
{
display_section($appname,$file);
}
else
{
display_sidebox($appname,lang('Admin'),$file);
}
}
}
}

View File

@ -0,0 +1,111 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id: $
*/
/**
* class arrayxml
* easy to use array2xml and xml2array functions. Presumably this is the n+1
* class of this kind out there, but i wasn't able to find a wokring one...
*
* @abstract PHP allowes array keys to be numeric while XML prohibits this.
* Therefore the XML structur of this class is a bit uncommon but nessesary!
* @todo deal with other types like objects
* @static only namespace here
*/
class importexport_arrayxml {
/**
* converts a php array to an xml string
*
* @param mixed $_data
* @param string $_name
* @param DOMElement $_node
* @return string XML string
*/
public static function array2xml ( $_data, $_name = 'root', $_node=null ) {
$returnXML = false;
if ( $_node === null ) {
$_node = new DOMDocument( '1.0', 'utf-8' );
$_node->formatOutput = true;
$returnXML = true;
}
$datatype = gettype( $_data );
switch ( $datatype ) {
case 'array' :
$subnode = new DOMElement( 'entry' );
$_node->appendChild( $subnode );
$subnode->setAttribute( 'type', $datatype );
$subnode->setAttribute( 'name' , $_name );
foreach ( $_data as $ikey => $ivalue ) {
self::array2xml( $ivalue, $ikey, $subnode );
}
break;
default :
switch ( $datatype ) {
case 'boolean' :
$data = $_data !== false ? 'TRUE' : 'FALSE';
break;
default:
$data = &$_data;
}
$subnode = new DOMElement( 'entry' , $data );
$_node->appendChild( $subnode );
$subnode->setAttribute( 'type', $datatype );
$subnode->setAttribute( 'name' , $_name );
break;
}
return $returnXML ? $_node->saveXML() : '';
}
/**
* converts XML string into php array
*
* @param string $_xml
* @return array
*/
public static function xml2array( $_xml ) {
if ( $_xml instanceof DOMElement ) {
$n = &$_xml;
} else {
$n = new DOMDocument;
$n->loadXML($_xml);
}
$xml_array = array();
foreach($n->childNodes as $nc) {
if ( $nc->nodeType != XML_ELEMENT_NODE ) continue;
$name = $nc->attributes->getNamedItem('name')->nodeValue;
$type = $nc->attributes->getNamedItem('type')->nodeValue;
//echo $nc->nodeType. "(length ): ". $nc->nodeName. " => ". $nc->nodeValue. "; Attriubtes: name=$name, type=$type \n ";
if( $nc->childNodes->length >= 2) {
$xml_array[$name] = self::xml2array($nc);
} else {
switch ( $type ) {
case 'boolean' :
$value = $nc->nodeValue == 'FALSE' ? false : true;
break;
default :
$value = $nc->nodeValue;
}
$xml_array[$name] = $value;
}
}
return $xml_array;
}
}
?>

View File

@ -0,0 +1,278 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Nathan Gray
*/
/**
* A basic CSV import plugin.
*
* You should extend this class to implement the various bits, but combined with the basic wizard
* should get you started on building a CSV plugin for an application fairly quickly.
*
*/
abstract class importexport_basic_import_csv implements importexport_iface_import_plugin {
protected static $plugin_options = array(
'fieldsep', // char
'charset', // string
'contact_owner', // int
'update_cats', // string {override|add} overides record
// with cat(s) from csv OR add the cat from
// csv file to exeisting cat(s) of record
'num_header_lines', // int number of header lines
'field_conversion', // array( $csv_col_num => conversion)
'field_mapping', // array( $csv_col_num => adb_filed)
'conditions', /* => array containing condition arrays:
'type' => exists, // exists
'string' => '#kundennummer',
'true' => array(
'action' => update,
'last' => true,
),
'false' => array(
'action' => insert,
'last' => true,
),*/
);
/**
* Actions wich could be done to data entries
* If your plugin supports different actions, be sure to modify this array
*/
protected static $actions = array( 'none', 'update', 'insert', 'delete', );
/**
* Conditions for actions
* If your plugin supports different conditions, be sure to modify this array
*
* @var array
*/
protected static $conditions = array( 'exists', 'greater', 'greater or equal', );
/**
* This is the definition that will be used to deal with the CSV file
* @var definition
*/
protected $definition;
/**
* @var bool
*/
protected $dry_run = false;
/**
* @var bool is current user admin?
*/
protected $is_admin = false;
/**
* @var int
*/
protected $user = null;
/**
* List of import errors
*/
protected $errors = array();
/**
* List of actions, and how many times that action was taken
*/
protected $results = array();
/**
* imports entries according to given definition object.
* @param resource $_stream
* @param string $_charset
* @param definition $_definition
*/
public function import( $_stream, importexport_definition $_definition ) {
$import_csv = new importexport_import_csv( $_stream, array(
'fieldsep' => $_definition->plugin_options['fieldsep'],
'charset' => $_definition->plugin_options['charset'],
));
$this->definition = $_definition;
// user, is admin ?
$this->is_admin = isset( $GLOBALS['egw_info']['user']['apps']['admin'] ) && $GLOBALS['egw_info']['user']['apps']['admin'];
$this->user = $GLOBALS['egw_info']['user']['account_id'];
// dry run?
$this->dry_run = isset( $_definition->plugin_options['dry_run'] ) ? $_definition->plugin_options['dry_run'] : false;
// set FieldMapping.
$import_csv->mapping = $_definition->plugin_options['field_mapping'];
// set FieldConversion
$import_csv->conversion = $_definition->plugin_options['field_conversion'];
//check if file has a header lines
if ( isset( $_definition->plugin_options['num_header_lines'] ) && $_definition->plugin_options['num_header_lines'] > 0) {
$import_csv->skip_records($_definition->plugin_options['num_header_lines']);
} elseif(isset($_definition->plugin_options['has_header_line']) && $_definition->plugin_options['has_header_line']) {
// First method is preferred
$import_csv->skip_records(1);
}
// set eventOwner
$_definition->plugin_options['contact_owner'] = isset( $_definition->plugin_options['contact_owner'] ) ?
$_definition->plugin_options['contact_owner'] : $this->user;
// Start counting successes
$count = 0;
$this->results = array();
// Failures
$this->errors = array();
while ( $record = $import_csv->get_record() ) {
$success = false;
// don't import empty records
if( count( array_unique( $record ) ) < 2 ) continue;
$record['owner'] = $this->_definition->plugin_options['contact_owner'];
$success = $this->import_record($record, $import_csv);
if($success) $count++;
}
return $count;
}
/**
* Import a single record
*
* You don't need to worry about mappings or translations, they've been done already.
* You do need to handle the conditions and the actions taken.
*/
protected abstract function import_record(&$record, &$import_csv);
/* Example stub:
{
if ( $this->_definition->plugin_options['conditions'] ) {
foreach ( $this->_definition->plugin_options['conditions'] as $condition ) {
switch ( $condition['type'] ) {
// exists
case 'exists' :
// Check for that record
// Apply true action to any matching records found
$action = $condition['true'];
$success = ($this->action( $action['action'], $record, $import_csv->get_current_position() ));
// Apply false action if no matching records found
$action = $condition['false'];
$success = ($this->action( $action['action'], $record, $import_csv->get_current_position() ));
break;
// not supported action
default :
die('condition / action not supported!!!');
break;
}
if ($action['last']) break;
}
} else {
// unconditional insert
$success = $this->action( 'insert', $record, $import_csv->get_current_position() );
}
return $success;
}
*/
/**
* perform the required action
*
* Make sure you record any errors you encounter here:
* $this->errors[$record_num] = error message;
*
* @param int $_action one of $this->actions
* @param array $_data contact data for the action
* @param int $record_num Which record number is being dealt with. Used for error messages.
* @return bool success or not
*/
protected abstract function action ( $_action, Array $_data, $record_num = 0 );
/**
* returns translated name of plugin
*
* @return string name
*/
public static function get_name() {
return lang('Basic CSV import');
}
/**
* returns translated (user) description of plugin
*
* @return string descriprion
*/
public static function get_description() {
return lang("Imports information from a CSV file. This is only a base class, and doesn't do anything on its own.");
}
/**
* retruns file suffix(s) plugin can handle (e.g. csv)
*
* @return string suffix (comma seperated)
*/
public static function get_filesuffix() {
return 'csv';
}
/**
* return etemplate components for options.
* @abstract We can't deal with etemplate objects here, as an uietemplate
* objects itself are scipt orientated and not "dialog objects"
*
* @return array (
* name => string,
* content => array,
* sel_options => array,
* preserv => array,
* )
*/
public function get_options_etpl() {
// lets do it!
}
/**
* returns etemplate name for slectors of this plugin
*
* @return string etemplate name
*/
public function get_selectors_etpl() {
// lets do it!
}
/**
* Returns errors that were encountered during importing
* Maximum of one error message per record, but you can append if you need to
*
* @return Array (
* record_# => error message
* )
*/
public function get_errors() {
return $this->errors;
}
/**
* Returns a list of actions taken, and the number of records for that action.
* Actions are things like 'insert', 'update', 'delete', and may be different for each plugin.
*
* @return Array (
* action => record count
* )
*/
public function get_results() {
return $this->results;
}
} // end of iface_export_plugin
?>

View File

@ -0,0 +1,310 @@
<?php
/**
* eGroupWare importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class definition
*
* definitions are ojects with all nessesary information to do
* complete import or export. All options needed for an explicit {Im|Ex}port
* are in one assiozative array which is complely managed by {Im|Ex}port plugins
* @todo testing
*/
class importexport_definition implements importexport_iface_egw_record {
const _appname = 'importexport';
const _defintion_talbe = 'egw_importexport_definitions';
private $attributes = array(
'definition_id' => 'string',
'name' => 'string',
'application' => 'string',
'plugin' => 'string',
'type' => 'string',
'allowed_users' => 'array',
'plugin_options' => 'array',
'owner' => 'int',
'description' => 'string',
);
/**
* @var so_sql holds so_sql object
*/
private $so_sql;
/**
* @var array internal representation of definition
*/
private $definition = array();
/**
* @var int holds current user
*/
private $user;
/**
* @var bool is current user an admin?
*/
private $is_admin;
/**
* constructor
* reads record from backend if identifier is given.
*
* @param string $_identifier
*/
public function __construct( $_identifier='' ) {
$this->so_sql = new so_sql(self::_appname ,self::_defintion_talbe);
$this->user = $GLOBALS['egw_info']['user']['user_id'];
$this->is_admin = $GLOBALS['egw_info']['user']['apps']['admin'] ? true : false;
// compability to string identifiers
if (is_string($_identifier) && strlen($_identifier) > 3) $_identifier = $this->name2identifier($_identifier);
if ((int)$_identifier != 0) {
$this->definition = $this->so_sql->read(array('definition_id' => $_identifier));
if ( empty( $this->definition ) ) {
throw new Exception('Error: No such definition with identifier :"'.$_identifier.'"!');
}
if ( !( in_array( $this->user, $this->get_allowed_users() ) || $this->definition['owner'] == $this->user || $this->is_admin)) {
throw new Exception('Error: User "'.$this->user.'" is not permitted to get definition with identifier "'.$_identifier.'"!');
}
$options_data = importexport_arrayxml::xml2array( $this->definition['plugin_options'] );
$this->definition['plugin_options'] = $options_data['root'];
}
}
/**
* compability function for string identifiers e.g. used by cli
*
* @param string $_name
* @return int
*/
private function name2identifier( $_name ) {
$identifiers = $this->so_sql->search(array('name' => $_name),true);
if (isset($identifiers[1])) {
throw new Exception('Error: Definition: "'.$_name. '" is not unique! Can\'t convert to identifier');
}
if ( empty( $identifiers[0] ) ) {
// not a good idea, till we don't have different exceptions so far
// throw new Exception('Error: No such definition :"'.$_name.'"!');
$identifiers = array( array( 'definition_id' => 0 ) );
}
return $identifiers[0]['definition_id'];
}
public function __get($_attribute_name) {
if (!array_key_exists($_attribute_name,$this->attributes)) {
throw new Exception('Error: "'. $_attribute_name. '" is not an attribute defintion');
}
switch ($_attribute_name) {
case 'allowed_users' :
return $this->get_allowed_users();
case 'plugin_options' :
return $this->get_options();
default :
return $this->definition[$_attribute_name];
}
}
public function __set($_attribute_name,$_data) {
if (!array_key_exists($_attribute_name,$this->attributes)) {
throw new Exception('Error: "'. $_attribute_name. '" is not an attribute defintion');
}
switch ($_attribute_name) {
case 'allowed_users' :
return $this->set_allowed_users($_data);
case 'plugin_options' :
return $this->set_options($_data);
default :
$this->definition[$_attribute_name] = $_data;
return;
}
}
/**
* gets users who are allowd to use this definition
*
* @return array
*/
private function get_allowed_users() {
return explode(',',$this->definition['allowed_users']);
}
/**
* sets allowed users
*
* @param array $_allowed_users
*/
private function set_allowed_users( $_allowed_users ) {
$this->definition['allowed_users'] = implode(',',(array)$_allowed_users);
}
/**
* gets options
*
* @return array
*/
private function get_options() {
return $this->definition['plugin_options'];
}
/**
* sets options
*
* @param array $options
*/
private function set_options(array $_plugin_options) {
$this->definition['plugin_options'] = $_plugin_options;
}
/**
* converts this object to array.
* @abstract We need such a function cause PHP5
* dosn't allow objects do define it's own casts :-(
* once PHP can deal with object casts we will change to them!
*
* @return array complete record as associative array
*/
public function get_record_array() {
$definition = $this->definition;
$definition['allowed_users'] = $this->get_allowed_users();
$definition['plugin_options'] = $this->get_options();
return $definition;
}
/**
* gets title of record
*
*@return string tiltle
*/
public function get_title() {
return $this->definition['name'];
}
/**
* sets complete record from associative array
*
* @return void
*/
public function set_record( array $_record ) {
$this->definition = array_intersect_key( $_record, $this->attributes );
// anything which is not an attribute is perhaps a plugin_option.
// If not, it gets whiped out on save time.
foreach ( $_record as $attribute => $value) {
if ( !array_key_exists( $attribute, $this->attributes ) ) {
$this->definition['plugin_options'][$attribute] = $value;
}
}
$this->plugin = $_record['plugin'];
// convert plugin_options into internal representation
$this->set_allowed_users( $this->definition['allowed_users'] );
$this->set_options( $this->definition['plugin_options'] ? $this->definition['plugin_options'] : array());
}
/**
* gets identifier of this record
*
* @return int identifier of this record
*/
public function get_identifier() {
return $this->definition['definition_id'];
}
/**
* saves record into backend
*
* @return string identifier
*/
public function save ( $_dst_identifier ) {
if ( strlen($this->definition['name']) < 3 ) {
throw new Exception('Error: Can\'t save definition, no valid name given!');
}
$this->so_sql->data = $this->definition;
$this->so_sql->data['plugin_options'] = importexport_arrayxml::array2xml( $this->definition['plugin_options'] );
if ($this->so_sql->save( array( 'definition_id' => $_dst_identifier ))) {
throw new Exception('Error: so_sql was not able to save definition: '.$this->get_identifier());
}
return $this->definition['definition_id'];
}
/**
* copys current record to record identified by $_dst_identifier
*
* @param string $_dst_identifier
* @return string dst_identifier
*/
public function copy ( $_dst_identifier ) {
$dst_object = clone $this;
try {
$dst_object->set_owner($this->user);
$dst_identifier = $dst_object->save($_dst_identifier);
}
catch(exception $Exception) {
unset($dst_object);
throw $Exception;
}
unset ($dst_object);
return $dst_identifier;
}
/**
* moves current record to record identified by $_dst_identifier
* $this will become moved record
*
* @param string $_dst_identifier
* @return string dst_identifier
*/
public function move ( $_dst_identifier ) {
if ($this->user != $this->get_owner() && !$this->is_admin) {
throw('Error: User '. $this->user. 'does not have permissions to move definition '.$this->get_identifier());
}
$old_object = clone $this;
try {
$dst_identifier = $this->save($_dst_identifier);
$old_object->delete();
}
catch(exception $Exception) {
unset($old_object);
throw $Exception;
}
unset($old_object);
return $dst_identifier;
}
/**
* delets current record from backend
* @return void
*
*/
public function delete () {
if($this->user != $this->get_owner() && !$this->is_admin) {
throw('Error: User '. $this->user. 'does not have permissions to delete definition '.$this->get_identifier());
}
if(!$this->so_sql->delete()) {
throw('Error: so_sql was not able to delete definition: '.$this->get_identifier());
}
}
/**
* destructor
*
*/
public function __destruct() {
unset($this->so_sql);
}
}

View File

@ -0,0 +1,176 @@
<?php
/**
* eGroupWare - importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/** bo to define {im|ex}ports
*
* @todo make this class an egw_record_pool!
*/
class importexport_definitions_bo {
const _appname = 'importexport';
const _defintion_table = 'egw_importexport_definitions';
/**
* @var so_sql holds so_sql
*/
private $so_sql;
/**
* @var array hold definitions
*/
private $definitions;
public function __construct($_query=false)
{
$this->so_sql = new so_sql(self::_appname, self::_defintion_table );
if ($_query) {
$definitions = $this->so_sql->search($_query, true);
foreach ((array)$definitions as $definition) {
$this->definitions[] = $definition['definition_id'];
}
}
}
/**
* gets array of definition ids
*
* @return array
*/
public function get_definitions() {
return $this->definitions;
}
public function read($definition_id) {
$definition = new importexport_definition( $definition_id['name'] );
return $definition->get_record_array();
}
/**
* deletes a defintion
*
* @param array $keys
*/
public function delete($keys) {
$this->so_sql->delete(array('definition_id' => $keys));
// clear private cache
foreach ($keys as $key) {
unset($this->definitions[array_search($key,$this->definitions)]);
}
}
/**
* Save a definition
*
* @param definition $definition
*/
public function save(Array $data) {
$definition = new importexport_definition();
$definition->set_record($data);
$definition->save($data['definition_id']);
}
/**
* checkes if user if permitted to access given definition
*
* @param array $_definition
* @return bool
*/
static public function is_permitted($_definition) {
$allowed_user = explode(',',$_definition['allowed_users']);
$this_user_id = $GLOBALS['egw_info']['user']['userid'];
$this_membership = $GLOBALS['egw']->accounts->membership($this_user_id);
$this_membership[] = array('account_id' => $this_user_id);
//echo $this_user_id;
//echo ' '.$this_membership;
foreach ((array)$this_membership as $account)
{
$this_membership_array[] = $account['account_id'];
}
$alluser = array_intersect($allowed_user,$this_membership_array);
return in_array($this_user_id,$alluser) ? true : false;
}
/**
* exports definitions
*
* @param array $keys to export
*/
public function export($keys)
{
$export_data = array('metainfo' => array(
'type' => 'importexport definitions',
'charset' => translation::charset(),
'entries' => count($keys),
));
$export_data['definitions'] = array();
foreach ($keys as $definition_id) {
$definition = new importexport_definition( $definition_id );
$export_data['definitions'][$definition->name] = $definition->get_record_array();
$export_data['definitions'][$definition->name]['allowed_users'] =
importexport_helper_functions::account_id2name(
$export_data['definitions'][$definition->name]['allowed_users']
);
$export_data['definitions'][$definition->name]['owner'] =
importexport_helper_functions::account_id2name(
$export_data['definitions'][$definition->name]['owner']
);
unset($export_data['definitions'][$definition->name]['definition_id']);
unset($definition);
}
$xml = new importexport_arrayxml();
return $xml->array2xml($export_data, 'importExportDefinitions');
}
/**
* imports definitions from file
*
* @param string $import_file
* @throws Exeption
* @return void
*/
public static function import( $_import_file )
{
if ( !is_file( $_import_file ) ) {
throw new Exception("'$_import_file' does not exist or is not readable" );
}
$data = importexport_arrayxml::xml2array( file_get_contents( $_import_file ) );
$metainfo = $data['importExportDefinitions']['metainfo'];
$definitions = $data['importExportDefinitions']['definitions'];
unset ( $data );
// convert charset into internal used charset
$definitions = translation::convert(
$definitions,
$metainfo['charset'],
translation::charset()
);
// save definition(s) into internal table
foreach ( $definitions as $name => $definition_data )
{
// convert allowed_user
$definition_data['allowed_users'] = importexport_helper_functions::account_name2id( $definition_data['allowed_users'] );
$definition_data['owner'] = importexport_helper_functions::account_name2id( $definition_data['owner'] );
$definition = new importexport_definition( $definition_data['name'] );
$definition_id = $definition->get_identifier() ? $definition->get_identifier() : NULL;
$definition->set_record( $definition_data );
$definition->save( $definition_id );
}
}
}

View File

@ -0,0 +1,493 @@
<?php
/**
* eGroupWare - importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* Userinterface to define {im|ex}ports
*
* @package importexport
*/
class importexport_definitions_ui
{
const _debug = false;
const _appname = 'importexport';
public $public_functions = array(
'edit' => true,
'index' => true,
'wizard' => true,
'import_definition' => true,
);
/**
* holds all available plugins
*
* @var array
*/
var $plugins;
/**
* holds user chosen plugin after step20
*
* @var object
*/
var $plugin;
/**
* xajax response object
*
* @var object
*/
var $response = true;
function __construct()
{
// we cant deal with notice and warnings, as we are on ajax!
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
$GLOBALS['egw']->translation->add_app(self::_appname);
$GLOBALS['egw_info']['flags']['currentapp'] = self::_appname;
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
$this->etpl = new etemplate();
$this->clock = html::image(self::_appname,'clock');
$this->steps = array(
'wizard_step10' => lang('Choose an application'),
'wizard_step20' => lang('Choose a plugin'),
'wizard_step21' => lang('Choose a name for this definition'),
'wizard_step90' => lang('Which users are allowed to use this definition'),
'wizard_finish' => '',
);
//register plugins
$this->plugins = importexport_helper_functions::get_plugins();
}
/**
* List defined {im|ex}ports
*
* @param array $content=null
*/
function index($content = null,$msg='')
{
$bodefinitions = new importexport_definitions_bo(array('name' => '*'));
if (is_array($content))
{
if (isset($content['delete']))
{
$bodefinitions->delete(array_keys($content['delete'],'pressed'));
}
elseif(($button = array_search('pressed',$content)) !== false)
{
$selected = array_keys($content['selected'],1);
if(count($selected) < 1 || !is_array($selected)) exit();
switch ($button)
{
case 'delete_selected' :
$bodefinitions->delete($selected);
break;
case 'export_selected' :
$mime_type = ($GLOBALS['egw']->html->user_agent == 'msie' || $GLOBALS['egw']->html->user_agent == 'opera') ?
'application/octetstream' : 'application/octet-stream';
$name = 'importexport_definition.xml';
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
echo $bodefinitions->export($selected);
exit();
break;
default:
}
}
}
$etpl = new etemplate(self::_appname.'.definition_index');
// we need an offset because of autocontinued rows in etemplate ...
$definitions = array('row0');
foreach ($bodefinitions->get_definitions() as $identifier) {
$definition = new importexport_definition($identifier);
$definitions[] = $definition->get_record_array();
unset($definition);
}
$content = $definitions;
return $etpl->exec( self::_appname.'.importexport_definitions_ui.index', $content, array(), $readonlys, $preserv );
}
function edit()
{
if(!$_definition = $_GET['definition'])
{
//close window
}
$definition = array('name' => $_definition);
$bodefinitions = new importexport_definitions_bo();
$definition = $bodefinitions->read($definition);
$definition['edit'] = true;
$this->wizard($definition);
}
function wizard($content = null, $msg='')
{
$GLOBALS['egw_info']['flags']['java_script'] .=
"<script type='text/javascript'>
function xajax_eT_wrapper_init() {
//window.resizeTo(document.documentElement.scrollWidth+20,document.documentElement.offsetHeight+40);
window.moveTo(screen.availWidth/2 - window.outerWidth/2,
screen.availHeight/2 - window.outerHeight/2);
}
</script>";
$this->etpl->read('importexport.wizardbox');
$this->wizard_content_template =& $this->etpl->children[0]['data'][1]['A'][2][1]['name'];
if(is_array($content) &&! $content['edit'])
{
if(self::_debug) error_log('importexport.wizard->$content '. print_r($content,true));
// fetch plugin object
if($content['plugin'] && $content['application'])
{
$wizard_name = $content['application'] . '_wizard_' . str_replace($content['application'] . '_', '', $content['plugin']);
// we need to deal with the wizard object if exists
if (file_exists(EGW_SERVER_ROOT . '/'. $content['application'].'/importexport/class.wizard_'. $content['plugin'].'.inc.php'))
{
error_log('Deprecated location for importexport wizard. Please move it to app/inc/ and rename it to follow new conventions');
}
elseif (file_exists(EGW_SERVER_ROOT . '/'. $content['application']."/inc/class.$wizard_name.inc.php"))
{
$wizard_plugin = $wizard_name;
}
else
{
$wizard_plugin = $content['plugin'];
}
$this->plugin = is_object($GLOBALS['egw']->$wizard_plugin) ? $GLOBALS['egw']->$wizard_plugin : new $wizard_plugin;
// Global object needs to be the same, or references to plugin don't work
if(!is_object($GLOBALS['egw']->importexport_definitions_ui) || $GLOBALS['egw']->importexport_definitions_ui !== $this)
$GLOBALS['egw']->importexport_definitions_ui =& $this;
}
// deal with buttons even if we are not on ajax
if(isset($content['button']) && array_search('pressed',$content['button']) === false && count($content['button']) == 1)
{
$button = array_keys($content['button']);
$content['button'] = array($button[0] => 'pressed');
}
// Override next button on step 21, to do a regular submit for the file upload
if($content['step'] == 'wizard_step21') {
$this->etpl->set_cell_attribute('button[next]', 'onclick', '');
}
// post process submitted step
if($content['step']) {
if(!key_exists($content['step'],$this->steps))
$next_step = $this->plugin->$content['step']($content);
else
$next_step = $this->$content['step']($content);
} else {
die('Cannot find next step');
}
// pre precess next step
$sel_options = $readonlys = $preserv = array();
// Disable finish button if required fields are missing
if(!$content['name'] || !$content['type'] || !$content['plugin']) {
$GLOBALS['egw']->js->set_onload("disable_button('exec[button][finish]');");
}
if(!key_exists($next_step,$this->steps))
{
$this->wizard_content_template = $this->plugin->$next_step($content,$sel_options,$readonlys,$preserv);
}
else
{
$this->wizard_content_template = $this->$next_step($content,$sel_options,$readonlys,$preserv);
}
$html = $this->etpl->exec(self::_appname.'.importexport_definitions_ui.wizard',$content,$sel_options,$readonlys,$preserv,1);
}
else
{
// initial content
$GLOBALS['egw']->js->set_onload("xajax_eT_wrapper_init();");
$GLOBALS['egw']->js->set_onload("disable_button('exec[button][previous]');");
$sel_options = $readonlys = $preserv = array();
if($content['edit'])
unset ($content['edit']);
$this->wizard_content_template = $this->wizard_step10($content, $sel_options, $readonlys, $preserv);
$html = $this->etpl->exec(self::_appname.'.importexport_definitions_ui.wizard',$content,$sel_options,$readonlys,$preserv,1);
}
if(class_exists('xajaxResponse'))
{
$this->response = new xajaxResponse();
if ($content['closewindow'])
{
$this->response->addScript("window.close();");
$this->response->addScript("opener.location.reload();");
// If Browser can't close window we display a "close" buuton and
// need to disable normal buttons
$this->response->addAssign('exec[button][previous]','style.display', 'none');
$this->response->addAssign('exec[button][next]','style.display', 'none');
$this->response->addAssign('exec[button][finish]','style.display', 'none');
$this->response->addAssign('exec[button][cancel]','style.display', 'none');
}
$this->response->addAssign('contentbox', 'innerHTML', $html);
if (($onload = $GLOBALS['egw']->js->set_onload('')))
{
$this->response->addScript($onload);
}
$this->response->addAssign('picturebox', 'style.display', 'none');
$this->response->addScript("set_style_by_class('div','popupManual','display','inline');");
return $this->response->getXML();
}
else
{
$GLOBALS['egw']->js->set_onload("document.getElementById('picturebox').style.display = 'none';");
egw_framework::validate_file('.', 'etemplate', 'etemplate');
$GLOBALS['egw']->common->egw_header();
echo '<div id="divMain">'."\n";
echo '<div><h3>{Im|Ex}port Wizard</h3></div>';
// adding a manual icon to every popup
if ($GLOBALS['egw_info']['user']['apps']['manual'])
{
$manual = new etemplate('etemplate.popup.manual');
echo $manual->exec(self::_appname.'.importexport_definitions_ui.wizard',$content,$sel_options,$readonlys,$preserv,1);
unset($manual);
}
echo '<div id="contentbox">';
echo $html;
echo '</div></div>'."\n";
echo '<style type="text/css">#picturebox { position: absolute; right: 27px; top: 24px; }</style>'."\n";
echo '<div id="picturebox">'. $this->clock. '</div>';
return;
}
}
/**
* gets name of next step
*
* @param string $curr_step
* @param int $step_width
* @return string containing function name of next step
*/
function get_step ($curr_step, $step_width)
{
/*if($content['plugin'] && $content['application']&& !is_object($this->plugin))
{
$plugin_definition = $this->plugins[$content['application']][$content['plugin']]['definition'];
if($plugin_definition) $this->plugin = new $plugin_definition;
}*/
if(is_object($this->plugin) && is_array($this->plugin->steps))
{
$steps = array_merge($this->steps,$this->plugin->steps);
$steps = array_flip($steps); asort($steps); $steps = array_flip($steps);
}
else
{
$steps = $this->steps;
}
$step_keys = array_keys($steps);
$nn = array_search($curr_step,$step_keys)+(int)$step_width;
return (key_exists($nn,$step_keys)) ? $step_keys[$nn] : 'wizard_finish';
}
function wizard_step10(&$content, &$sel_options, &$readonlys, &$preserv)
{
if(self::_debug) error_log('importexport.importexport_definitions_ui::wizard_step10->$content '.print_r($content,true));
// return from step10
if ($content['step'] == 'wizard_step10')
{
switch (array_search('pressed', $content['button']))
{
case 'next':
return $this->get_step($content['step'],1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step10($content,$sel_options,$readonlys,$preserv);
}
}
// init step10
else
{
$content['msg'] = $this->steps['wizard_step10'];
foreach ($this->plugins as $appname => $options) $sel_options['application'][$appname] = lang($appname);
$GLOBALS['egw']->js->set_onload("disable_button('exec[button][previous]');");
$content['step'] = 'wizard_step10';
$preserv = $content;
unset ($preserv['button']);
return 'importexport.wizard_chooseapp';
}
}
// get plugin
function wizard_step20(&$content, &$sel_options, &$readonlys, &$preserv)
{
if(self::_debug) error_log('importexport.' . get_class($this) . '::wizard_step20->$content '.print_r($content,true));
// return from step20
if ($content['step'] == 'wizard_step20')
{
switch (array_search('pressed', $content['button']))
{
case 'next':
// There's no real reason the plugin has to come from any of these, as long as it has a $steps variable
if($this->plugin instanceof importexport_iface_import_plugin || $this->plugin instanceof importexport_wizard_basic_import_csv) {
$content['type'] = 'import';
} elseif($this->plugin instanceof importexport_iface_export_plugin) {
$content['type'] = 'export';
} else {
throw new egw_exception('Invalid plugin');
}
return $this->get_step($content['step'],1);
case 'previous' :
unset ($content['plugin']);
if(is_object($this->response)) {
$this->response->addScript("disable_button('exec[button][previous]');");
}
return $this->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step20($content,$sel_options,$readonlys,$preserv);
}
}
// init step20
else
{
$content['msg'] = $this->steps['wizard_step20'];
foreach ($this->plugins[$content['application']] as $type => $plugins) {
foreach($plugins as $plugin => $name) {
$sel_options['plugin'][$plugin] = $name;
}
}
$content['step'] = 'wizard_step20';
$preserv = $content;
unset ($preserv['button']);
return 'importexport.wizard_chooseplugin';
}
}
// name
function wizard_step21(&$content, &$sel_options, &$readonlys, &$preserv)
{
if(self::_debug) error_log('importexport.importexport_definitions_ui::wizard_step21->$content '.print_r($content,true));
// return from step21
if ($content['step'] == 'wizard_step21')
{
switch (array_search('pressed', $content['button']))
{
case 'next':
return $this->get_step($content['step'],1);
case 'previous' :
return $this->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step21($content,$sel_options,$readonlys,$preserv);
}
}
// init step21
else
{
$content['msg'] = $this->steps['wizard_step21'];
$content['step'] = 'wizard_step21';
$preserv = $content;
unset ($preserv['button']);
return 'importexport.wizard_choosename';
}
}
// allowed users
function wizard_step90(&$content, &$sel_options, &$readonlys, &$preserv)
{
if(self::_debug) error_log('importexport.importexport_definitions_ui::wizard_step90->$content '.print_r($content,true));
// return from step90
if ($content['step'] == 'wizard_step90')
{
$content['allowed_users'] = implode(',',$content['allowed_users']);
// workaround for some ugly bug related to readonlys;
switch (array_search('pressed', $content['button']))
{
case 'previous' :
return $this->get_step($content['step'],-1);
case 'next':
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step90($content,$sel_options,$readonlys,$preserv);
}
}
// init step90
else
{
$content['msg'] = $this->steps['wizard_step90'];
$content['step'] = 'wizard_step90';
$preserv = $content;
unset ($preserv['button']);
$GLOBALS['egw']->js->set_onload("disable_button('exec[button][next]');");
if(is_object($this->response)) {
$this->response->addAssign('exec[button][next]','style.display', 'none');
}
return 'importexport.wizard_chooseallowedusers';
}
}
function wizard_finish(&$content)
{
if(self::_debug) error_log('importexport.importexport_definitions_ui::wizard_finish->$content '.print_r($content,true));
// Take out some UI leavings
unset($content['msg']);
unset($content['step']);
unset($content['button']);
$bodefinitions = new importexport_definitions_bo();
$bodefinitions->save($content);
// This message is displayed if browser cant close window
$content['msg'] = lang('ImportExport wizard finished successfully!');
$content['closewindow'] = true;
return 'importexport.wizard_close';
}
function import_definition($content='')
{
$bodefinitions = new importexport_definitions_bo();
if (is_array($content))
{
$bodefinitions->import($content['import_file']['tmp_name']);
// TODO make redirect here!
return $this->index();
}
else
{
$etpl = new etemplate(self::_appname.'.import_definition');
return $etpl->exec(self::_appname.'.importexport_definitions_ui.import_definition',$content,array(),$readonlys,$preserv);
}
}
}

View File

@ -0,0 +1,183 @@
<?php
/**
* eGroupWare importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class export_csv
* This an record exporter.
* An record is e.g. a single address or or single event.
* No mater where the records come from, at the end export_entry
* stores it into the stream
*/
class importexport_export_csv implements importexport_iface_export_record
{
/**
* @var array array with field mapping in form egw_field_name => exported_field_name
*/
protected $mapping = array();
/**
* @var array array with conversions to be done in form: egw_field_name => conversion_string
*/
protected $conversion = array();
/**
* @var array holding the current record
*/
protected $record = array();
/**
* @var translation holds (charset) translation object
*/
protected $translation;
/**
* @var string charset of csv file
*/
protected $csv_charset;
/**
* @var int holds number of exported records
*/
protected $num_of_records = 0;
/**
* @var stream stream resource of csv file
*/
protected $handle;
/**
* @var array csv specific options
*/
protected $csv_options = array(
'delimiter' => ';',
'enclosure' => '"',
);
/**
* constructor
*
* @param stram $_stream resource where records are exported to.
* @param array _options options for specific backends
* @return bool
*/
public function __construct( $_stream, array $_options ) {
if (!is_object($GLOBALS['egw']->translation)) {
$GLOBALS['egw']->translation = new translation();
}
$this->translation = &$GLOBALS['egw']->translation;
$this->handle = $_stream;
$this->csv_charset = $_options['charset'] ? $_options['charset'] : 'utf-8';
if ( !empty( $_options ) ) {
$this->csv_options = array_merge( $this->csv_options, $_options );
}
}
/**
* sets field mapping
*
* @param array $_mapping egw_field_name => csv_field_name
*/
public function set_mapping( array $_mapping) {
if ($this->num_of_records > 0) {
throw new Exception('Error: Field mapping can\'t be set during ongoing export!');
}
$this->mapping = $_mapping;
}
/**
* Sets conversion.
* @see importexport_helper_functions::conversion.
*
* @param array $_conversion
*/
public function set_conversion( array $_conversion) {
$this->conversion = $_conversion;
}
/**
* exports a record into resource of handle
*
* @param importexport_iface_egw_record record
* @return bool
*/
public function export_record( importexport_iface_egw_record $_record ) {
$this->record = $_record->get_record_array();
// begin with fieldnames ?
if ($this->num_of_records == 0 && $this->csv_options['begin_with_fieldnames'] ) {
$mapping = ! empty( $this->mapping ) ? $this->mapping : array_keys ( $this->record );
$mapping = $this->translation->convert( $mapping, $this->translation->charset(), $this->csv_charset );
fputcsv( $this->handle ,$mapping ,$this->csv_options['delimiter'], $this->csv_options['enclosure'] );
}
// do conversions
if ( !empty( $this->conversion )) {
$this->record = importexport_helper_functions::conversion( $this->record, $this->conversion );
}
// do fieldmapping
if ( !empty( $this->mapping ) ) {
$record_data = $this->record;
$this->record = array();
foreach ($this->mapping as $egw_field => $csv_field) {
$this->record[$csv_field] = $record_data[$egw_field];
}
}
// do charset translation
$this->record = $this->translation->convert( $this->record, $this->translation->charset(), $this->csv_charset );
$this->fputcsv( $this->handle, $this->record, $this->csv_options['delimiter'], $this->csv_options['enclosure'] );
$this->num_of_records++;
}
/**
* Retruns total number of exported records.
*
* @return int
*/
public function get_num_of_records() {
return $this->num_of_records;
}
/**
* destructor
*
* @return
*/
public function __destruct() {
}
/**
* The php build in fputcsv function is buggy, so we need an own one :-(
*
* @param resource $filePointer
* @param array $dataArray
* @param char $delimiter
* @param char $enclosure
*/
protected function fputcsv($filePointer, Array $dataArray, $delimiter, $enclosure){
$string = "";
$writeDelimiter = false;
foreach($dataArray as $dataElement) {
if($writeDelimiter) $string .= $delimiter;
$string .= $enclosure . $dataElement . $enclosure;
$writeDelimiter = true;
}
$string .= "\n";
fwrite($filePointer, $string);
}
} // end export_csv_record
?>

View File

@ -0,0 +1,448 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* userinterface for exports
*
*/
class importexport_export_ui {
const _appname = 'importexport';
public $public_functions = array(
'export_dialog' => true,
'download' => true,
);
private $js;
private $user;
/**
* holds all export plugins from all apps
*
* @var array
*/
private $export_plugins;
public function __construct() {
$this->js = $GLOBALS['egw']->js = is_object($GLOBALS['egw']->js) ? $GLOBALS['egw']->js : CreateObject('phpgwapi.javascript');
$this->js->validate_file('.','export_dialog','importexport');
$this->user = $GLOBALS['egw_info']['user']['user_id'];
$this->export_plugins = importexport_helper_functions::get_plugins('all','export');
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
}
public function export_dialog($_content=array()) {
$tabs = 'general_tab|selection_tab|options_tab';
$content = array();
$sel_options = array();
$readonlys = array();
$preserv = array();
if(empty($_content)) {
$et = new etemplate(self::_appname. '.export_dialog');
$_appname = $_GET['appname'];
$_definition = $_GET['definition'];
$_plugin = $_GET['plugin']; // NOTE: definition _must_ be 'expert' if for plugin to be used!
$_selection = $_GET['selection'];
//error_log(__FILE__.__FUNCTION__. '::$_GET[\'appname\']='. $_appname. ',$_GET[\'definition\']='. $_definition. ',$_GET[\'plugin\']='.$_plugin. ',$_GET[\'selection\']='.$_selection);
// if appname is given and valid, list available definitions (if no definition is given)
if (!empty($_appname) && $GLOBALS['egw']->acl->check('run',1,$_appname)) {
$content['appname'] = $_appname;
$preserv['appname'] = $_appname;
$readonlys['appname'] = true;
$this->js->set_onload("export_dialog.appname = '$_appname';");
$this->js->set_onload("set_style_by_class('tr','select_appname','display','none');");
// fill definitions
$sel_options['definition'] = array();
$definitions = new importexport_definitions_bo(array(
'type' => 'export',
'application' => isset($content['appname']) ? $content['appname'] : '%'
));
foreach ((array)$definitions->get_definitions() as $identifier) {
$definition = new importexport_definition($identifier);
if ($title = $definition->get_title()) {
$sel_options['definition'][$title] = $title;
}
unset($definition);
}
unset($definitions);
$sel_options['definition']['expert'] = lang('Expert options');
if(isset($_definition) && array_key_exists($_definition,$sel_options['definition'])) {
$content['definition'] = $_definition;
}
else {
$defdescs = array_keys($sel_options['definition']);
$content['definition'] = $sel_options['definition'][$defdescs[0]];
unset($defdescs);
}
// fill plugins
$sel_options['plugin'] = $this->export_plugins[$_appname]['export'];
// show definitions or plugins in ui?
if($content['definition'] == 'expert') {
if(isset($_plugin) && array_key_exists($_plugin,$sel_options['plugin'])) {
$content['plugin'] = $_plugin;
$selected_plugin = $_plugin;
}
else {
/*
$plugins_classnames = array_keys($sel_options['plugin']);
$selected_plugin = $plugins_classnames[0];
$sel_options['plugin'] = $plugins;
*/
}
$this->js->set_onload("set_style_by_class('tr','select_definition','display','none');");
}
else {
$this->js->set_onload("set_style_by_class('tr','select_plugin','display','none');");
$this->js->set_onload("set_style_by_class('tr','save_definition','display','none');");
$definition = new importexport_definition($content['definition']);
$selected_plugin = $definition->plugin;
$content['description'] = $definition->description;
}
// handle selector
if($selected_plugin) {
$plugin_object = new $selected_plugin;
$content['description'] = $plugin_object->get_description();
// fill options tab
// TODO: do we need all options templates online?
// NO, we can manipulate the session array of template id on xajax request
// however, there might be other solutions... we solve this in 1.3
$content['plugin_options_html'] = $plugin_object->get_options_etpl();
}
// fill selection tab
if ($_selection) {
$readonlys[$tabs]['selection_tab'] = true;
$content['selection'] = $_selection;
$preserv['selection'] = $_selection;
}
elseif ($plugin_object) {
// ToDo: I need to think abaout it...
// are selectors abstracted in the iface_egw_record_entity ?
// if so, we might not want to have html here ?
$content['plugin_selectors_html'] = $plugin_object->get_selectors_html();
}
unset ($plugin_object);
}
// if no appname is supplied, list apps which can export
else {
(array)$apps = importexport_helper_functions::get_apps('export');
$sel_options['appname'] = array('' => lang('Select one')) + array_combine($apps,$apps);
$this->js->set_onload("set_style_by_class('tr','select_plugin','display','none');");
$content['plugin_selectors_html'] = $content['plugin_options_html'] =
lang('You need to select an app and format first!');
$this->js->set_onload("document.getElementById('importexport.export_dialog.options_tab-tab').style.visibility='hidden';");
$this->js->set_onload("document.getElementById('importexport.export_dialog.selection_tab-tab').style.visibility='hidden';");
}
if (!$_selection) {
$this->js->set_onload("
disable_button('exec[preview]');
disable_button('exec[export]');
");
}
// disable preview box
$this->js->set_onload("set_style_by_class('tr','preview-box','display','none');");
}
//xajax_eT_wrapper submit
elseif(class_exists('xajaxResponse'))
{
//error_log(__LINE__.__FILE__.'$_content: '.print_r($_content,true));
$response = new xajaxResponse();
if ($_content['definition'] == 'expert') {
$definition = new importexport_definition();
$definition->definition_id = $_content['definition_id'] ? $_content['definition_id'] : '';
$definition->name = $_content['name'] ? $_content['name'] : '';
$definition->application = $_content['appname'];
$definition->plugin = $_content['plugin'];
$definition->type = 'export';
$definition->allowed_users = $_content['allowed_users'] ? $_content['allowed_users'] : $this->user;
$definition->owner = $_content['owner'] ? $_content['owner'] : $this->user;
}
else {
$definition = new importexport_definition($_content['definition']);
}
if(!is_array($definition->plugin_options)) {
$definition->plugin_options = array(
'mapping' => array()
);
}
if (isset($definition->plugin_options['selection'])) {
//$definition->plugin_options = parse(...)
}
else {
$definition->plugin_options = array_merge(
$definition->plugin_options,
array('selection' => $_content['selection'])
);
}
if(!$definition->plugin_options['selection']) {
$response->addScript('alert("' . lang('No records selected') . '");');
return $response->getXML();
}
$tmpfname = tempnam('/tmp','export');
$file = fopen($tmpfname, "w+");
if (! $charset = $definition->plugin_options['charset']) {
$charset = $GLOBALS['egw']->translation->charset();
}
$plugin_object = new $definition->plugin;
$plugin_object->export( $file, $definition );
if($_content['export'] == 'pressed') {
fclose($file);
$response->addScript("xajax_eT_wrapper();");
$response->addScript("opener.location.href='". $GLOBALS['egw']->link('/index.php','menuaction=importexport.importexport_export_ui.download&_filename='. $tmpfname.'&_appname='. $definition->application). "&_suffix=". $plugin_object->get_filesuffix(). "';");
$response->addScript('window.setTimeout("window.close();", 100);');
return $response->getXML();
}
elseif($_content['preview'] == 'pressed') {
fseek($file, 0);
$item_count = 1;
$preview = '';
$search = array('[\016]','[\017]',
'[\020]','[\021]','[\022]','[\023]','[\024]','[\025]','[\026]','[\027]',
'[\030]','[\031]','[\032]','[\033]','[\034]','[\035]','[\036]','[\037]');
$replace = $preview = '';
while(!feof($file) && $item_count < 10) {
$preview .= preg_replace($search,$replace,fgets($file,1024));
$item_count++;
}
fclose($file);
unlink($tmpfname);
// NOTE: $definition->plugin_options['charset'] may not be set,
// but it's the best guess atm.
$preview = $GLOBALS['egw']->translation->convert( $preview,
$definition->plugin_options['charset'],
$GLOBALS['egw']->translation->charset()
);
$response->addAssign('exec[preview-box]','innerHTML',$preview);
//$response->addAssign('divPoweredBy','style.display','none');
$response->addAssign('exec[preview-box]','style.display','inline');
$response->addAssign('exec[preview-box-buttons]','style.display','inline');
$response->addScript("xajax_eT_wrapper();");
return $response->getXML();
}
//nothing else expected!
throw new Exception('Error: unexpected submit in export_dialog!');
} else {
$readonlys[$tabs]['selection'] = true;
$readonlys[$tabs]['selection'] = false;
}
//error_log(print_r($content,true));
return $et->exec(self::_appname. '.importexport_export_ui.export_dialog',$content,$sel_options,$readonlys,$preserv,2);
}
public function ajax_get_definitions($_appname, xajaxResponse &$response = null) {
if(is_null($response)) {
$response = new xajaxResponse();
} else {
$no_return = true;
}
if (!$_appname) {
$response->addScript("set_style_by_class('tr','select_definition','display','none');");
return $no_return ? '' : $response->getXML();
}
$definitions = new importexport_definitions_bo(array(
'type' => 'export',
'application' => $_appname
));
foreach ((array)$definitions->get_definitions() as $identifier) {
$definition = new importexport_definition($identifier);
if ($title = $definition->get_title()) {
if (!$selected_plugin) $selected_plugin = $title;
$sel_options['definition'] .= '<option ' . ($selected_plugin == $title ? 'selected="selected" ' : '') .
'value="'. $title. '" >'. $title. '</option>';
}
unset($definition);
}
unset($definitions);
$sel_options['definition'] .= '<option value="expert">' . lang('Expert options') . '</option';
if($selected_plugin == 'expert') {
$this->ajax_get_plugins($_appname, $response);
} else {
$response->addScript("set_style_by_class('tr','select_plugin','display','none');");
}
$response->addAssign('exec[definition]','innerHTML',$sel_options['definition']);
$response->addScript('export_dialog.change_definition(document.getElementById("exec[definition]"));');
$response->addScript("set_style_by_class('tr','select_definition','display','table-row');");
return $no_return ? '' : $response->getXML();
}
public function ajax_get_plugins($_appname, xajaxResponse &$response = null) {
if(!is_null($response)) {
$no_return = true;
} else {
$response = new xajaxResponse();
}
if (!$_appname) {
$response->addScript("set_style_by_class('tr','select_plugin','display','none');");
return $no_return ? '' : $response->getXML();
}
(array)$plugins = importexport_helper_functions::get_plugins($_appname,'export');
$sel_options['plugin'] = '';
foreach ($plugins[$_appname]['export'] as $plugin => $plugin_name) {
if (!$selected_plugin) $selected_plugin = $plugin;
$sel_options['plugin'] .= '<option value="'. $plugin. '" >'. $plugin_name. '</option>';
}
$this->ajax_get_plugin_description($selected_plugin,$response);
$this->ajax_get_plugin_options($selected_plugin, $response, $_definition);
$this->ajax_get_plugin_selectors($selected_plugin, $response, $_definition);
$response->addAssign('exec[plugin]','innerHTML',$sel_options['plugin']);
$response->addScript("set_style_by_class('tr','select_plugin','display','table-row');");
return $no_return ? '' : $response->getXML();
}
public function ajax_get_definition_description($_definition, xajaxResponse &$response=null) {
$no_return = !is_null($response);
if(is_null($response)) {
$response = new xajaxResponse();
}
if (!$_definition) return $response->getXML();
$_object = new importexport_definition($_definition);
if (is_a($_object, 'importexport_definition')) {
$description = $_object->description;
$response->assign('exec[plugin_description]','innerHTML',$description);
}
unset ($_object);
return $no_return ? '' : $response->getXML();
}
public function ajax_get_plugin_description($_plugin,&$_response=false) {
$no_return = !is_null($_response);
if(is_null($_response)) {
$_response = new xajaxResponse();
}
if (!$_plugin) return $no_return ? '' : $response->getXML();
$plugin_object = new $_plugin;
if (is_a($plugin_object, 'importexport_iface_export_plugin')) {
$description = $plugin_object->get_description();
$_response->addAssign('exec[plugin_description]','innerHTML',$description);
$this->ajax_get_plugin_options($_plugin, $_response);
}
unset ($plugin_object);
return $no_return ? '' : $response->getXML();
}
public function ajax_get_plugin_options($_plugin,&$response=false, $definition = '') {
$no_return = !is_null($response);
if(is_null($response)) {
$response = new xajaxResponse();
}
if (!$_plugin) return $no_return ? '' : $response->getXML();
$plugin_object = new $_plugin;
if (is_a($plugin_object, 'importexport_iface_export_plugin')) {
$options = $plugin_object->get_options_etpl();
ob_start();
$template = new etemplate($options);
/*
$template->exec('importexport.importexport_export_ui.dialog', array(), array(), array(), array(), 2);
$html = ob_get_clean();
ob_end_clean();
*/
$html = $template->exec('importexport.importexport_export_ui.dialog', array(), array(), array(), array(), 1);
$html = preg_replace('|<input.+id="etemplate_exec_id".*/>|',
'',
$html
);
$response->addAssign('importexport.export_dialog.options_tab', 'innerHTML', $html);
}
unset ($plugin_object);
return $no_return ? '' : $response->getXML();
}
/**
* downloads file to client and deletes it.
*
* @param sting $_tmpfname
* @todo we need a suffix atibute in plugins e.g. .csv
*/
public function download($_tmpfname = '') {
$tmpfname = $_tmpfname ? $_tmpfname : $_GET['_filename'];
if (!is_readable($tmpfname)) die();
$appname = $_GET['_appname'];
$nicefname = 'egw_export_'.$appname.'-'.date('y-m-d');
header('Content-type: application/text');
header('Content-Disposition: attachment; filename="'.$nicefname.'.'.$_GET['_suffix'].'"');
$file = fopen($tmpfname,'r');
while(!feof($file))
echo fgets($file,1024);
fclose($file);
unlink($tmpfname);
}
public function ajax_get_plugin_selectors($_plugin,&$response=false, $definition = '') {
$no_return = !is_null($response);
if(is_null($response)) {
$response = new xajaxResponse();
}
if (!$_plugin) return $no_return ? '' : $response->getXML();
$plugin_object = new $_plugin;
if (is_a($plugin_object, 'importexport_iface_export_plugin')) {
$options = $plugin_object->get_selectors_etpl();
ob_start();
$template = new etemplate($options);
$template->exec('importexport.importexport_export_ui.dialog', array(), array(), array(), array(), 2);
$html = ob_get_clean();
ob_end_clean();
$html = preg_replace('|<input.+id="etemplate_exec_id".*/>|',
'',
$html
);
$response->addAssign('importexport.export_dialog.selection_tab', 'innerHTML', $html);
}
unset ($plugin_object);
return $no_return ? '' : $response->getXML();
}
public function ajax_get_template($_name) {
}
} // end class uiexport

View File

@ -0,0 +1,353 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class importexport_helper_functions (only static methods)
* use importexport_helper_functions::method
*/
class importexport_helper_functions {
/**
* Plugins are scanned and cached for all instances using this source path for given time (in seconds)
*/
const CACHE_EXPIRATION = 3600;
/**
* Files known to cause problems, and will be skipped in a plugin scan
* If you put appname => true, the whole app will be skipped.
*/
protected static $blacklist_files = array(
'news_admin' => array(
'class.news_admin_import.inc.php',
),
);
/**
* nothing to construct here, only static functions!
*/
/**
* Converts a custom time string to to unix timestamp
* The format of the time string is given by the argument $_format
* which takes the same parameters as the php date() function.
*
* @abstract supportet formatstrings: d,m,y,Y,H,h,i,s,O,a,A
* If timestring is empty, php strtotime is used.
* @param string $_string time string to convert
* @param string $_format format of time string e.g.: d.m.Y H:i
* @param int $_is_dst is day light saving time? 0 = no, 1 = yes, -1 = system default
*/
public static function custom_strtotime( $_string, $_format='', $_is_dst = -1) {
if ( empty( $_format ) ) return strtotime( $_string );
$fparams = explode( ',', chunk_split( $_format, 1, ',' ) );
$spos = 0;
foreach ( $fparams as $fparam ) {
switch ( $fparam ) {
case 'd': (int)$day = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'm': (int)$mon = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'y': (int)$year = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'Y': (int)$year = substr( $_string, $spos, 4 ); $spos += 4; break;
case 'H': (int)$hour = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'h': (int)$hour = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'i': (int)$min = substr( $_string, $spos, 2 ); $spos += 2; break;
case 's': (int)$sec = substr( $_string, $spos, 2 ); $spos += 2; break;
case 'O': (int)$offset = $year = substr( $_string, $spos, 5 ); $spos += 5; break;
case 'a': (int)$hour = $fparam == 'am' ? $hour : $hour + 12; break;
case 'A': (int)$hour = $fparam == 'AM' ? $hour : $hour + 12; break;
default: $spos++; // seperator
}
}
print_debug("hour:$hour; min:$min; sec:$sec; mon:$mon; day:$day; year:$year;\n");
$timestamp = mktime($hour, $min, $sec, $mon, $day, $year, $_is_dst);
// offset given?
if ( isset( $offset ) && strlen( $offset == 5 ) ) {
$operator = $offset{0};
$ohour = 60 * 60 * (int)substr( $offset, 1, 2 );
$omin = 60 * (int)substr( $offset, 3, 2 );
if ( $operator == '+' ) $timestamp += $ohour + $omin;
else $timestamp -= $ohour + $omin;
}
return $timestamp;
}
/**
* converts accound_lid to account_id
*
* @param mixed $_account_lid comma seperated list or array with lids
* @return mixed comma seperated list or array with ids
*/
public static function account_name2id( $_account_lids ) {
$account_lids = is_array( $_account_lids ) ? $_account_lids : explode( ',', $_account_lids );
foreach ( $account_lids as $account_lid ) {
if ( $account_id = $GLOBALS['egw']->accounts->name2id( $account_lid )) {
$account_ids[] = $account_id;
}
}
return is_array( $_account_lids ) ? $account_ids : implode( ',', (array)$account_ids );
} // end of member function account_lid2id
/**
* converts account_ids to account_lids
*
* @param mixed $_account_ids comma seperated list or array with ids
* @return mixed comma seperated list or array with lids
*/
public static function account_id2name( $_account_id ) {
$account_ids = is_array( $_account_id ) ? $_account_id : explode( ',', $_account_id );
foreach ( $account_ids as $account_id ) {
if ( $account_lid = $GLOBALS['egw']->accounts->id2name( $account_id )) {
$account_lids[] = $account_lid;
}
}
return is_array( $_account_id ) ? $account_lids : implode( ',', (array)$account_lids );
} // end of member function account_id2lid
/**
* converts cat_id to a cat_name
*
* @param mixed _cat_ids comma seperated list or array
* @return mixed comma seperated list or array with cat_names
*/
public static function cat_id2name( $_cat_ids ) {
$cat_ids = is_array( $_cat_ids ) ? $_cat_ids : explode( ',', $_cat_ids );
foreach ( $cat_ids as $cat_id ) {
$cat_names[] = categories::id2name( (int)$cat_id );
}
return is_array( $_cat_ids ) ? $cat_names : implode(',',(array)$cat_names);
} // end of member function category_id2name
/**
* converts cat_name to a cat_id.
* If a cat isn't found, it will be created.
*
* @param mixed $_cat_names comma seperated list or array.
* @return mixed comma seperated list or array with cat_ids
*/
public static function cat_name2id( $_cat_names ) {
$cats = new categories(); // uses current user and app (egw_info[flags][currentapp])
$cat_names = is_array( $_cat_names ) ? $_cat_names : explode( ',', $_cat_names );
foreach ( $cat_names as $cat_name ) {
if ( $cat_name == '' ) continue;
if ( ( $cat_id = $cats->name2id( $cat_name ) ) == 0 ) {
$cat_id = $cats->add( array(
'name' => $cat_name,
'access' => 'public',
'descr' => $cat_name. ' ('. lang('Automatically created by importexport'). ')'
));
}
$cat_ids[] = $cat_id;
}
return is_array( $_cat_names ) ? $cat_ids : implode( ',', (array)$cat_ids );
} // end of member function category_name2id
/**
* conversion
*
* Conversions enable you to change / adapt the content of each _record field for your needs.
* General syntax is: pattern1 |> replacement1 || ... || patternN |> replacementN
* 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.
* Example: 1|>private||public
* This will translate a '1' in the _record field to 'privat' and everything else to 'public'.
*
* In addintion to the fields assign by the pattern of the reg.exp.
* you can use all other _record fields, with the syntax |[FIELDINDEX].
* Example:
* Your record is:
* array( 0 => Company, 1 => NFamily, 2 => NGiven
* Your conversion string for field 0 (Company):
* .+|>|[0]: |[1], |[2]|||[1], |[2]
* This constructs something like
* Company: FamilyName, GivenName or FamilyName, GivenName if 'Company' is empty.
*
* Moreover the two helper function cat() and account() can be used.
* cat(Cat1,...,CatN) returns a (','-separated) list with the cat_id's. If a
* category isn't found, it will be automaticaly added.
*
* Patterns as well as the replacement can be regular expressions (the replacement is done
* via ereg_replace).
*
* @param array _record reference with record to do the conversion with
* @param array _conversion array with conversion description
* @param object &$cclass calling class to process the '@ evals' (not impelmeted yet)
* @return bool
*/
public static function conversion( $_record, $_conversion, &$_cclass = null ) {
if (empty( $_conversion ) ) return $_record;
$PSep = '||'; // Pattern-Separator, separats the pattern-replacement-pairs in conversion
$ASep = '|>'; // Assignment-Separator, separats pattern and replacesment
$CPre = '|['; $CPos = ']'; // |[_record-idx] is expanded to the corespondig value
$TPre = '|T{'; $TPos = '}'; // |{_record-idx} is trimmed
$CntlPre = '|TC{'; // Filter all cntl-chars \x01-\x1f and trim
$CntlnCLPre = '|TCnCL{'; // Like |C{ but allowes CR and LF
$INE = '|INE{'; // Only insert if stuff in ^^ is not empty
foreach ( $_conversion as $idx => $conversion_string ) {
if ( empty( $conversion_string ) ) continue;
// fetch patterns ($rvalues)
$pat_reps = explode( $PSep, stripslashes( $conversion_string ) );
foreach( $pat_reps as $k => $pat_rep ) {
list( $pattern, $replace ) = explode( $ASep, $pat_rep, 2 );
if( $replace == '' ) {
$replace = $pattern; $pattern = '^.*$';
}
$rvalues[$pattern] = $replace; // replace two with only one, added by the form
}
// conversion list may be longer than $_record aka (no_csv)
$val = array_key_exists( $idx, $_record ) ? $_record[$idx] : '';
foreach ( $rvalues as $pattern => $replace ) {
if( ereg( (string)$pattern, $val) ) {
$val = ereg_replace( (string)$pattern, $replace, (string)$val );
$reg = '\|\[([a-zA-Z_0-9]+)\]';
while( ereg( $reg, $val, $vars ) ) {
// expand all _record fields
$val = str_replace(
$CPre . $vars[1] . $CPos,
$_record[array_search($vars[1], array_keys($_record))],
$val
);
}
$val = preg_replace_callback( "/(cat|account|strtotime)\(([^)]*)\)/i", array( self, 'c2_dispatcher') , $val );
}
}
// clean each field
$val = preg_replace_callback("/(\|T\{|\|TC\{|\|TCnCL\{|\|INE\{)(.*)\}/", array( self, 'strclean'), $val );
$_record[$idx] = $val;
}
return $_record;
} // end of member function conversion
/**
* callback for preg_replace_callback from self::conversion.
* This function gets called when 2nd level conversions are made,
* like the cat() and account() statements in the conversions.
*
* @param array $_matches
*/
private static function c2_dispatcher( $_matches ) {
$action = &$_matches[1]; // cat or account ...
$data = &$_matches[2]; // datas for action
switch ( $action ) {
case 'strtotime' :
list( $string, $format ) = explode( ',', $data );
return self::custom_strtotime( trim( $string ), trim( $format ) );
default :
$method = (string)$action. ( is_int( $data ) ? '_id2name' : '_name2id' );
return self::$method( $data );
}
}
private static function strclean( $_matches ) {
switch( $_matches[1] ) {
case '|T{' : return trim( $_matches[2] );
case '|TC{' : return trim( preg_replace( '/[\x01-\x1F]+/', '', $_matches[2] ) );
case '|TCnCL{' : return trim( preg_replace( '/[\x01-\x09\x11\x12\x14-\x1F]+/', '', $_matches[2] ) );
case '|INE{' : return preg_match( '/\^.+\^/', $_matches[2] ) ? $_matches[2] : '';
default:
throw new Exception('Error in conversion string! "'. substr( $_matches[1], 0, -1 ). '" is not valid!');
}
}
/**
* returns a list of importexport plugins
*
* @param string $_tpye {import | export | all}
* @param string $_appname {<appname> | all}
* @return array(<appname> => array( <type> => array(<plugin> => <title>)))
*/
public static function get_plugins( $_appname = 'all', $_type = 'all' ) {
$plugins = egw_cache::getTree(
__CLASS__,
'plugins',
array('importexport_helper_functions','_get_plugins'),
array(array_keys($GLOBALS['egw_info']['apps']), array('import', 'export')),
self::CACHE_EXPIRATION
);
$appnames = $_appname == 'all' ? array_keys($GLOBALS['egw_info']['apps']) : (array)$_appname;
$types = $_type == 'all' ? array('import','export') : (array)$_type;
foreach($plugins as $appname => $types) {
if(!in_array($appname, $appnames)) unset($plugins['appname']);
}
foreach($plugins as $appname => $types) {
$plugins[$appname] = array_intersect_key($plugins[$appname], $types);
}
return $plugins;
}
public static function _get_plugins(Array $appnames, Array $types) {
$plugins = array();
foreach ($appnames as $appname) {
if(array_key_exists($appname, self::$blacklist_files) && self::$blacklist_files[$appname] === true) continue;
$appdir = EGW_INCLUDE_ROOT. "/$appname/inc";
if(!is_dir($appdir)) continue;
$d = dir($appdir);
// step through each file in appdir
while (false !== ($entry = $d->read())) {
// Blacklisted?
if(is_array(self::$blacklist_files[$appname]) && in_array($entry, self::$blacklist_files[$appname])) continue;
list( ,$classname, ,$extension) = explode('.',$entry);
$file = $appdir. '/'. $entry;
foreach ($types as $type) {
if( !is_file($file) || strpos($entry, $type) === false || $extension != 'php' ) continue;
require_once($file);
$reflectionClass = new ReflectionClass($classname);
if($reflectionClass->IsInstantiable() &&
$reflectionClass->implementsInterface('importexport_iface_'.$type.'_plugin')) {
try {
$plugin_object = new $classname;
}
catch (Exception $exception) {
continue;
}
$plugins[$appname][$type][$classname] = $plugin_object->get_name();
unset ($plugin_object);
}
}
}
$d->close();
}
//error_log(__CLASS__.__FUNCTION__.print_r($plugins,true));
return $plugins;
}
/**
* returns list of apps which have plugins of given type.
*
* @param string $_type
* @return array $num => $appname
*/
public static function get_apps($_type) {
return array_keys(self::get_plugins('all',$_type));
}
public static function guess_filetype( $_file ) {
}
} // end of importexport_helper_functions

View File

@ -0,0 +1,123 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class importexport_iface_egw_record
* This a the abstract interface of an egw record.
* A record is e.g. a single address or or single event.
* The idea behind is that we can have metaoperation over differnt apps by
* having a common interface.
* A record is identified by a identifier. As we are a Webapp and want to
* deal with the objects in the browser, identifier should be a string!
*
* @todo lots! of discussion with other developers
* @todo move to api once developers accepted it!
* @todo functions for capabilities of object
* @todo caching. e.g. only read name of object
*/
interface importexport_iface_egw_record
{
/**
* constructor
* reads record from backend if identifier is given.
*
* @param string $_identifier
*/
public function __construct( $_identifier='' );
/**
* magic method to set attributes of record
*
* @param string $_attribute_name
*/
public function __get($_attribute_name);
/**
* magig method to set attributes of record
*
* @param string $_attribute_name
* @param data $data
*/
public function __set($_attribute_name, $data);
/**
* converts this object to array.
* @abstract We need such a function cause PHP5
* dosn't allow objects do define it's own casts :-(
* once PHP can deal with object casts we will change to them!
*
* @return array complete record as associative array
*/
public function get_record_array();
/**
* gets title of record
*
*@return string tiltle
*/
public function get_title();
/**
* sets complete record from associative array
*
* @return void
*/
public function set_record(array $_record);
/**
* gets identifier of this record
*
* @return string identifier of this record
*/
public function get_identifier();
/**
* saves record into backend
*
* @return string identifier
*/
public function save ( $_dst_identifier );
/**
* copys current record to record identified by $_dst_identifier
*
* @param string $_dst_identifier
* @return string dst_identifier
*/
public function copy ( $_dst_identifier );
/**
* moves current record to record identified by $_dst_identifier
* $this will become moved record
*
* @param string $_dst_identifier
* @return string dst_identifier
*/
public function move ( $_dst_identifier );
/**
* delets current record from backend
* @return void
*
*/
public function delete ();
/**
* destructor
*
*/
public function __destruct();
} // end of iface_egw_record
?>

View File

@ -0,0 +1,90 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class importexport_iface_export_plugin
* This a the abstract interface for an export plugin of importexport
*
* You need to implement this class in
* EGW_INCLUDE_ROOT/appname/inc/importexport/class.export_<type>.inc.php
* to attend the importexport framwork with your export.
*
* NOTE: This is an easy interface, cause plugins live in theire own
* space. Means that they are responsible for generating a defintion AND
* working on that definition.
* So this interface just garanties the interaction with userinterfaces. It
* has nothing to do with datatypes.
*
* JS:
* required function in opener:
*
*
* // returns array of identifiers
* // NOTE: identifiers need to b
* get_selection();
*
* get_selector(); //returns array
*/
interface importexport_iface_export_plugin {
/**
* exports entries according to given definition object.
*
* @param stream $_stream
* @param importexport_definition $_definition
*/
public function export($_stream, importexport_definition $_definition);
/**
* returns translated name of plugin
*
* @return string name
*/
public static function get_name();
/**
* returns translated (user) description of plugin
*
* @return string descriprion
*/
public static function get_description();
/**
* retruns file suffix for exported file (e.g. csv)
*
* @return string suffix
*/
public static function get_filesuffix();
/**
* return etemplate components for options.
* @abstract We can't deal with etemplate objects here, as an uietemplate
* objects itself are scipt orientated and not "dialog objects"
*
* @return array (
* name => string,
* content => array,
* sel_options => array,
* preserv => array,
* )
*/
public function get_options_etpl();
/**
* returns etemplate name for slectors of this plugin
*
* @return string etemplate name
*/
public function get_selectors_etpl();
} // end of iface_export_plugin
?>

View File

@ -0,0 +1,61 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class iface_export_record
* This a the abstract interface for an record exporter.
* An record is e.g. a single address or or single event.
* No mater where the records come from, at the end export_entry
* stores it into the stream
* NOTE: we don't give records the type "egw_reocrd". Thats becuase
* PHP5 dosn't allow objects do define it's own casts :-(
*
* NOTE: You are not forced to implement this interface to attend importexport
* framework. However if you plugin implements this interface it might also be
* usable for other tasks.
*
*/
interface importexport_iface_export_record
{
/**
* constructor
*
* @param stream $_stream resource where records are exported to.
* @param array $_options options for specific backends
* @return bool
*/
public function __construct( $_stream, array $_options );
/**
* exports a record into resource of handle
*
* @param object of interface egw_record _record
* @return bool
*/
public function export_record( importexport_iface_egw_record $_record );
/**
* Retruns total number of exported records.
*
* @return int
*/
public function get_num_of_records( );
/**
* destructor
*
* @return
*/
public function __destruct( );
} // end of iface_export_record
?>

View File

@ -0,0 +1,101 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id:$
*/
/**
* class iface_import_plugin
* This a the abstract interface for an import plugin of importexport
*
* You need to implement this class in
* EGW_INCLUDE_ROOT/appname/inc/importexport/class.import_<type>.inc.php
* to attend the importexport framwork with your export.
*
* NOTE: This is an easy interface, cause plugins live in theire own
* space. Means that they are responsible for generating a defintion AND
* working on that definition.
* So this interface just garanties the interaction with userinterfaces. It
* has nothing to do with datatypes.
*/
interface importexport_iface_import_plugin {
/**
* imports entries according to given definition object.
*
* @param stram $_stram
* @param definition $_definition
* @return int number of successful imports
*/
public function import( $_stream, importexport_definition $_definition );
/**
* returns translated name of plugin
*
* @return string name
*/
public static function get_name();
/**
* returns translated (user) description of plugin
*
* @return string descriprion
*/
public static function get_description();
/**
* retruns file suffix(s) plugin can handle (e.g. csv)
*
* @return string suffix (comma seperated)
*/
public static function get_filesuffix();
/**
* return etemplate components for options.
* @abstract We can't deal with etemplate objects here, as an uietemplate
* objects itself are scipt orientated and not "dialog objects"
*
* @return array (
* name => string,
* content => array,
* sel_options => array,
* preserv => array,
* )
*/
public function get_options_etpl();
/**
* returns etemplate name for slectors of this plugin
*
* @return string etemplate name
*/
public function get_selectors_etpl();
/**
* Returns errors that were encountered during importing
* Maximum of one error message per record, but you can concatenate them if you need to
*
* @return Array (
* record_# => error message
* )
*/
public function get_errors();
/**
* Returns a list of actions taken, and the number of records for that action.
* Actions are things like 'insert', 'update', 'delete', and may be different for each plugin.
*
* @return Array (
* action => record count
* )
*/
public function get_results();
} // end of iface_export_plugin
?>

View File

@ -0,0 +1,66 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class iface_import_record
* This a the abstract interface for an record importer.
* An record is e.g. a single address or or single event.
* No mater where the records come from, at the end the get_entry method comes out
*/
interface importexport_iface_import_record
{
/**
* Opens resource, returns false if something fails
*
* @param stream $_stream resource containing data. Differs according to the implementations
* @param array $_options options for specific backends
* @return bool
*/
public function __construct( $_stream, array $_options );
/**
* cleanup
*
* @return
*/
public function __destruct( );
/**
* Returns array with the record found at position and updates the position
*
* @param string _position may be: {first|last|next|previous|somenumber}
* @return bool
*/
public function get_record( $_position = 'next' );
/**
* Retruns total number of records for the open resource.
*
* @return int
*/
public function get_num_of_records( );
/**
* Returns pointer of current position
*
* @return int
*/
public function get_current_position( );
} // end of iface_import_record
?>

View File

@ -0,0 +1,243 @@
<?php
/**
* eGroupWare - importexport
* General Comma Serperated Values (CSV) record importer (abstract class)
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
/**
* class import_csv
* This a an abstract implementation of interface iface_import_record
* An record is e.g. a single address or or single event.
* No mater where the records come from, at the end the get_record method comes out
* @todo Throw away spechial chars and trim() entries ?
* @todo Check for XSS like userinput! (see common_functions)
*/
class importexport_import_csv implements importexport_iface_import_record { //, Iterator {
const csv_max_linelength = 8000;
/**
* @var array array with field mapping in form column number => new_field_name
*/
public $mapping = array();
/**
* @var array with conversions to be done in form: new_field_name => conversion_string
*/
public $conversion = array();
/**
* @var array holding the current record
*/
protected $record = array();
/**
* @var int current position counter
*/
protected $current_position = 0;
/**
* @var int holds total number of records
*/
protected $num_of_records = 0;
/**
* @var stream
*/
private $resource;
/**
* fieldseperator for csv file
* @access private
* @var char
*/
private $csv_fieldsep;
/**
*
* @var string charset of csv file
*/
private $csv_charset;
/**
* @param string $_resource resource containing data. May be each valid php-stream
* @param array $_options options for the resource array with keys: charset and fieldsep
*/
public function __construct( $_resource, array $_options ) {
$this->resource = $_resource;
$this->csv_fieldsep = $_options['fieldsep'];
$this->csv_charset = $_options['charset'];
return;
} // end of member function __construct
/**
* cleanup
*/
public function __destruct( ) {
} // end of member function __destruct
/**
* Returns array with the record found at position and updates the position
*
* @param mixed _position may be: {current|first|last|next|previous|somenumber}
* @return mixed array with data / false if no furtor records
*/
public function get_record( $_position = 'next' ) {
if ($this->get_raw_record( $_position ) === false) {
return false;
}
// skip empty records
if( count( array_unique( $this->record ) ) < 2 ) return $this->get_record( $_position );
if ( !empty( $this->conversion ) ) {
$this->do_conversions();
}
if ( !empty( $this->mapping ) ) {
$this->do_fieldmapping();
}
return $this->record;
} // end of member function get_record
/**
* Skips $_numToSkip of records from current position on
*
* @param int $_numToSkip
*/
public function skip_records( $_numToSkip ) {
while ( (int)$_numToSkip-- !== 0 ) {
fgetcsv( $this->resource, self::csv_max_linelength, $this->csv_fieldsep);
}
}
/**
* updates $this->record
*
* @param mixed $_position
* @return bool
*/
private function get_raw_record( $_position = 'next' ) {
switch ($_position) {
case 'current' :
if ($this->current_position == 0) {
return;
}
break;
case 'first' :
if (!$this->current_position == 0) {
$this->current_position = 0;
rewind($this->resource);
}
case 'next' :
$csv_data = fgetcsv( $this->resource, self::csv_max_linelength, $this->csv_fieldsep);
if (!is_array($csv_data)) {
return false;
}
$this->current_position++;
$this->record = $GLOBALS['egw']->translation->convert($csv_data, $this->csv_charset);
break;
case 'previous' :
if ($this->current_position < 2) {
throw new Exception('Error: There is no previous record!');
}
$final_position = --$this->current_position;
$this->current_position = 0;
rewind($this->resource);
while ($this->current_position !== $final_position) {
$this->get_raw_record();
}
break;
case 'last' :
while ($this->get_raw_record()) {}
break;
default: //somenumber
if (!is_int($_position)) {
throw new Exception('Error: $position must be one of {current|first|last|next|previous} or an integer value');
}
if ($_position == $this->current_position) {
break;
}
elseif ($_position < $this->current_position) {
$this->current_position = 0;
rewind($this->resource);
}
while ($this->current_position !== $_position) {
$this->get_raw_record();
}
break;
}
return;
} // end of member function get_raw_record
/**
* Retruns total number of records for the open resource.
*
* @return int
*/
public function get_num_of_records( ) {
if ($this->num_of_records > 0) {
return $this->num_of_records;
}
$current_position = $this->current_position;
while ($this->get_raw_record()) {}
$this->num_of_records = $this->current_position;
$this->get_record($current_position);
return $this->num_of_records;
} // end of member function get_num_of_records
/**
* Returns pointer of current position
*
* @return int
*/
public function get_current_position( ) {
return $this->current_position;
} // end of member function get_current_position
/**
* does fieldmapping according to $this->mapping
*
* @return
*/
protected function do_fieldmapping( ) {
$record = $this->record;
$this->record = array();
foreach ($this->mapping as $cvs_idx => $new_idx) {
if( $new_idx == '' ) continue;
$this->record[$new_idx] = $record[$cvs_idx];
}
return true;
} // end of member function do_fieldmapping
/**
* does conversions according to $this->conversion
*
* @return bool
*/
protected function do_conversions( ) {
if ( $record = importexport_helper_functions::conversion( $this->record, $this->conversion )) {
$this->record = $record;
return;
}
throw new Exception('Error: Could not applay conversions to record');
} // end of member function do_conversions
} // end of import_csv
?>

View File

@ -0,0 +1,135 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Nathan Gray
* @copyright Nathan Gray
* @version $Id: class.importexport_import_ui.inc.php 27222 2009-06-08 16:21:14Z ralfbecker $
*/
/**
* userinterface for imports
*
*/
class importexport_import_ui {
const _appname = 'importexport';
public $public_functions = array(
'import_dialog' => true,
);
/**
* holds all import plugins from all apps
*
* @var array
*/
private $plugins;
public function __construct() {
$GLOBALS['egw']->js->validate_file('.','import_dialog','importexport');
$this->plugins = importexport_helper_functions::get_plugins('all','import');
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
}
/**
* Step user through importing their file
*/
public function import_dialog($content = array()) {
$appname = $_GET['appname'] ? $_GET['appname'] : $content['appname'];
$definition = $_GET['definition'] ? $_GET['definition'] : $content['definition'];
if($content['import'] && $definition) {
try {
$definition_obj = new importexport_definition($content['definition']);
if($content['dry-run']) {
$definition_obj->plugin_options = (array)$definition_obj->plugin_options + array('dry_run' => true);
}
$plugin = new $definition_obj->plugin;
$file = fopen($content['file']['tmp_name'], 'r');
// Some of the translation, conversion, etc look here
$GLOBALS['egw_info']['flags']['currentapp'] = $appname;
$count = $plugin->import($file, $definition_obj);
$this->message = lang('%1 records processed', $count);
foreach($plugin->get_results() as $action => $count) {
$this->message .= "\n" . lang($action) . ": $count";
}
if(count($plugin->get_errors())) {
$this->message .= "\n".lang('Unable to import:');
foreach($plugin->get_errors() as $record => $message) {
$this->message .= "\n$record: $message";
}
}
} catch (Exception $e) {
$this->message = $e->getMessage();
}
} elseif($content['cancel']) {
$GLOBALS['egw']->js->set_onload('window.close();');
}
$data['appname'] = $appname;
$data['definition'] = $definition;
$sel_options = self::get_select_options($data);
$data['message'] = $this->message;
$template = new etemplate('importexport.import_dialog');
$template->exec('importexport.importexport_import_ui.import_dialog', $data, $sel_options, $readonlys, $preserve, 2);
}
/**
* Get options for select boxes
*/
public static function get_select_options(Array $data) {
$options = array();
(array)$apps = importexport_helper_functions::get_apps('import');
$options['appname'] = array('' => lang('Select one')) + array_combine($apps,$apps);
if($data['appname']) {
$options['definition'] = array();
if($data['file'] && !is_array($data['file'])) {
$extension = substr($data['file'], -3);
}
$definitions = new importexport_definitions_bo(array(
'type' => 'import',
'application' => $data['appname']
));
foreach ((array)$definitions->get_definitions() as $identifier) {
$definition = new importexport_definition($identifier);
if ($title = $definition->get_title()) {
$options['definition'][$title] = $title;
}
unset($definition);
}
unset($definitions);
}
return $options;
}
/**
* Get definitions via ajax
*/
public function ajax_get_definitions($appname, $file=null) {
$options = self::get_select_options(array('appname'=>$appname, 'file'=>$file));
if(is_array($options['definition'])) {
foreach ($options['definition'] as $value => $title) {
$sel_options['definition'] .= '<option value="'. $value. '" >'. $title. '</option>';
}
}
$response = new xajaxResponse();
$response->addScript('import_dialog.change_definition(document.getElementId(\'exec[definition]\'));');
$response->addAssign('exec[definition]','innerHTML',$sel_options['definition']);
return $response->getXML();
}
}
?>

View File

@ -0,0 +1,320 @@
<?php
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Nathan Gray
* @copyright Nathan Gray
* @version $Id: class.importexport_import_ui.inc.php 27222 2009-06-08 16:21:14Z ralfbecker $
*/
/**
* userinterface for admins to schedule imports or exports using async services
*
*/
class importexport_schedule_ui {
public $public_functions = array(
'index' => true,
'edit' => true,
);
protected static $template;
public function __construct() {
$this->template = new etemplate();
}
public function index($content = array()) {
if($content['scheduled']['delete']) {
$key = key($content['scheduled']['delete']);
ExecMethod('phpgwapi.asyncservice.cancel_timer', $key);
}
$async_list = ExecMethod('phpgwapi.asyncservice.read', 'importexport%');
$data = array();
if(is_array($async_list)) {
foreach($async_list as $id => $async) {
if(is_array($async['data']['errors'])) {
$async['data']['errors'] = implode("\n", $async['data']['errors']);
}
if(is_numeric($async['data']['record_count'])) {
$async['data']['record_count'] = lang('%1 records processed', $async['data']['record_count']);
}
$data['scheduled'][] = $async['data'] + array(
'id' => $id,
'next' => $async['next'],
'times' => str_replace("\n", '', print_r($async['times'], true)),
);
}
array_unshift($data['scheduled'], false);
}
$sel_options = self::get_select_options($data);
$this->template->read('importexport.schedule_index');
$GLOBALS['egw_info']['flags']['app_header'] = lang('Schedule import / export');
$this->template->exec('importexport.importexport_schedule_ui.index', $data, $sel_options, $readonlys, $preserve);
}
public function edit($content = array()) {
$id = $_GET['id'] ? $_GET['id'] : $content['id'];
unset($content['id']);
$data = $content;
// Deal with incoming
if($content['save'] && self::check_target($content) === true) {
unset($content['save']);
ExecMethod('phpgwapi.asyncservice.cancel_timer', $id);
$id = self::generate_id($content);
$schedule = $content['schedule'];
unset($content['schedule']);
// Fill in * for any left blank
foreach($schedule as $key => &$value) {
if($value == '') $value = '*';
}
$result = ExecMethod2('phpgwapi.asyncservice.set_timer',
$schedule,
$id,
'importexport.importexport_schedule_ui.exec',
$content
);
if($result) {
$GLOBALS['egw']->js->set_onload('window.opener.location.reload(); self.close();');
} else {
$data['message'] = lang('Unable to schedule');
unset($id);
}
}
if($id) {
$preserve['id'] = $id;
$async = ExecMethod('phpgwapi.asyncservice.read', $id);
if(is_array($async[$id]['data'])) {
$data += $async[$id]['data'];
$data['schedule'] = $async[$id]['times'];
} else {
$data['message'] = lang('Schedule not found');
}
} else {
$data['type'] = 'import';
}
if($data['target'] && $data['type']) {
$file_check = self::check_target($data);
if($file_check !== true) $data['message'] .= ($data['message'] ? "\n" . $file_check : $file_check);
}
$sel_options = self::get_select_options($data);
$GLOBALS['egw_info']['flags']['app_header'] = lang('Schedule import / export');
$this->template->read('importexport.schedule_edit');
$this->template->exec('importexport.importexport_schedule_ui.edit', $data, $sel_options, $readonlys, $preserve, 2);
}
/**
* Get options for select boxes
*/
public static function get_select_options(Array $data) {
$options = array(
'type' => array(
'import' => lang('import'),
'export' => lang('export')
)
);
(array)$apps = importexport_helper_functions::get_apps($data['type'] ? $data['type'] : 'all');
if(count($apps)) {
$options['appname'] = array('' => lang('Select one')) + array_combine($apps,$apps);
}
if($data['appname']) {
$plugins = importexport_helper_functions::get_plugins($data['appname'], $data['type']);
if(is_array($plugins[$data['appname']][$data['type']])) {
foreach($plugins[$data['appname']][$data['type']] as $key => $title) {
$options['plugin'][$key] = $title;
}
}
} else {
$plugins = importexport_helper_functions::get_plugins('all', $data['type'] ? $data['type'] : 'all');
if(is_array($plugins)) {
foreach($plugins as $appname => $_types) {
foreach($_types as $type => $plugins) {
foreach($plugins as $key => $title) {
$options['plugin'][$key] = $title;
}
}
}
}
}
$options['definition'] = array();
if($data['file'] && !is_array($data['file'])) {
$extension = substr($data['file'], -3);
}
// If the query isn't started with something, bodefinitions won't load the definitions
$query = array('definition_id');
if($data['type']) $query['type'] = $data['type'];
if($data['application']) $query['application'] = $data['application'];
if($data['plugin']) $query['plugin'] = $data['plugin'];
$definitions = new importexport_definitions_bo($query);
foreach ((array)$definitions->get_definitions() as $identifier) {
$definition = new importexport_definition($identifier);
if ($title = $definition->get_title()) {
$options['definition'][$title] = $title;
}
unset($definition);
}
unset($definitions);
return $options;
}
/**
* Generate a async key
*/
public static function generate_id($data) {
$query = array(
'name' => $data['definition']
);
$definitions = new importexport_definitions_bo($query);
$definition_list = ((array)$definitions->get_definitions());
$id = 'importexport.'.$definition_list[0].'.'.$data['target'];
return $id;
}
/**
* Get plugins via ajax
*/
public function ajax_get_plugins($type, $appname, &$response = null) {
if($response) {
$return = false;
} else {
$response = new xajaxResponse();
}
$options = self::get_select_options(array('type' => $type, 'appname'=>$appname));
if(is_array($options['plugins'])) {
foreach ($options['plugins'] as $value => $title) {
$response->addScript("selectbox_add_option('exec[plugin]','$title', '$value',false);");
}
}
return $response->getXML();
}
/**
* Get definitions via ajax
*/
public function ajax_get_definitions($appname, $plugin) {
$options = self::get_select_options(array('appname'=>$appname, 'plugin'=>$plugin));
if(is_array($options['definition'])) {
foreach ($options['definition'] as $value => $title) {
$sel_options['definition'] .= '<option value="'. $value. '" >'. $title. '</option>';
}
}
$response = new xajaxResponse();
$response->addAssign('exec[definition]','innerHTML',$sel_options['definition']);
return $response->getXML();
}
/**
* Check that the target is valid for the type (readable or writable)
* $data should contain target & type
*/
public static function check_target(Array $data) {
if ($data['type'] == 'import' && !is_readable($data['target']))
{
return $data['target']. ' is not readable';
}
elseif ($data['type'] == 'export' && !is_writable($data['target'])) {
return $data['target']. ' is not writable';
}
return true;
}
/**
* Execute a scheduled import or export
*/
public static function exec($data) {
ob_start();
// check file
$file_check = self::check_target($data);
if($file_check !== true) {
fwrite(STDERR,'importexport_schedule: ' . date('c') . ": $file_check \n");
exit();
}
$definition = new importexport_definition($data['definition']);
if( $definition->get_identifier() < 1 ) {
fwrite(STDERR,'importexport_schedule: ' . date('c') . ": Definition not found! \n");
exit();
}
$GLOBALS['egw_info']['flags']['currentapp'] = $definition->application;
$po = new $definition->plugin;
$type = $data['type'];
if($resource = fopen( $data['target'], $data['type'] == 'import' ? 'r' : 'w' )) {
$result = $po->$type( $resource, $definition );
fclose($resource);
} else {
fwrite(STDERR,'importexport_schedule: ' . date('c') . ": Definition not found! \n");
}
if($po->get_errors()) {
$data['errors'] = $po->get_errors();
fwrite(STDERR, 'importexport_schedule: ' . date('c') . ": Import errors:\n#\tError\n");
foreach($po->get_errors() as $record => $error) {
fwrite(STDERR, "$record\t$error\n");
}
} else {
unset($data['errors']);
}
if($po instanceof importexport_iface_import_plugin) {
if(is_numeric($result)) {
$data['record_count'] = $result;
}
$data['result'] = '';
foreach($po->get_results() as $action => $count) {
$data['result'] .= "\n" . lang($action) . ": $count";
}
} else {
$data['result'] = $result;
}
$data['last_run'] = time();
// Update job with results
$id = self::generate_id($data);
$async = ExecMethod('phpgwapi.asyncservice.read', $id);
$async = $async[$id];
if(is_array($async)) {
ExecMethod('phpgwapi.asyncservice.cancel_timer', $id);
$result = ExecMethod2('phpgwapi.asyncservice.set_timer',
$async['times'],
$id,
'importexport.importexport_schedule_ui.exec',
$data
);
}
$contents = ob_get_contents();
if($contents) {
fwrite(STDOUT,'importexport_schedule: ' . date('c') . ": \n".$contents);
}
ob_end_clean();
}
}
?>

View File

@ -0,0 +1,305 @@
<?php
/**
* eGroupWare - A basic implementation of a wizard to go with the basic CSV plugin.
*
* To add or remove steps, change $this->steps appropriately. The key is the function, the value is the title.
* Don't go past 80, as that's where the wizard picks it back up again to finish it off.
*
* For the mapping to work properly, you will have to fill $mapping_fields with the target fields for your application.
*
* NB: Your wizard class must be in <appname>/inc/class.appname_wizard_<plugin_name>.inc.php
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Nathan Gray
*/
class importexport_wizard_basic_import_csv
{
const TEMPLATE_MARKER = '-eTemplate-';
/**
* List of steps. Key is the function, value is the translated title.
*/
public $steps;
/**
* List of eTemplates to use for each step. You can override this with your own etemplates steps.
*/
protected $step_templates = array(
'wizard_step30' => 'importexport.wizard_basic_import_csv.sample_file',
'wizard_step40' => 'importexport.wizard_basic_import_csv.choosesepncharset',
'wizard_step50' => 'importexport.wizard_basic_import_csv.fieldmapping',
'wizard_step55' => 'importexport.wizard_basic_import_csv.conditions'
);
/**
* Destination fields for the mapping
* Key is the field name, value is the human version
*/
protected $mapping_fields = array();
/**
* List of conditions your plugin supports
*/
protected $conditions = array();
/**
* List of actions your plugin supports
*/
protected $actions = array();
/**
* constructor
*/
function __construct()
{
$this->steps = array(
'wizard_step30' => lang('Load Sample file'),
'wizard_step40' => lang('Choose seperator and charset'),
'wizard_step50' => lang('Manage mapping'),
'wizard_step55' => lang('Edit conditions'),
);
}
/**
* Take a sample CSV file. It will be processed in later steps
*/
function wizard_step30(&$content, &$sel_options, &$readonlys, &$preserv)
{
if($this->debug) error_log(get_class($this) . '::wizard_step30->$content '.print_r($content,true));
// return from step30
if ($content['step'] == 'wizard_step30')
{
switch (array_search('pressed', $content['button']))
{
case 'next':
// Move sample file to temp
if($content['file']['tmp_name']) {
$csvfile = tempnam($GLOBALS['egw_info']['server']['temp_dir'],$content['plugin']."_");
move_uploaded_file($content['file']['tmp_name'], $csvfile);
$GLOBALS['egw']->session->appsession('csvfile','',$csvfile);
}
unset($content['file']);
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],1);
case 'previous' :
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step30($content,$sel_options,$readonlys,$preserv);
}
}
// init step30
else
{
$content['msg'] = $this->steps['wizard_step30'];
$content['step'] = 'wizard_step30';
$preserv = $content;
unset ($preserv['button']);
$GLOBALS['egw']->js->set_onload("xajax_eT_wrapper_init();");
return $this->step_templates[$content['step']];
}
}
/**
* choose fieldseperator, charset and headerline
*
* @param array $content
* @param array $sel_options
* @param array $readonlys
* @param array $preserv
* @return string template name
*/
function wizard_step40(&$content, &$sel_options, &$readonlys, &$preserv)
{
if($this->debug) error_log(get_class($this) . '::wizard_step40->$content '.print_r($content,true));
// return from step40
if ($content['step'] == 'wizard_step40') {
switch (array_search('pressed', $content['button']))
{
case 'next':
// Process sample file for fields
if (($handle = fopen($GLOBALS['egw']->session->appsession('csvfile'), "rb")) !== FALSE) {
$data = fgetcsv($handle, 8000, $content['fieldsep']);
$content['csv_fields'] = translation::convert($data,$content['charset']);
} elseif($content['plugin_options']['csv_fields']) {
$content['csv_fields'] = $content['plugin_options']['csv_fields'];
}
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],1);
case 'previous' :
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step40($content,$sel_options,$readonlys,$preserv);
}
}
// init step40
else
{
$content['msg'] = $this->steps['wizard_step40'];
$content['step'] = 'wizard_step40';
// If editing an existing definition, these will be in plugin_options
if(!$content['fieldsep'] && $content['plugin_options']['fieldsep']) {
$content['fieldsep'] = $content['plugin_options']['fieldsep'];
} elseif (!$content['fieldsep']) {
$content['fieldsep'] = ';';
}
if(!$content['charset'] && $content['plugin_options']['charset']) {
$content['charset'] = $content['plugin_options']['charset'];
}
if(!$content['has_header_line'] && $content['plugin_options']['has_header_line']) {
$content['num_header_lines'] = 1;
}
if(!$content['num_header_lines'] && $content['plugin_options']['num_header_lines']) {
$content['num_header_lines'] = $content['plugin_options']['num_header_lines'];
}
$sel_options['charset'] = $GLOBALS['egw']->translation->get_installed_charsets()+
array('utf-8' => 'utf-8 (Unicode)');
$preserv = $content;
unset ($preserv['button']);
return $this->step_templates[$content['step']];
}
}
/**
* Process the sample file, get the fields out of it, then allow them to be mapped onto
* the fields the destination understands. Also, set any translations to be done to the field.
*
* You can use the eTemplate
*/
function wizard_step50(&$content, &$sel_options, &$readonlys, &$preserv)
{
if($this->debug) error_log(get_class($this) . '::wizard_step50->$content '.print_r($content,true));
// return from step50
if ($content['step'] == 'wizard_step50')
{
array_shift($content['csv_fields']);
array_shift($content['field_mapping']);
array_shift($content['field_conversion']);
foreach($content['field_conversion'] as $field => $convert) {
if(!trim($convert)) unset($content['field_conversion'][$field]);
}
switch (array_search('pressed', $content['button']))
{
case 'next':
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],1);
case 'previous' :
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
default :
return $this->wizard_step50($content,$sel_options,$readonlys,$preserv);
}
}
// init step50
else
{
$content['msg'] = $this->steps['wizard_step50'];
$content['step'] = 'wizard_step50';
if(!$content['field_mapping'] && $content['plugin_options']) {
$content['field_mapping'] = $content['plugin_options']['field_mapping'];
$content['field_conversion'] = $content['plugin_options']['field_conversion'];
}
array_unshift($content['csv_fields'],array('row0'));
array_unshift($content['field_mapping'],array('row0'));
array_unshift($content['field_conversion'],array('row0'));
$j = 1;
foreach ($content['csv_fields'] as $field)
{
if(strstr($field,'no_csv_')) $j++;
}
while ($j <= 3)
{
$content['csv_fields'][] = 'no_csv_'.$j;
$content['field_mapping'][] = $content['field_conversion'][] = '';
$j++;
}
$sel_options['field_mapping'] = array('' => lang('none')) + $this->mapping_fields;
$preserv = $content;
unset ($preserv['button']);
return $this->step_templates[$content['step']];
}
}
/**
* Edit conditions
*/
function wizard_step55(&$content, &$sel_options, &$readonlys, &$preserv)
{
if($this->debug) error_log(get_class($this) . '::wizard_step55->$content '.print_r($content,true));
// return from step55
if ($content['step'] == 'wizard_step55')
{
array_shift($content['conditions']);
foreach($content['conditions'] as $key => &$condition) {
// Clear empties
if($condition['string'] == '') {
unset($content['conditions'][$key]);
continue;
}
}
switch (array_search('pressed', $content['button']))
{
case 'next':
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],1);
case 'previous' :
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],-1);
case 'finish':
return 'wizard_finish';
case 'add':
return $GLOBALS['egw']->importexport_definitions_ui->get_step($content['step'],0);
default :
return $this->wizard_step55($content,$sel_options,$readonlys,$preserv);
break;
}
}
// init step55
$content['msg'] = $this->steps['wizard_step55'];
$content['step'] = 'wizard_step55';
if(!$content['conditions'] && $content['plugin_options']['conditions']) {
$content['conditions'] = $content['plugin_options']['conditions'];
}
foreach($content['field_mapping'] as $field) {
$sel_options['string'][$field] = $this->mapping_fields[$field];
}
$sel_options['type'] = $this->conditions;
$sel_options['action'] = $this->actions;
// Make 3 empty conditions
$j = 1;
foreach ($content['conditions'] as $condition)
{
if(!$condition['string']) $j++;
}
while ($j <= 3)
{
$content['conditions'][] = array('string' => '');
$j++;
}
// Leave room for heading
array_unshift($content['conditions'], false);
$preserv = $content;
unset ($preserv['button']);
return $this->step_templates[$content['step']];
}
}

View File

@ -0,0 +1,37 @@
/**
* eGroupWare
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @copyright Cornelius Weiss <nelius@cwtech.de>
* @version $Id:$
*/
function export_dialog() {
this.change_definition = function(sel_obj) {
if(sel_obj.value == 'expert') {
xajax_doXMLHTTP('importexport.importexport_export_ui.ajax_get_plugins',document.getElementById('exec[appname]') ? document.getElementById('exec[appname]').value : this.appname);
// next two lines fix some strange layout bug
//set_style_by_class('tr','select_definition','display','none');
//set_style_by_class('tr','select_definition','display','inline');
set_style_by_class('tr','select_plugin','display','table-row');
set_style_by_class('tr','save_definition','display','inline');
document.getElementById('importexport.export_dialog.selection_tab-tab').style.visibility='visible';
document.getElementById('importexport.export_dialog.options_tab-tab').style.visibility='visible';
}
else {
xajax_doXMLHTTP('importexport.importexport_export_ui.ajax_get_definition_description',sel_obj.value);
set_style_by_class('tr','select_plugin','display','none');
set_style_by_class('tr','save_definition','display','none');
document.getElementById('importexport.export_dialog.selection_tab-tab').style.visibility='hidden';
document.getElementById('importexport.export_dialog.options_tab-tab').style.visibility='hidden';
enable_button('exec[export]');
enable_button('exec[preview]');
}
};
this.appname = '';
}
var export_dialog = new export_dialog();

View File

@ -0,0 +1,40 @@
%1 records processed importexport cs %1 záznamů zpracováno
allowed users importexport cs Oprávnění uživatelé
automatically created by importexport importexport cs Automaticky vytvořeno aplikací ImportExport
basic csv import importexport cs Základní CSV import
choose a name for this definition importexport cs Zvolte název pro tuto definici
choose a plugin importexport cs Zvolte plugin
choose an application importexport cs Zvolte aplikaci
choose seperator and charset importexport cs Vybrat oddělovač a znakovou sadu
define imports|exports common cs Definovat importy|exporty
delete all selected definitions importexport cs Smazat VŠECHNY vybrané definice
edit conditions importexport cs Editovat podmínky
expert options importexport cs Rozšířené volby
export importexport cs Exportovat
export all selected definitions importexport cs Exportovat VŠECHNY vybrané definice
finish importexport cs Dokončit
general importexport cs Obecné
import importexport cs import
import definitions common cs Definice importu
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport cs Importovat definice (Pozor: Stávající definice téhož jména budou přepsány!!!)
importexport common cs Import a export
importexport wizard finished successfully! importexport cs Průvodce aplikace ImportExport úspěšně dokončen!
imports information from a csv file. this is only a base class, and doesn't do anything on its own. importexport cs Importuje informace z CSV souboru. Jedná se o základní úroveň, program nic nedělá na vlastní pěst.
load sample file importexport cs Nahrát ukázkový soubor
manage mapping importexport cs Spravovat mapování
next importexport cs Další
no records selected importexport cs Nebyly vybrány žádné záznamy
preview importexport cs Náhled
previous importexport cs Předchozí
save as definition importexport cs Uložit jako definici
schedule common cs Plán
schedule import / export common cs Plánovat import / export
schedule not found importexport cs Nebyl nalezen žádný plán
select definition importexport cs Vybrat definici
select plugin importexport cs Vybrat plugin
some nice text importexport cs nějaký pěkný text
unable to import: importexport cs Nebylo možné importovat:
unable to schedule importexport cs Není možné naplánovat
which useres are allowed for this definition importexport cs Oprávnění uživatelé této definice
which users are allowed to use this definition importexport cs Kteří uživatelé mohou použít tuto definici
you need to select an app and format first! importexport cs Nejprve musíte vybrat aplikaci a formát!

View File

@ -0,0 +1,40 @@
%1 records processed importexport de %1 Einträge ausgeführt
allowed users importexport de Erlaubte Benutzer
automatically created by importexport importexport de Wurde automatisch vom Import/Export Modul erstellt
basic csv import importexport de Basis CSV Import
choose a name for this definition importexport de Wählen sie einen Namen für diese Definition.
choose a plugin importexport de Wählen sie ein Plugin.
choose an application importexport de Wählen sei eine Anwendung.
choose seperator and charset importexport de Wählen Sie das Trennzeichen und den Zeichensatz aus
define imports|exports common de Profil definieren
delete all selected definitions importexport de Alle ausgewählten Definitionen löschen
edit conditions importexport de Einstellmöglichkeiten bearbeiten
expert options importexport de Export Optionen
export importexport de Exportieren
export all selected definitions importexport de Alle ausgewählten Definitionen exportieren
finish importexport de Fertig
general importexport de Generell
import importexport de Import
import definitions common de Import von Definitionsdateien
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport de Definitionen importieren (Achtung: Alle gleichnamigen existierenden Definitionen werden überschrieben!)
importexport common de Import/Export
importexport wizard finished successfully! importexport de Der ImportExport Assistent wurde erfolgreich beendet
imports information from a csv file. this is only a base class, and doesn't do anything on its own. importexport de Importiert Infomationen aus einem CSV Datei. Dies ist nur eine Basis Klasse.
load sample file importexport de Beispieldatei laden
manage mapping importexport de Zuordnung bearbeiten
next importexport de Weiter
no records selected importexport de Keine Datensätze ausgewählt
preview importexport de Vorschau
previous importexport de Zurück
save as definition importexport de Als Definition speichern
schedule common de Zeitplan zum Import bzw. Export festlegen
schedule import / export common de Zeitplan für Import/Export
schedule not found importexport de Kein Zeitplan gefunden
select definition importexport de Definition auswählen
select plugin importexport de Plugin auswählen
some nice text importexport de Ein schöner Text
unable to import: importexport de Kein Import möglich
unable to schedule importexport de Zeitplan nicht möglich
which useres are allowed for this definition importexport de Welche Benutzer dürden diese Definition verwenden?
which users are allowed to use this definition importexport de Welche Benutzer dürfen die Definition benutzen?
you need to select an app and format first! importexport de Sie müssen zuerst eine Anwendung und ein Format auswählen

View File

@ -0,0 +1,40 @@
%1 records processed importexport en %1 records processed
allowed users importexport en Allowed users
automatically created by importexport importexport en Automatically created by importexport
basic csv import importexport en Basic CSV import
choose a name for this definition importexport en Choose a name for this definition
choose a plugin importexport en Choose a plugin
choose an application importexport en Choose an application
choose seperator and charset importexport en Choose seperator and charset
define imports|exports common en Define imports|exports
delete all selected definitions importexport en delete ALL selected definitions
edit conditions importexport en Edit conditions
expert options importexport en Expert options
export importexport en Export
export all selected definitions importexport en export ALL selected definitions
finish importexport en finish
general importexport en General
import importexport en import
import definitions common en Import definitions
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport en Import definitions (Attension: Existing definitions with equal names will be overwritten!!!)
importexport common en importexport
importexport wizard finished successfully! importexport en ImportExport wizard finished successfully!
imports information from a csv file. this is only a base class, and doesn't do anything on its own. importexport en Imports information from a CSV file. This is only a base class, and doesn't do anything on its own.
load sample file importexport en Load Sample file
manage mapping importexport en Manage mapping
next importexport en next
no records selected importexport en No records selected
preview importexport en Preview
previous importexport en previous
save as definition importexport en Save as definition
schedule common en Schedule
schedule import / export common en Schedule import / export
schedule not found importexport en Schedule not found
select definition importexport en Select definition
select plugin importexport en Select plugin
some nice text importexport en some nice text
unable to import: importexport en Unable to import:
unable to schedule importexport en Unable to schedule
which useres are allowed for this definition importexport en Which useres are allowed for this definition
which users are allowed to use this definition importexport en Which users are allowed to use this definition
you need to select an app and format first! importexport en You need to select an app and format first!

View File

@ -0,0 +1,22 @@
allowed users importexport es-es Usuarios permitidos
automatically created by importexport importexport es-es Creados automáticamente por importexport
choose a name for this definition importexport es-es Elija un nombre para esta definición
choose a plugin importexport es-es Elija un plugin
choose an application importexport es-es Elija una aplicación
delete all selected definitions importexport es-es Borrar TODAS las definiciones seleccionadas
expert options importexport es-es Opciones de experto
export importexport es-es Exportar
export all selected definitions importexport es-es Exportar TODAS las definiciones seleccionadas
finish importexport es-es Terminar
general importexport es-es General
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport es-es Importar definiciones (¡¡Atención: se sobreescribirán las definiciones existentes con el mismo nombre!!)
importexport wizard finished successfully! importexport es-es ¡El asistente de Importar-Exportar finalizó correctamente!
next importexport es-es Siguiente
preview importexport es-es Vista previa
previous importexport es-es Anterior
save as definition importexport es-es Guardar como definición
select definition importexport es-es Seleccionar definición
select plugin importexport es-es Seleccionar plugin
some nice text importexport es-es Algún texto agradable
which useres are allowed for this definition importexport es-es Qué usuarios pueden usar esta definición
you need to select an app and format first! importexport es-es ¡Necesita seleccionar una aplicación y un formato antes!

View File

@ -0,0 +1,22 @@
allowed users importexport et Lubatud kasutajad
automatically created by importexport importexport et automaatselt tehtud Import-Eksport poolt
choose a name for this definition importexport et Vali nimi selle definitsioonijaoks
choose a plugin importexport et Vali plugin
choose an application importexport et Vali rakendus
delete all selected definitions importexport et kustuta KÕIK valitud definitsioonid
expert options importexport et Ekspordi omadused
export importexport et Eksport
export all selected definitions importexport et ekspordi KÕIK valitud definitsioonid
finish importexport et valmis
general importexport et Üldine
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport et Impordi definitsioonid (Ettevaatust: Olemasolevad definitsioonid mis on sama nimega kirjutatakse üle!!!)
importexport wizard finished successfully! importexport et Import-Eksport abimees lõpetas edukalt !
next importexport et järgmine
preview importexport et Eelvaade
previous importexport et eelmine
save as definition importexport et Salvesta kui definitsioon
select definition importexport et Vali definitsioon
select plugin importexport et Vali plugin
some nice text importexport et mõni lahe tekst
which useres are allowed for this definition importexport et Millised kasutajad on lubatud selle definitsioonijaoks
you need to select an app and format first! importexport et Vajalik on valida rakendus ja formaat esmalt!

View File

@ -0,0 +1,33 @@
allowed users importexport fi Sallittu käyttäjille
automatically created by importexport importexport fi Luotu automaattisesti tuonnissa/viennissä.
basic csv import importexport fi Perus CSV -tuonti
choose a name for this definition importexport fi Valitse nimi tälle selitteelle
choose a plugin importexport fi Valitse liitännäinen
choose an application importexport fi Valitse sovellus
choose seperator and charset importexport fi Valitse erotin ja merkistökoodaus
define imports|exports common fi Määrittele tuonti | vienti
delete all selected definitions importexport fi Poista kaikki selitteet
edit conditions importexport fi Muokkaa ehtoja
expert options importexport fi Vie optiot
export importexport fi Vienti
export all selected definitions importexport fi Vie kaikki valitut selitteet
finish importexport fi Valmis
general importexport fi Yleinen
import importexport fi Tuonti
import definitions common fi Tuo selitteet
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport fi Tuo selitteet (Huomio: Olemassaolevat samannimiset selitteet ylikirjoitetaan (overwrite)!!!
importexport common fi Tuonti|Vienti
importexport wizard finished successfully! importexport fi Tuonti|Vienti wizard lopetettu onnistuneesti!
load sample file importexport fi Lataa esimerkkitiedosto
next importexport fi Seuraava
no records selected importexport fi Tietueita ei ole valittu
preview importexport fi Esinäkymä
previous importexport fi Edellinen
save as definition importexport fi Tallenna selitteenä
select definition importexport fi Valitse selite
select plugin importexport fi Valitse PlugIn
some nice text importexport fi jotain kivaa tekstiä
unable to import: importexport fi Tuonti ei voitu suorittaa:
which useres are allowed for this definition importexport fi Kenellä on oikeus käyttää tätä selitettä
which users are allowed to use this definition importexport fi Kenellä on oikeus käyttää tätä selitettä
you need to select an app and format first! importexport fi Valitse ensin sovellus ja formaatti!

View File

@ -0,0 +1,8 @@
allowed users importexport fr Utilisateurs autorisés
choose a name for this definition importexport fr Choisissez un nom pour cette définition
choose a plugin importexport fr Choisissez un module enfichable
choose an application importexport fr Choisissez une application
finish importexport fr terminer
next importexport fr prochain
previous importexport fr précédent
which useres are allowed for this definition importexport fr Quels utilisateurs sont autorisés pour cette définition

View File

@ -0,0 +1,19 @@
allowed users importexport id Pengguna yang dibolehkan
define imports|exports common id Definisi impor|ekspor
edit conditions importexport id Edit conditions
expert options importexport id Expert options
export importexport id Ekspor
finish importexport id selesai
general importexport id Umum
import importexport id Impor
import definitions common id Impor definisi
importexport common id ImporEkspor
load sample file importexport id Muatkan berkas contoh
manage mapping importexport id Pengelolaan pemetaan
next importexport id berikutnya
preview importexport id Preview
previous importexport id sebelumnya
schedule common id Jadual
schedule import / export common id Jadualkan impor/ekspor
select definition importexport id Pilih definisi
select plugin importexport id Pilih plugin

View File

@ -0,0 +1,22 @@
allowed users importexport nl Toegestane gebruikers
automatically created by importexport importexport nl Automatisch aangemaakt door importexport
choose a name for this definition importexport nl Kies een naam voor deze definitie
choose a plugin importexport nl Kies een plugin
choose an application importexport nl Kies een toepassing
delete all selected definitions importexport nl verwijder ALLE geselecteerde definities
expert options importexport nl Expert opties
export importexport nl Export
export all selected definitions importexport nl exporteer ALLE geselecteerde definities
finish importexport nl beëindig
general importexport nl Algemeen
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport nl Importdefinities (Let op: Bestaande definities met dezelfde naam worden overschreven!!!)
importexport wizard finished successfully! importexport nl ImportExport wizard is succesvol geëindigd!
next importexport nl volgende
preview importexport nl Voorbeeld
previous importexport nl vorige
save as definition importexport nl Bewaar als definitie
select definition importexport nl Selecteer definitie
select plugin importexport nl Selecteer plugin
some nice text importexport nl een fraaie uitleg
which useres are allowed for this definition importexport nl Welke gebruikers mogen deze definitie gebruiken
you need to select an app and format first! importexport nl U moet eerst een toepassing en formaat selecteren!

View File

@ -0,0 +1,8 @@
allowed users importexport pl Użytkownicy z dostępem
choose a name for this definition importexport pl Wybierz nazwę dla tej definicji
choose a plugin importexport pl Wybierz wtyczkę
choose an application importexport pl Wybierz aplikację
finish importexport pl zakończ
next importexport pl następny
previous importexport pl poprzedni
which useres are allowed for this definition importexport pl Którzy użytkownicy mają dostęp do tej definicji?

View File

@ -0,0 +1,22 @@
allowed users importexport pt-br Usuários permitidos
automatically created by importexport importexport pt-br Automaticamente criado por importar/exportar
choose a name for this definition importexport pt-br Escolha um nome para esta definição
choose a plugin importexport pt-br EScolha um plugin
choose an application importexport pt-br Escolha uma aplicação
delete all selected definitions importexport pt-br remover TODAS as definições selecionadas
expert options importexport pt-br Opções avançadas
export importexport pt-br Exportar
export all selected definitions importexport pt-br exportar TODAS as definições selecionadas
finish importexport pt-br terminar
general importexport pt-br Geral
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport pt-br Importar definições (Atenção: definições existentes com nomes iguais serão substituídas!!!)
importexport wizard finished successfully! importexport pt-br Assistente de importação/exportação terminado com sucesso!
next importexport pt-br próximo
preview importexport pt-br Pré-visualização
previous importexport pt-br anterior
save as definition importexport pt-br Salvar como definição
select definition importexport pt-br Selecionar definição
select plugin importexport pt-br Selecionar plugin
some nice text importexport pt-br algum texto legal
which useres are allowed for this definition importexport pt-br Quais usuários são permitidos para esta definição
you need to select an app and format first! importexport pt-br Você deve selecionar um aplicativo e um formato primeiro!

View File

@ -0,0 +1,22 @@
allowed users importexport ru Пользователи имеющие доступ
automatically created by importexport importexport ru Автоматически создано ИмпортЭкспорт'ом
choose a name for this definition importexport ru Выберите название для этого определения
choose a plugin importexport ru Выберите модуль расширения
choose an application importexport ru Выберите приложение
delete all selected definitions importexport ru удаление ВСЕХ выбранных определений
expert options importexport ru Настройки для эксперта
export importexport ru Экспорт
export all selected definitions importexport ru экспорт ВСЕХ выбранных определений
finish importexport ru конец
general importexport ru Общее
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport ru Импорт определений (Внимание: Существующие определения с совпадающими именами будут перезаписаны !!!)
importexport wizard finished successfully! importexport ru Мастер настройки ИмпортЭкспорта завершил работу успешно!
next importexport ru следующий
preview importexport ru Предварительный просмотр
previous importexport ru Предыдущий
save as definition importexport ru Сохранить как определение
select definition importexport ru Выбор определения
select plugin importexport ru Выбор модуля расширения
some nice text importexport ru некий приятный текст
which useres are allowed for this definition importexport ru Какие пользователи меют доступ к этому определению
you need to select an app and format first! importexport ru Вы должны сначала выбрать приложение и формат!

View File

@ -0,0 +1,22 @@
allowed users importexport sk Oprávnení používatelia
automatically created by importexport importexport sk Automaticky vytvorené aplikáciou importexport
choose a name for this definition importexport sk Zvoľte názov pre túto definíciu
choose a plugin importexport sk Zvoľte zásuvný modul (plugin)
choose an application importexport sk Zvoľte aplikáciu
delete all selected definitions importexport sk Odstrániť VŠETKY vybrané definície
expert options importexport sk Možnosti pre expertov
export importexport sk Export
export all selected definitions importexport sk Exportovať VŠETKY vybrané definície
finish importexport sk Dokončiť
general importexport sk Hlavné
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport sk Importovať definície (Pozor: Existujúce definície so zhodnými názvami sa prepíšu!!)
importexport wizard finished successfully! importexport sk Sprievodca ImportExport bol úspešne ukončený!
next importexport sk Ďalšie
preview importexport sk Náhľad
previous importexport sk Predchádzajúce
save as definition importexport sk Uložiť ako definíciu
select definition importexport sk Vybrať definíciu
select plugin importexport sk Vybrať zásuvný modul
some nice text importexport sk nejaký pekný text
which useres are allowed for this definition importexport sk Ktorí používatelia sú oprávnení pre túto definíciu
you need to select an app and format first! importexport sk Najprv potrebujete vybrať aplikáciu a formát!

View File

@ -0,0 +1,22 @@
allowed users importexport sl Dovoljeni uporabniki
automatically created by importexport importexport sl Samodejno ustvarjeno z Importexport
choose a name for this definition importexport sl Izberite ime za to definicijo
choose a plugin importexport sl Izberite vtičnik
choose an application importexport sl Izberite aplikacijo
delete all selected definitions importexport sl Izbriši vse izbrane definicije
expert options importexport sl Napredne možnosti
export importexport sl Izvozi
export all selected definitions importexport sl Izvozi vse izbrane definicije
finish importexport sl Končaj
general importexport sl Splošno
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport sl Uvozi definicije (pozor: obstoječe definicije z enakim imenom bodo prepisane!)
importexport wizard finished successfully! importexport sl Čarovnik ImportExport se je uspešno zaključil.
next importexport sl Naslednji
preview importexport sl Predogled
previous importexport sl Prejšnji
save as definition importexport sl Shrani kot definicijo
select definition importexport sl Izberi definicijo
select plugin importexport sl Izberi vtičnik
some nice text importexport sl Nekaj ljubkega besedila
which useres are allowed for this definition importexport sl Kateri uporabniki so dovoljeni za to definicijo
you need to select an app and format first! importexport sl Najprej morate izbrati aplikacijo in obliko.

View File

@ -0,0 +1,8 @@
allowed users importexport zh-tw 允許使用的帳號
choose a name for this definition importexport zh-tw 選擇這個定義的名稱
choose a plugin importexport zh-tw 選擇一個外掛
choose an application importexport zh-tw 選擇一個模組
finish importexport zh-tw 完成
next importexport zh-tw 下一個
previous importexport zh-tw 上一個
which useres are allowed for this definition importexport zh-tw 哪個使用者可以運用這個定義

View File

@ -0,0 +1,23 @@
allowed users importexport zh 允许的用户
automatically created by importexport importexport zh 导入导出自动地创建
choose a name for this definition importexport zh 选择这个定义的名称
choose a plugin importexport zh 选择一插件
choose an application importexport zh 选择一应用程序
delete all selected definitions importexport zh 删除所有选择的定义
expert options importexport zh 高级选项
export importexport zh 导出
export all selected definitions importexport zh 导出所有选择的定义
finish importexport zh 完成
general importexport zh 通用
import definitions (attension: existing definitions with equal names will be overwritten!!!) importexport zh 导入定义(注意:现有的同名定义将被覆盖!)
importexport common zh 导入导出
importexport wizard finished successfully! importexport zh 导入导出向导成功地完成!
next importexport zh 下一个
preview importexport zh 预览
previous importexport zh 上一个
save as definition importexport zh 保存为默认
select definition importexport zh 选择定义
select plugin importexport zh 选择插件
some nice text importexport zh 一些不错的文本
which useres are allowed for this definition importexport zh 哪个用户考虑到这一定义
you need to select an app and format first! importexport zh 您需要选择应用程序并首先格式化!

View File

@ -0,0 +1,36 @@
<?php
/**
* eGroupWare - importexport
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @link http://www.egroupware.org
* @author Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
if (!extension_loaded('dom'))
{
echo "<p>Required PHP DOM extension missing, installation of ImportExport definitions aborted.</p>\n";
return; // otherwise we mess up the whole eGroupware install process
}
require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.importexport_definitions_bo.inc.php');
// This sets up $GLOBALS['egw']->accounts and $GLOBALS['egw']->db
$GLOBALS['egw_setup']->setup_account_object();
// step through every source code intstalled app
$egwdir = dir(EGW_INCLUDE_ROOT);
while (false !== ($appdir = $egwdir->read())) {
$defdir = EGW_INCLUDE_ROOT. "/$appdir/importexport/definitions";
if ( !is_dir( $defdir ) ) continue;
// step through each file in defdir of app
$d = dir($defdir);
while (false !== ($entry = $d->read())) {
$file = $defdir. '/'. $entry;
list( $filename, $extension) = explode('.',$entry);
if ( $extension != 'xml' ) continue;
importexport_definitions_bo::import( $file );
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
* eGroupWare - eTemplates for Application importexport
* http://www.egroupware.org
* generated by soetemplate::dump4setup() 2010-03-11 10:40
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @subpackage setup
* @version $Id$
*/
$templ_version=1;
$templ_data[] = array('name' => 'importexport.definition_index','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:4:{s:4:"span";s:13:"all,redItalic";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";s:4:"type";s:5:"label";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:2:{s:2:"c1";s:2:"th";s:2:"c2";s:7:"row,top";}i:1;a:6:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";s:4:"span";s:11:",lr_padding";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Name";s:4:"span";s:11:",lr_padding";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";s:4:"span";s:11:",lr_padding";}s:1:"D";a:4:{s:5:"align";s:6:"center";s:4:"type";s:5:"label";s:5:"label";s:13:"Allowed users";s:4:"span";s:11:",lr_padding";}s:1:"E";a:5:{s:5:"label";s:3:"Add";s:5:"align";s:6:"center";s:4:"type";s:6:"button";s:4:"span";s:11:",lr_padding";s:7:"onclick";s:226:"window.open(egw::link(\'/index.php\',\'menuaction=importexport.importexport_definitions_ui.wizard\'),\'\',\'dependent=yes,width=500,height=500,location=no,menubar=no,toolbar=no,scrollbars=yes,status=yes\'); return false; return false;";}s:1:"F";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:6:{s:5:"label";s:6:"Delete";s:4:"name";s:15:"delete_selected";s:4:"type";s:6:"button";s:4:"help";s:31:"delete ALL selected definitions";s:4:"size";s:6:"delete";s:7:"onclick";s:65:"return confirm(\'Do you really want to DELETE this definitions?\');";}i:2;a:5:{s:5:"label";s:6:"Export";s:4:"name";s:15:"export_selected";s:4:"type";s:6:"button";s:4:"help";s:31:"export ALL selected definitions";s:4:"size";s:10:"fileexport";}}}i:2;a:6:{s:1:"A";a:4:{s:7:"no_lang";s:1:"1";s:4:"type";s:5:"image";s:4:"span";s:11:",lr_padding";s:4:"name";s:12:"${row}[type]";}s:1:"B";a:4:{s:7:"no_lang";s:1:"1";s:4:"name";s:12:"${row}[name]";s:4:"type";s:5:"label";s:4:"span";s:11:",lr_padding";}s:1:"C";a:4:{s:7:"no_lang";s:1:"1";s:4:"name";s:19:"${row}[application]";s:4:"type";s:5:"label";s:4:"span";s:11:",lr_padding";}s:1:"D";a:6:{s:7:"no_lang";s:1:"1";s:4:"type";s:14:"select-account";s:4:"span";s:11:",lr_padding";s:8:"readonly";s:1:"1";s:4:"name";s:21:"${row}[allowed_users]";s:4:"size";s:6:"5,both";}s:1:"E";a:5:{s:5:"align";s:6:"center";s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:5:"label";s:4:"Edit";s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:7:"onclick";s:251:"window.open(egw::link(\'/index.php\',\'menuaction=importexport.importexport_definitions_ui.edit&definition=$row_cont[name]\'),\'\',\'dependent=yes,width=500,height=500,location=no,menubar=no,toolbar=no,scrollbars=yes,status=yes\'); return false; return false;";}i:2;a:6:{s:5:"label";s:6:"Delete";s:7:"onclick";s:41:"return confirm(\'Delete this definition\');";s:4:"name";s:32:"delete[$row_cont[definition_id]]";s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:4:"help";s:21:"Delete this eTemplate";}}s:1:"F";a:4:{s:5:"align";s:6:"center";s:4:"name";s:34:"selected[$row_cont[definition_id]]";s:4:"type";s:8:"checkbox";s:4:"help";s:34:"select this eTemplate to delete it";}}}s:4:"cols";i:6;s:4:"rows";i:2;}}}s:4:"cols";i:1;s:4:"rows";i:2;s:4:"size";s:4:"100%";}}','size' => '100%','style' => '.redItalic { color:red; font-style:italic;} td.lr_padding { padding-left: 5px; padding-right: 5px; }','modified' => '1145972373',);
$templ_data[] = array('name' => 'importexport.export_dialog','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:1:{s:2:"c3";s:15:"save_definition";}i:1;a:1:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:3:"tab";s:5:"label";s:25:"General|Selection|Options";s:4:"name";s:37:"general_tab|selection_tab|options_tab";}}i:3;a:1:{s:1:"A";a:3:{s:4:"type";s:8:"checkbox";s:5:"label";s:18:"Save as definition";s:4:"name";s:18:"save_as_definition";}}i:4;a:1:{s:1:"A";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:4:"span";s:3:"all";i:1;a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Export";s:4:"name";s:6:"export";s:7:"onclick";s:36:"xajax_eT_wrapper(this);return false;";}i:2;a:4:{s:4:"type";s:6:"button";s:5:"label";s:7:"Preview";s:4:"name";s:7:"preview";s:7:"onclick";s:36:"xajax_eT_wrapper(this);return false;";}}i:2;a:5:{s:4:"type";s:6:"button";s:5:"label";s:6:"Cancel";s:5:"align";s:5:"right";s:4:"name";s:6:"cancel";s:7:"onclick";s:29:"window.close(); return false;";}}}i:5;a:1:{s:1:"A";a:6:{s:4:"type";s:3:"box";s:4:"size";s:1:"1";s:4:"name";s:11:"preview-box";s:6:"needed";s:1:"1";i:1;a:1:{s:4:"type";s:5:"label";}s:4:"span";s:12:",preview-box";}}i:6;a:1:{s:1:"A";a:7:{s:4:"type";s:3:"box";s:4:"size";s:1:"1";s:4:"span";s:20:",preview-box-buttons";s:4:"name";s:19:"preview-box-buttons";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:2:"OK";s:5:"align";s:6:"center";s:7:"onclick";s:167:"document.getElementById(form::name(\'preview-box\')).style.display=\'none\'; document.getElementById(form::name(\'preview-box-buttons\')).style.display=\'none\'; return false;";}s:6:"needed";s:1:"1";s:5:"align";s:6:"center";}}}s:4:"rows";i:6;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '.preview-box {
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 360px;
overflow: scroll;
background-color: white;
z-index: 999;
display: none;
}
.preview-box-buttons {
position: absolute;
top: 365px;
left: 0px;
width: 400px;
height: 20px;
z-index: 999;
display: none;
}','modified' => '1158220473',);
$templ_data[] = array('name' => 'importexport.export_dialog.general_tab','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:1:{s:2:"c1";s:4:",top";}i:1;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:6:"export";}s:1:"B";a:2:{s:4:"type";s:8:"template";s:4:"name";s:46:"importexport.export_dialog.general_tab_content";}}}s:4:"rows";i:1;s:4:"cols";i:2;s:4:"size";s:6:",200px";s:7:"options";a:1:{i:1;s:5:"200px";}}}','size' => ',200px','style' => '','modified' => '1158223670',);
$templ_data[] = array('name' => 'importexport.export_dialog.general_tab_content','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:3:{s:2:"c2";s:14:"select_appname";s:2:"c3";s:17:"select_definition";s:2:"c4";s:13:"select_plugin";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:5:"label";s:14:"some nice text";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:18:"Select application";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"appname";s:8:"onchange";s:87:"xajax_doXMLHTTP(\'importexport.importexport_export_ui.ajax_get_definitions\',this.value);";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Select definition";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:10:"definition";s:8:"onchange";s:52:"export_dialog.change_definition(this); return false;";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:13:"Select plugin";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:8:"onchange";s:94:"xajax_doXMLHTTP(\'importexport.importexport_export_ui.ajax_get_definition_options\',this.value);";s:7:"no_lang";s:1:"1";s:4:"name";s:6:"plugin";}}i:5;a:2:{s:1:"A";a:6:{s:4:"type";s:3:"box";s:4:"span";s:3:"all";s:4:"name";s:18:"plugin_description";s:6:"needed";s:1:"1";s:4:"size";s:1:"1";i:1;a:7:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:6:"needed";s:1:"1";i:1;a:4:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:6:"needed";s:1:"1";s:5:"label";s:11:"Description";}i:2;a:2:{s:4:"type";s:5:"label";s:4:"name";s:18:"plugin_description";}s:4:"name";s:11:"description";s:7:"no_lang";s:1:"1";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:5;s:4:"cols";i:2;}}','size' => '','style' => '','modified' => '1158223021',);
$templ_data[] = array('name' => 'importexport.export_dialog.options_tab','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:1:{s:2:"c1";s:4:",top";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:4:"html";s:4:"name";s:19:"plugin_options_html";s:7:"no_lang";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:6:",200px";s:7:"options";a:1:{i:1;s:5:"200px";}}}','size' => ',200px','style' => '','modified' => '1158223824',);
$templ_data[] = array('name' => 'importexport.export_dialog.selection_tab','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:1:{s:2:"c1";s:4:",top";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:4:"html";s:4:"name";s:21:"plugin_selectors_html";s:7:"no_lang";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:6:",200px";s:7:"options";a:1:{i:1;s:5:"200px";}}}','size' => ',200px','style' => '','modified' => '1158223796',);
$templ_data[] = array('name' => 'importexport.import_definition','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:92:"Import definitions (Attension: Existing definitions with equal names will be overwritten!!!)";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:4:"file";s:4:"name";s:11:"import_file";}}i:3;a:1:{s:1:"A";a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Import";s:4:"name";s:6:"import";}}}s:4:"rows";i:3;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1150533844',);
$templ_data[] = array('name' => 'importexport.import_dialog','template' => '','lang' => '','group' => '0','version' => '0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:1:{s:2:"h1";s:10:",!@message";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:11:"all,message";s:4:"name";s:7:"message";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";}s:1:"B";a:3:{s:4:"type";s:6:"select";s:4:"name";s:7:"appname";s:8:"onchange";s:87:"xajax_doXMLHTTP(\'importexport.importexport_import_ui.ajax_get_definitions\',this.value);";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Import definition";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:10:"definition";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:28:"Please select file to import";}s:1:"B";a:2:{s:4:"type";s:4:"file";s:4:"name";s:4:"file";}}i:5;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:6;a:2:{s:1:"A";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";s:4:"span";s:3:"all";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Import";s:4:"name";s:6:"import";}i:2;a:3:{s:4:"type";s:6:"button";s:4:"name";s:6:"cancel";s:5:"label";s:6:"Cancel";}i:3;a:4:{s:4:"type";s:8:"checkbox";s:4:"name";s:7:"dry-run";s:5:"label";s:9:"Test only";s:5:"align";s:5:"right";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:6;s:4:"cols";i:2;}}','size' => '','style' => '','modified' => '1266439013',);
$templ_data[] = array('name' => 'importexport.schedule_edit','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:9:{i:0;a:1:{s:2:"h1";s:10:",!@message";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:11:"all,message";s:4:"name";s:7:"message";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:4:"type";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";}s:1:"B";a:3:{s:4:"type";s:6:"select";s:4:"name";s:7:"appname";s:8:"onchange";s:137:"xajax_doXMLHTTP(\'importexport.importexport_schedule_ui.ajax_get_plugins\', document.getElementById(form::name(\'type\')).value, this.value);";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Plugin";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:4:"name";s:6:"plugin";s:4:"size";s:9:"Select...";s:8:"onchange";s:144:"xajax_doXMLHTTP(\'importexport.importexport_schedule_ui.ajax_get_definitions\', document.getElementById(form::name(\'appname\')).value, this.value);";}}i:5;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:10:"Definition";}s:1:"B";a:3:{s:4:"type";s:6:"select";s:4:"name";s:10:"definition";s:4:"size";s:9:"Select...";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Target";}s:1:"B";a:3:{s:4:"type";s:4:"text";s:4:"size";s:2:"50";s:4:"name";s:6:"target";}}i:7;a:2:{s:1:"A";a:7:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"c1";s:2:"th";}i:1;a:6:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Year";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Month";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"Day";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Day of week";}s:1:"E";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Hour";}s:1:"F";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Minute";}}i:2;a:6:{s:1:"A";a:3:{s:4:"type";s:4:"text";s:4:"name";s:4:"year";s:4:"size";s:1:"5";}s:1:"B";a:3:{s:4:"type";s:4:"text";s:4:"name";s:5:"month";s:4:"size";s:1:"5";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:3:"day";s:4:"size";s:1:"5";}s:1:"D";a:4:{s:4:"type";s:4:"text";s:4:"name";s:3:"dow";s:5:"align";s:6:"center";s:4:"size";s:1:"5";}s:1:"E";a:3:{s:4:"type";s:4:"text";s:4:"name";s:4:"hour";s:4:"size";s:1:"5";}s:1:"F";a:3:{s:4:"type";s:4:"text";s:4:"name";s:3:"min";s:4:"size";s:1:"5";}}i:3;a:6:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:1:"3";s:5:"label";s:11:"(* for all)";}s:1:"B";a:1:{s:4:"type";s:5:"label";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:12:"(0-6, 0=Sun)";}s:1:"E";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"(0-23)";}s:1:"F";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:3;s:4:"cols";i:6;s:4:"name";s:8:"schedule";s:4:"span";s:3:"all";s:7:"options";a:0:{}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:8;a:2:{s:1:"A";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:4:"span";s:3:"all";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:4:"save";}i:2;a:4:{s:4:"type";s:6:"button";s:4:"name";s:6:"cancel";s:5:"label";s:6:"Cancel";s:7:"onclick";s:13:"self.close();";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:8;s:4:"cols";i:2;}}','size' => '','style' => '','modified' => '1267036378',);
$templ_data[] = array('name' => 'importexport.schedule_index','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:11:"all,message";s:4:"name";s:4:"@msg";}}i:2;a:1:{s:1:"A";a:6:{s:4:"type";s:4:"grid";s:4:"name";s:9:"scheduled";s:7:"options";a:0:{}s:4:"data";a:3:{i:0;a:2:{s:2:"c1";s:2:"th";s:2:"c2";s:4:",top";}i:1;a:8:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Application";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Plugin";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:10:"Definition";}s:1:"E";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Target";}s:1:"F";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Last Run";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Next Run";}i:2;a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Schedule";}}s:1:"H";a:1:{s:4:"type";s:5:"label";}}i:2;a:8:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[type]";}s:1:"B";a:3:{s:4:"type";s:10:"select-app";s:4:"name";s:15:"${row}[appname]";s:8:"readonly";s:1:"1";}s:1:"C";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:14:"${row}[plugin]";s:8:"readonly";s:1:"1";}s:1:"D";a:3:{s:4:"type";s:6:"select";s:4:"name";s:18:"${row}[definition]";s:8:"readonly";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:14:"${row}[target]";}s:1:"F";a:6:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"4";i:1;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[last_run]";s:8:"readonly";s:1:"1";}i:2;a:3:{s:4:"type";s:5:"label";s:4:"name";s:20:"${row}[record_count]";s:7:"no_lang";s:1:"1";}i:3;a:3:{s:4:"type";s:5:"label";s:4:"name";s:14:"${row}[result]";s:7:"no_lang";s:1:"1";}i:4;a:2:{s:4:"type";s:5:"label";s:4:"name";s:14:"${row}[errors]";}}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:12:"${row}[next]";s:8:"readonly";s:1:"1";}i:2;a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"${row}[times]";}}s:1:"H";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:4:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:4:"name";s:21:"edit[${row_cont[id]}]";s:7:"onclick";s:198:"window.open(egw::link(\'/index.php\',\'menuaction=importexport.importexport_schedule_ui.edit&id={$row_cont[id]}\'),\'_blank\',\'dependent=yes,width=600,height=450,scrollbars=yes,status=yes\'); return false;";}i:2;a:3:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:4:"name";s:23:"delete[{$row_cont[id]}]";}}}}s:4:"rows";i:2;s:4:"cols";i:8;}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"1";s:4:"span";s:3:"all";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:3:"add";s:4:"name";s:3:"add";s:7:"onclick";s:179:"window.open(egw::link(\'/index.php\',\'menuaction=importexport.importexport_schedule_ui.edit\'),\'_blank\',\'dependent=yes,width=600,height=450,scrollbars=yes,status=yes\'); return false;";}}}}s:4:"rows";i:3;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1267034207',);
$templ_data[] = array('name' => 'importexport.wizardbox','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:2:"c2";s:7:",bottom";s:2:"c1";s:4:",top";s:1:"A";s:4:"100%";}i:1;a:1:{s:1:"A";a:5:{s:4:"type";s:4:"hbox";s:7:"no_lang";s:1:"1";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:4:"hbox";s:7:"no_lang";s:1:"1";s:4:"size";s:1:"1";i:1;a:3:{s:4:"type";s:5:"image";s:7:"no_lang";s:1:"1";s:4:"name";s:12:"importexport";}}i:2;a:4:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:14:"wizard_content";}s:4:"span";s:15:",wizard_content";}}}i:2;a:1:{s:1:"A";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:4:"span";s:3:"all";i:1;a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:4:{s:4:"type";s:6:"button";s:4:"name";s:16:"button[previous]";s:5:"label";s:8:"previous";s:7:"onclick";s:37:"xajax_eT_wrapper(this); return false;";}i:2;a:4:{s:4:"type";s:6:"button";s:4:"name";s:12:"button[next]";s:5:"label";s:4:"next";s:7:"onclick";s:37:"xajax_eT_wrapper(this); return false;";}i:3;a:4:{s:4:"type";s:6:"button";s:4:"name";s:14:"button[finish]";s:5:"label";s:6:"finish";s:7:"onclick";s:37:"xajax_eT_wrapper(this); return false;";}}i:2;a:5:{s:4:"type";s:6:"button";s:4:"name";s:14:"button[cancel]";s:5:"label";s:6:"cancel";s:7:"onclick";s:29:"window.close(); return false;";s:5:"align";s:5:"right";}s:5:"align";s:5:"right";}}}s:4:"rows";i:2;s:4:"cols";i:1;s:4:"size";s:4:",400";s:7:"options";a:1:{i:1;s:3:"400";}}}','size' => ',400','style' => '.wizard_content fieldset {
height: 347px;
width: 250px;
max-height:347px;
overflow:auto;
}','modified' => '1268325039',);
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.choosesepncharset','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:1:{s:1:"B";s:5:"180px";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:14:"Fieldseperator";}s:1:"B";a:4:{s:4:"type";s:4:"text";s:7:"no_lang";s:1:"1";s:4:"name";s:8:"fieldsep";s:4:"size";s:1:"1";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:15:"Charset of file";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"charset";s:4:"span";s:9:",width180";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:20:"Header lines to skip";}s:1:"B";a:3:{s:4:"type";s:3:"int";s:4:"name";s:16:"num_header_lines";s:4:"size";s:1:"0";}}}s:4:"rows";i:4;s:4:"cols";i:2;}}','size' => '','style' => '.width180 select { width:150px;}','modified' => '1268236708',);
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.conditions','template' => '','lang' => '','group' => '0','version' => '0.01','data' => 'a:1:{i:0;a:7:{s:4:"type";s:4:"vbox";s:4:"data";a:2:{i:0;a:0:{}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[string]";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[type]";}i:2;a:2:{s:4:"type";s:4:"text";s:4:"name";s:12:"${row}[op_2]";}}s:1:"C";a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[true]";}s:1:"D";a:2:{s:4:"type";s:6:"select";s:4:"name";s:13:"${row}[false]";}}}s:4:"rows";i:1;s:4:"cols";i:4;s:4:"size";s:1:"2";i:1;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"c1";s:2:"th";}i:1;a:6:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Field";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Condition";}s:1:"C";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";s:4:"span";s:1:"2";i:1;a:4:{s:4:"type";s:5:"label";s:4:"span";s:1:"2";s:5:"label";s:4:"True";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,2,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";}i:2;a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Stop";s:5:"align";s:5:"right";}}}s:1:"D";a:1:{s:4:"type";s:5:"label";}s:1:"E";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";s:4:"span";s:1:"2";i:1;a:4:{s:4:"type";s:5:"label";s:4:"span";s:1:"2";s:5:"label";s:5:"False";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,2,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";}i:2;a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Stop";s:5:"align";s:5:"right";}}}s:1:"F";a:1:{s:4:"type";s:5:"label";}}i:2;a:6:{s:1:"A";a:2:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[string]";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"${row}[type]";}i:2;a:2:{s:4:"type";s:4:"text";s:4:"name";s:12:"${row}[op_2]";}}s:1:"C";a:2:{s:4:"type";s:6:"select";s:4:"name";s:20:"${row}[true][action]";}s:1:"D";a:3:{s:4:"type";s:8:"checkbox";s:5:"align";s:6:"center";s:4:"name";s:18:"${row}[true][stop]";}s:1:"E";a:2:{s:4:"type";s:6:"select";s:4:"name";s:21:"${row}[false][action]";}s:1:"F";a:3:{s:4:"type";s:8:"checkbox";s:5:"align";s:6:"center";s:4:"name";s:19:"${row}[false][stop]";}}}s:4:"rows";i:2;s:4:"cols";i:6;s:4:"name";s:10:"conditions";s:7:"options";a:0:{}}i:2;a:5:{s:4:"type";s:6:"button";s:4:"name";s:3:"add";s:5:"label";s:3:"add";s:4:"help";s:59:"This causes a segfault... haven\'t figured out how to fix it";s:8:"disabled";s:1:"1";}}}','size' => '','style' => '','modified' => '1268236762',);
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.fieldmapping','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";s:4:"span";s:3:"all";}}i:2;a:1:{s:1:"A";a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"c1";s:2:"th";}i:1;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"CSV Field";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:12:"Target Field";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Translation";}}i:2;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:6:"${row}";s:7:"no_lang";s:1:"1";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:4:"name";s:16:"csv_fields[$row]";s:7:"no_lang";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:19:"field_mapping[$row]";}s:1:"D";a:2:{s:4:"type";s:4:"text";s:4:"name";s:22:"field_conversion[$row]";}}}s:4:"rows";i:2;s:4:"cols";i:4;s:4:"size";s:10:",,,,,,auto";s:7:"options";a:1:{i:6;s:4:"auto";}}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1268236373',);
$templ_data[] = array('name' => 'importexport.wizard_basic_import_csv.sample_file','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"name";s:3:"msg";s:7:"no_lang";s:1:"1";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:4:"file";s:4:"name";s:4:"file";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1268236654',);
$templ_data[] = array('name' => 'importexport.wizard_chooseallowedusers','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:13:"allowed_users";s:4:"size";s:8:"5,groups";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1146312041',);
$templ_data[] = array('name' => 'importexport.wizard_chooseapp','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:11:"application";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1145976439',);
$templ_data[] = array('name' => 'importexport.wizard_choosename','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:2:{s:4:"type";s:4:"text";s:4:"name";s:4:"name";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1146317310',);
$templ_data[] = array('name' => 'importexport.wizard_chooseplugin','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:6:"plugin";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1145976573',);
$templ_data[] = array('name' => 'importexport.wizard_close','template' => '','lang' => '','group' => '0','version' => '0.0.1','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}}s:4:"rows";i:1;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1146648383',);

View File

@ -0,0 +1,235 @@
<?php
$export_data = array('metainfo' => array(
'type' => 'importexport definitions',
'charset' => 'utf-8',
'entries' => 5,
));
$export_data['outlook_csv_german']= array(
'name' => 'outlook_csv_german',
'application' => 'addressbook',
'plugin' => 'export_contacts_csv',
'type' => 'export',
'allowed_users' => -1,
'owner' => 0,
'description' => 'Exportiert ausgewählte Kontakte zur Datenübernahme in die deutsche Version von MS Outlook',
'mapping' => array(
'n_prefix' => 'Anrede',
'n_given' => 'Vorname',
'n_middle' => 'Weitere Vornamen',
'n_family' => 'Nachname',
'n_suffix' => 'Suffix',
'org_name' => 'Firma',
'org_unit' => 'Abteilung',
'title' => 'Position',
'adr_one_street' => 'Straße geschäftlich',
'address2' => 'Straße geschäftlich 2',
'address3' => 'Straße geschäftlich 3',
'adr_one_locality' => 'Ort geschäftlich',
'adr_one_region' => 'Region geschäftlich',
'adr_one_postalcode' => 'Postleitzahl geschäftlich',
'adr_one_countryname' => 'Land geschäftlich',
'adr_two_street' => 'Straße privat',
'adr_two_locality' => 'Ort privat',
'adr_two_region' => 'Region privat',
'adr_two_postalcode' => 'Postleitzahl privat',
'adr_two_countryname' => 'Land privat',
'tel_fax' => 'Fax geschäftlich',
'tel_work' => 'Telefon geschäftlich',
'tel_msg' => 'Telefon Assistent',
'tel_car' => 'Autotelefon',
'tel_isdn' => 'ISDN',
'tel_home' => 'Telefon privat',
'tel_cell' => 'Mobiltelefon',
'tel_pager' => 'Pager',
'ophone' => 'Telefon geschäftlich 2',
'bday' => 'Geburtstag',
'email' => 'E-Mail-Adresse',
'email_home' => 'E-Mail 2: Adresse',
'url' => 'Webseite',
'note' => 'Notizen'
)
);
$export_data['outlook_csv_english']= array(
'name' => 'outlook_csv_english',
'application' => 'addressbook',
'plugin' => 'export_contacts_csv',
'type' => 'export',
'allowed_users' => -1,
'owner' => 0,
'description' => 'Exports selected contacts for english version of MS Outlook',
'mapping' => array(
'n_prefix' => 'Title',
'n_given' => 'First Name',
'n_middle' => 'Middle Name',
'n_family' => 'Last Name',
'n_suffix' => 'Suffix',
'org_name' => 'Company',
'org_unit' => 'Department',
'title' => 'Job Title',
'adr_one_street' => 'Business Street',
'address2' => 'Business Street 2',
'address3' => 'Business Street 3',
'adr_one_locality' => 'Business City',
'adr_one_region' => 'Business State',
'adr_one_postalcode' => 'Business Postal Code',
'adr_one_countryname' => 'Business Country',
'adr_two_street' => 'Home Street',
'adr_two_locality' => 'Home City',
'adr_two_region' => 'Home State',
'adr_two_postalcode' => 'Home Postal Code',
'adr_two_countryname' => 'Home Country',
'tel_fax' => 'Business Fax',
'tel_work' => 'Business Phone',
'tel_msg' => "Assistant's Phone",
'tel_car' => 'Car Phone',
'tel_isdn' => 'ISDN',
'tel_home' => 'Home Phone',
'tel_cell' => 'Mobile Phone',
'tel_pager' => 'Pager',
'ophone' => 'Business Phone 2',
'bday' => 'Birthday',
'email' => 'E-mail Address',
'email_home' => 'E-mail Address 2',
'url' => 'Web Page',
'note' => 'Notes'
)
);
$export_data['outlook_csv_italian']= array(
'name' => 'outlook_csv_italien',
'application' => 'addressbook',
'plugin' => 'export_contacts_csv',
'type' => 'export',
'allowed_users' => -1,
'owner' => 0,
'description' => 'i like pizza !',
'mapping' => array(
'title' => 'Posizione',
'n_prefix' => 'Titolo',
'n_given' => 'Nome',
'n_middle' => 'Secondo nome',
'n_family' => 'Cognome',
'n_suffix' => 'Titolo straniero',
'org_name' => 'Società',
'org_unit' => 'Reparto',
'adr_one_street' => 'Via (uff.)',
'address2' => 'Via (uff.) 2',
'address3' => 'Via (uff.) 3',
'adr_one_locality' => 'Città (uff.)',
'adr_one_region' => 'Provincia (uff.)',
'adr_one_postalcode' => 'CAP (uff.)',
'adr_one_countryname' => 'Paese (uff.)',
'adr_two_street' => 'Via (ab.)',
'adr_two_locality' => 'Città (ab.)',
'adr_two_region' => 'Provincia (ab.)',
'adr_two_postalcode' => 'CAP (ab.)',
'adr_two_countryname' => 'Paese (ab.)',
'tel_fax' => 'Fax (uff.)',
'tel_work' => 'Ufficio',
'tel_msg' => 'Telefono assistente',
'tel_car' => 'Telefono auto',
'tel_isdn' => 'ISDN',
'tel_home' => 'Abitazione',
'tel_cell' => 'Cellulare',
'tel_pager' => 'Pager',
'ophone' => 'Business Phone 2',
'bday' => 'Compleanno',
'email' => 'Indirizzo posta elettronica',
'email_home' => 'Indirizzo posta elettronica 2',
'url' => 'Pagina Web',
'note' => 'Notes'
)
);
$export_data['outlook_csv_finish']= array(
'name' => 'outlook_csv_finish',
'application' => 'addressbook',
'plugin' => 'export_contacts_csv',
'type' => 'export',
'allowed_users' => -1,
'owner' => 0,
'description' => 'test',
'mapping' => array(
'title' => 'Tehtävänimike',
'n_given' => 'Etunimi',
'n_middle' => 'Toinen nimi',
'n_family' => 'Sukunimi',
'n_suffix' => 'Jälkiliite',
'org_name' => 'Yritys',
'org_unit' => 'Osasto',
'adr_one_street' => 'Lähiosoite (työ)',
'Business Street 2' => 'Lähiosoite (työ) 2',
'Business Street 3' => 'Lähiosoite (työ) 3',
'Business City' => 'Postitoimipaikka (työ)',
'Business State' => 'Sijaintitiedot (työ)',
'Business Postal Code' => 'Postinumero (työ)',
'Business Country' => 'Maa (työ)',
'Home Street' => 'Lähiosoite (koti)',
'Home City' => 'Postitoimipaikka (koti)',
'Home State' => 'Sijaintitiedot (koti)',
'Home Postal Code' => 'Postinumero (koti)',
'Home Country' => 'Maa (koti)',
'Business Fax' => 'Työfaksi',
'Business Phone' => 'Työpuhelin',
"Assistant's Phone" => 'Avustajan puhelinnumero',
'Car Phone' => 'Autopuhelin',
'ISDN' => 'ISDN',
'Home Phone' => 'Kotipuhelin',
'Mobile Phone' => 'Matkapuhelin',
'Pager' => 'Hakulaite',
'Business Phone 2' => 'Työpuhelin 2',
'Birthday' => 'Syntymäpäivä',
'E-mail Address' => 'Sähköpostiosoite',
'E-mail Address 2' => 'Säköpostiosoite 2',// Note! Typo error in Finnish Outlook 2003 export addressbook to csv-file!
'Web Page' => 'Web-sivu',
'Notes' => 'Muistilaput'
)
);
$export_data['outlook_csv_french']= array(
'name' => 'outlook_csv_french',
'application' => 'addressbook',
'plugin' => 'export_contacts_csv',
'type' => 'export',
'allowed_users' => -1,
'owner' => 0,
'description' => 'Viva la France!',
'mapping' => array(
'title' => 'Fonction',
'n_given' => 'Prénom',
'n_middle' => 'Deuxième prénom',
'n_family' => 'Nom',
'n_suffix' => 'Suffixe',
'org_name' => 'Société',
'org_unit' => 'Service',
'adr_one_street' => 'Rue (bureau)',
'address2' => 'Rue (bureau) 2',
'address3' => 'Rue (bureau) 3',
'adr_one_locality' => 'Ville (bureau)',
'adr_one_region' => 'État/Prov (bureau)',
'adr_one_postalcode' => 'Code postal (bureau)',
'adr_one_countryname' => 'Pays (bureau)',
'adr_two_street' => 'Rue (domicile)',
'adr_two_locality' => 'Ville (domicile)',
'adr_two_region' => 'État/Prov (domicile)',
'adr_two_postalcode' => 'Code postal (domicile)',
'adr_two_countryname' => 'Pays (domicile)',
'tel_fax' => 'Télécopie (bureau)',
'tel_work' => 'Téléphone (bureau)',
'tel_msg' => "Téléphone de l'assistant(e)",
'tel_car' => 'Téléphone (voiture)',
'tel_isdn' => 'RNIS',
'tel_home' => 'Téléphone (domicile)',
'tel_cell' => 'Tél. mobile',
'tel_pager' => 'Récepteur de radiomessagerie',
'ophone' => 'Téléphone 2 (bureau)',
'bday' => 'Anniversaire',
'email' => 'Adresse e-mail',
'email_home' => 'Adresse e-mail 2',
'url' => 'Page Web',
'note' => 'Notes'
)
);
echo serialize($export_data);

View File

@ -0,0 +1,49 @@
<?php
/**
* EGroupware - importexport
*
* @link www.egroupware.org
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @author Cornelius Weiss <nelius@cwtech.de>
* @version $Id$
*/
$setup_info['importexport']['name'] = 'importexport';
$setup_info['importexport']['version'] = '1.8';
$setup_info['importexport']['app_order'] = 2;
$setup_info['importexport']['enable'] = 2;
$setup_info['importexport']['tables'] = array('egw_importexport_definitions');
$setup_info['importexport']['author'] = 'Cornelius Weiss';
$setup_info['importexport']['maintainer'] = array(
'name' => 'eGroupware core team',
'email' => 'egroupware-developers@lists.sf.net'
);
$setup_info['importexport']['license'] = 'GPL';
$setup_info['importexport']['description'] =
'';
$setup_info['importexport']['note'] =
'';
/* The hooks this app includes, needed for hooks registration */
$setup_info['importexport']['hooks']['preferences'] =
$setup_info['importexport']['hooks']['admin'] =
$setup_info['importexport']['hooks']['sidebox_menu'] = 'importexport_admin_prefs_sidebox_hooks::all_hooks';
/* Dependencies for this app to work */
$setup_info['importexport']['depends'][] = array(
'appname' => 'phpgwapi',
'versions' => Array('1.7','1.8','1.9')
);
$setup_info['importexport']['depends'][] = array(
'appname' => 'etemplate',
'versions' => Array('1.7','1.8','1.9')
);
// installation checks for importexport
$setup_info['importexport']['check_install'] = array(
'dom' => array(
'func' => 'extension_check',
),
);

View File

@ -0,0 +1,34 @@
<?php
/**************************************************************************\
* eGroupWare - Setup *
* http://www.eGroupWare.org *
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de *
* -------------------------------------------- *
* 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$ */
$phpgw_baseline = array(
'egw_importexport_definitions' => array(
'fd' => array(
'definition_id' => array('type' => 'auto'),
'name' => array('type' => 'varchar','precision' => '255'),
'application' => array('type' => 'varchar','precision' => '50'),
'plugin' => array('type' => 'varchar','precision' => '100'),
'type' => array('type' => 'varchar','precision' => '20'),
'allowed_users' => array('type' => 'varchar','precision' => '255'),
'plugin_options' => array('type' => 'longtext'),
'owner' => array('type' => 'int','precision' => '20'),
'description' => array('type' => 'varchar','precision' => '255')
),
'pk' => array('definition_id'),
'fk' => array(),
'ix' => array('name'),
'uc' => array('name')
)
);

View File

@ -0,0 +1,43 @@
<?php
/**
* EGroupware - Setup
*
* @link http://www.egroupware.org
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package importexport
* @subpackage setup
* @version $Id: class.db_tools.inc.php 21408 2006-04-21 10:31:06Z nelius_weiss $
*/
function importexport_upgrade0_002()
{
$GLOBALS['egw_setup']->oProc->AddColumn('egw_importexport_definitions','description',array(
'type' => 'varchar',
'precision' => '255'
));
return $GLOBALS['setup_info']['importexport']['currentver'] = '0.003';
}
function importexport_upgrade0_003()
{
return $GLOBALS['setup_info']['importexport']['currentver'] = '1.4';
}
function importexport_upgrade1_4()
{
$sql = 'UPDATE egw_importexport_definitions SET plugin = CONCAT(application, "_", plugin)';
$GLOBALS['egw_setup']->db->query($sql, __LINE__, __FILE__);
return $GLOBALS['setup_info']['importexport']['currentver'] = '1.7.001';
}
function importexport_upgrade1_7_001()
{
return $GLOBALS['setup_info']['importexport']['currentver'] = '1.8';
}

View File

@ -0,0 +1,169 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<overlay>
<template id="importexport.export_dialog.general_tab_content" template="" lang="" group="0" version="">
<grid height="200px">
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<description span="all" value="some nice text"/>
</row>
<row class="select_appname">
<description value="Select application"/>
<menulist>
<menupopup no_lang="1" id="appname" onchange="xajax_doXMLHTTP('importexport.uiexport.ajax_get_plugins',this.value);"/>
</menulist>
</row>
<row class="select_plugin">
<description value="Select format"/>
<menulist>
<menupopup no_lang="1" id="plugin" onchange="xajax_doXMLHTTP('importexport.uiexport.ajax_get_plugin_options',this.value);"/>
</menulist>
</row>
<row>
<box span="all" id="plugin_description" needed="1">
<description span="all" needed="1" id="plugin_description" no_lang="1"/>
</box>
</row>
</rows>
</grid>
</template>
<template id="importexport.export_dialog.general_tab" template="" lang="" group="0" version="">
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row valign="top">
<image src="export"/>
<template id="importexport.export_dialog.general_tab_content"/>
</row>
</rows>
</grid>
</template>
<template id="importexport.export_dialog.selection_tab" template="" lang="" group="0" version="">
<grid height="200px">
<columns>
<column/>
</columns>
<rows>
<row valign="top">
<html id="plugin_selectors_html" no_lang="1"/>
</row>
</rows>
</grid>
</template>
<template id="importexport.export_dialog.options_tab" template="" lang="" group="0" version="">
<grid height="200px">
<columns>
<column/>
</columns>
<rows>
<row valign="top">
<html id="plugin_options_html" no_lang="1"/>
</row>
</rows>
</grid>
</template>
<template id="importexport.export_dialog.templates_tab" template="" lang="" group="0" version="">
<grid>
<columns>
<column/>
</columns>
<rows>
<row>
<description value="Select a template"/>
</row>
<row>
<listbox no_lang="1" id="templates" rows="5"/>
</row>
<row>
<description value="Description"/>
</row>
<row>
<description id="description"/>
</row>
<row>
<button label="Load" id="load"/>
</row>
</rows>
</grid>
</template>
<template id="importexport.export_dialog" template="" lang="" group="0" version="">
<grid width="100%">
<columns>
<column/>
</columns>
<rows>
<row>
<description id="msg"/>
</row>
<row>
<tabbox>
<tabs>
<tab label="General" statustext=""/>
<tab label="Selection" statustext=""/>
<tab label="Options" statustext=""/>
<tab label="Templates" statustext=""/>
</tabs>
<tabpanels>
<template id="importexport.export_dialog.general_tab"/>
<template id="importexport.export_dialog.selection_tab"/>
<template id="importexport.export_dialog.options_tab"/>
<template id="importexport.export_dialog.templates_tab"/>
</tabpanels>
</tabbox>
</row>
<row>
<checkbox label="Save as template" id="save_as_template"/>
</row>
<row>
<hbox span="all">
<hbox>
<button label="Export" id="export" onclick="xajax_eT_wrapper(this);return false;"/>
<button label="Preview" id="preview" onclick="xajax_eT_wrapper(this);return false;"/>
</hbox>
<button label="Cancel" align="right" id="cancel" onclick="window.close(); return false;"/>
</hbox>
</row>
<row>
<box id="preview-box" needed="1" class="preview-box">
<description/>
</box>
</row>
<row>
<box class="preview-box-buttons" id="preview-box-buttons" needed="1" align="center">
<button label="OK" align="center" onclick="document.getElementById('divPoweredBy').style.display='block'; document.getElementById(form::name('preview-box')).style.display='none'; document.getElementById(form::name('preview-box-buttons')).style.display='none'; return false;"/>
</box>
</row>
</rows>
</grid>
<styles>
.preview-box {
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 360px;
overflow: scroll;
background-color: white;
z-index: 999;
display: none;
}
.preview-box-buttons {
position: absolute;
top: 365px;
left: 0px;
width: 400px;
height: 20px;
z-index: 999;
display: none;
}
</styles>
</template>
</overlay>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB