diff --git a/importexport/doc/README.developers b/importexport/doc/README_developers.txt similarity index 53% rename from importexport/doc/README.developers rename to importexport/doc/README_developers.txt index 34f88d32ff..f5cb7e14a6 100644 --- a/importexport/doc/README.developers +++ b/importexport/doc/README_developers.txt @@ -1,25 +1,47 @@ -=importexport= += 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. +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_ or -class.export_ +class.import_ or +class.export_ in -EGW_INCLUDE_ROOT/YourApp/inc/ +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 +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=&have_selection=<{true|false}>" diff --git a/importexport/importexport_cli.php b/importexport/importexport_cli.php index c8451adf6b..2264e842d7 100755 --- a/importexport/importexport_cli.php +++ b/importexport/importexport_cli.php @@ -15,12 +15,12 @@ $usage = "usage: --definition --file + --charset --user --password --domain \n"; - if (php_sapi_name() != 'cli') - { + if (php_sapi_name() != 'cli') { die('This script only runs form command line'); } @@ -48,6 +48,7 @@ $long_opts = array( 'definition=', 'file=', + 'charset=', 'user=', 'password=', 'domain=' @@ -67,13 +68,14 @@ } $domain = 'default'; - foreach ($options[0] as $option) - { - switch ($option[0]) - { + foreach ($options[0] as $option) { + switch ($option[0]) { case '--file' : $file = $option[1]; break; + case '--charset' : + $charset = $option[1]; + break; case '--definition' : $definition = $option[1]; break; @@ -92,11 +94,14 @@ } } // check file - if (!$user || !$password) - { + if ( !$user || !$password ) { fwrite(STDERR,'importexport_cli: You have to supply a username / password'."\n".$usage); exit(INVALID_OPTION); } + if ( !$charset ) { + fwrite(STDERR,'importexport_cli: You have to supply a valid charset'."\n".$usage); + exit(INVALID_OPTION); + } $GLOBALS['egw_info']['flags'] = array( 'disable_Template_class' => True, @@ -134,7 +139,7 @@ exit(INVALID_OPTION); } - require_once('./inc/class.definition.inc.php'); + require_once('inc/class.definition.inc.php'); try { $definition = new definition($definition); } @@ -142,12 +147,14 @@ fwrite(STDERR,"importexport_cli: ". $e->getMessage(). "\n"); exit(INVALID_OPTION); } - - require_once("$path_to_egroupware/$definition->application/inc/class.$definition->plugin.inc.php"); + + require_once("$path_to_egroupware/$definition->application/importexport/class.$definition->plugin.inc.php"); $po = new $definition->plugin; $type = $definition->type; - $po->$type($definition,array('file' => $file)); + $resource = fopen( $file, 'r' ); + $po->$type( $resource, $charset, $definition ); + $GLOBALS['egw']->common->phpgw_exit(); function import_export_access(&$account) diff --git a/importexport/inc/class.arrayxml.inc.php b/importexport/inc/class.arrayxml.inc.php new file mode 100644 index 0000000000..97de6f4c2f --- /dev/null +++ b/importexport/inc/class.arrayxml.inc.php @@ -0,0 +1,113 @@ + + * @copyright Cornelius Weiss + * @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 arrayxml { + + /** + * converts a php array to an xml string + * + * @static + * @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 + * + * @static + * @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 = utf8_decode($nc->nodeValue) == 'FALSE' ? false : true; + break; + default : + $value = utf8_decode($nc->nodeValue); + } + $xml_array[$name] = $value; + } + } + + return $xml_array; + } +} +?> \ No newline at end of file diff --git a/importexport/inc/class.bodefinitions.inc.php b/importexport/inc/class.bodefinitions.inc.php index b2df98e3a1..1aea53a901 100644 --- a/importexport/inc/class.bodefinitions.inc.php +++ b/importexport/inc/class.bodefinitions.inc.php @@ -11,6 +11,7 @@ */ require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.definition.inc.php'); +require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.arrayxml.inc.php'); require_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php'); /** bo to define {im|ex}ports @@ -41,6 +42,14 @@ class bodefinitions { } } + /** + * gets definitions as raw data. + * well, we need a god idea for egw_record pools... + * its not a god idea to make a definition object of each + * at the moment, as each defintion holds an so_sql instance. + * + * @return array + */ public function get_definitions() { return $this->definitions; } @@ -48,11 +57,11 @@ class bodefinitions { /** * reads a definition from database * + * @deprecated see class.definition.inc.php * @param mixed &$definition * @return bool success or not */ - public function read(&$definition) - { + public function read(&$definition) { if(is_int($definition)) $definition = array('definition_id' => $definition); elseif(is_string($definition)) $definition = array('name' => $definition); if(!$definition = $this->so_sql->read($definition)) return false; @@ -61,45 +70,14 @@ class bodefinitions { return true; } - public function save($content) - { - $plugin = $content['plugin']; - if (!$plugin) return false; - - $definition = array_intersect_key($content,array_flip($this->so_sql->db_cols)); - - if(is_object($this->plugin) && $this->plugin->plugin_info['plugin'] == $plugin) - { - $plugin_options = array_intersect_key($content,array_flip($this->plugin->plugin_options)); - } - else - { - // we come eg. from definition import - $file = EGW_SERVER_ROOT . SEP . $definition['application'] . SEP . 'inc' . SEP . 'importexport'. SEP . 'class.'.$definition['plugin'].'.inc.php'; - if (is_file($file)) - { - @include_once($file); - $obj = new $plugin; - $plugin_options = array_intersect_key($content,array_flip($obj->plugin_options)); - unset($obj); - } - else - { - foreach ($this->so_sql->db_cols as $col) unset($content[$col]); - $plugin_options = $content; - - } - } - $definition['plugin_options'] = serialize($plugin_options); - $this->so_sql->data = $definition; - //print_r($definition); - return $this->so_sql->save(); - } - - public function delete($keys) - { + /** + * deletes a defintion + * + * @param array $keys + */ + public function delete($keys) { $this->so_sql->delete(array('definition_id' => $keys)); - // clear private cach + // clear private cache foreach ($keys as $key) { unset($this->definitions[array_search($key,$this->definitions)]); } @@ -126,36 +104,6 @@ class bodefinitions { return in_array($this_user_id,$alluser) ? true : false; } - /** - * searches and registers plugins from all apps - * - * @deprecated see import_export_helperfunctions::get_plugins - * @return array $info info about existing plugins - */ - static public function plugins() - { - if (!key_exists('apps',$GLOBALS['egw_info'])) return false; - foreach (array_keys($GLOBALS['egw_info']['apps']) as $appname) - { - $dir = EGW_INCLUDE_ROOT . "/$appname/inc"; - if(!$d = @opendir($dir)) continue; - while (false !== ($file = readdir($d))) - { - //echo $file."\n"; - $pnparts = explode('.',$file); - if(!is_file($file = "$dir/$file") || substr($pnparts[1],0,7) != 'wizzard' || $pnparts[count($pnparts)-1] != 'php') continue; - $plugin_classname = $pnparts[1]; - include_once($file); - if (!is_object($GLOBALS['egw']->$plugin_classname)) - $GLOBALS['egw']->$plugin_classname = new $plugin_classname; - $info[$appname][$GLOBALS['egw']->$plugin_classname->plugin_info['plugin']] = $GLOBALS['egw']->$plugin_classname->plugin_info; - } - closedir($d); - } - return $info; - } - - /** * exports definitions * @@ -169,43 +117,55 @@ class bodefinitions { 'entries' => count($keys), )); - foreach ($keys as $definition_id) - { - $definition = array('definition_id' => $definition_id); - $this->read($definition); - unset($definition['definition_id']); - $export_data[$definition['name']] = $definition; + $export_data['definitions'] = array(); + foreach ($keys as $definition_id) { + $definition = new definition( $definition_id ); + $export_data['definitions'][$definition->name] = $definition->get_record_array(); + unset($export_data['definitions'][$definition->name]['definition_id']); + unset($definition); } - /* This is no fun as import -> export cycle in xmltools results in different datas :-( - $xml =& CreateObject('etemplate.xmltool','root'); - $xml->import_var('importexport.definitions', $export_data); - $xml_data = $xml->export_xml(); - we export serialised arrays in the meantime - */ - return serialize($export_data); + + $xml = new arrayxml(); + return $xml->array2xml($export_data, 'importExportDefinitions'); } - public function import($import_file) + /** + * imports definitions from file + * + * @param string $import_file + * @throws Exeption + * @return void + */ + public static function import( $_import_file ) { - // read given file and check if its a valid definition - if (!is_file($import_file['tmp_name'])) return false; - $f = fopen($import_file['tmp_name'],'r'); - $data = fread($f,100000); - fclose($f); - if (($data = unserialize($data)) === false) return false; - $metainfo = $data['metainfo']; - unset($data['metainfo']); + if ( !is_file( $_import_file ) ) { + throw new Exception("'$_import_file' is not a valid file" ); + } + + $data = arrayxml::xml2array( file_get_contents( $_import_file ) ); + + $metainfo = $data['importExportDefinitions']['metainfo']; + $definitions = $data['importExportDefinitions']['definitions']; + unset ( $data ); // convert charset into internal used charset - $data = $GLOBALS['egw']->translation->convert($data,$metainfo['charset'],$GLOBALS['egw']->translation->charset()); + $definitions = $GLOBALS['egw']->translation->convert( + $definitions, + $metainfo['charset'], + $GLOBALS['egw']->translation->charset() + ); // save definition(s) into internal table - foreach ($data as $name => $definition) + foreach ( $definitions as $name => $definition_data ) { - $this->save($definition); + $definition = new definition( $definition_data['name'] ); + $definition_id = $definition->get_identifier() ? $definition->get_identifier() : NULL; + + $definition->set_record( $definition_data ); + $definition->save( $definition_id ); } } - + } diff --git a/importexport/inc/class.definition.inc.php b/importexport/inc/class.definition.inc.php index 698801718f..3a4820dcd8 100644 --- a/importexport/inc/class.definition.inc.php +++ b/importexport/inc/class.definition.inc.php @@ -33,7 +33,7 @@ class definition implements iface_egw_record { 'plugin' => 'string', 'type' => 'string', 'allowed_users' => 'array', - 'options' => 'array', + 'plugin_options' => 'array', 'owner' => 'int', 'description' => 'string', ); @@ -80,15 +80,13 @@ class definition implements iface_egw_record { if (is_string($_identifier) && strlen($_identifier) > 3) $_identifier = $this->name2identifier($_identifier); if ((int)$_identifier != 0) { - $this->so_sql->read(array('definition_id' => $_identifier)); - if (empty($this->so_sql->data)) { + $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->get_owner() == $this->user || $this->is_admin)) { + 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.'"!'); - $this->definition = $this->so_sql->data; } - $this->definition = $this->so_sql->data; } } @@ -98,7 +96,7 @@ class definition implements iface_egw_record { * @param string $_name * @return int */ - private function name2identifier($_name) { + 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'); @@ -113,7 +111,7 @@ class definition implements iface_egw_record { switch ($_attribute_name) { case 'allowed_users' : return $this->get_allowed_users(); - case 'options' : + case 'plugin_options' : return $this->get_options(); default : return $this->definition[$_attribute_name]; @@ -127,7 +125,7 @@ class definition implements iface_egw_record { switch ($_attribute_name) { case 'allowed_users' : return $this->set_allowed_users($_data); - case 'options' : + case 'plugin_options' : return $this->set_options($_data); default : $this->definition[$_attribute_name] = $_data; @@ -149,7 +147,7 @@ class definition implements iface_egw_record { * * @param array $_allowed_users */ - private function set_allowed_users($_allowed_users) { + private function set_allowed_users( $_allowed_users ) { $this->definition['allowed_users'] = implode(',',(array)$_allowed_users); } @@ -159,12 +157,7 @@ class definition implements iface_egw_record { * @return array */ private function get_options() { - // oh compat funct to be removed! - if(array_key_exists('plugin_options',$this->definition)) { - $this->definition['options'] = $this->definition['plugin_options']; - unset($this->definition['plugin_options']); - } - return unserialize($this->definition['options']); + return unserialize($this->definition['plugin_options']); } /** @@ -172,8 +165,8 @@ class definition implements iface_egw_record { * * @param array $options */ - private function set_options(array $_options) { - $this->definition['options'] = serialize($_options); + private function set_options(array $_plugin_options) { + $this->definition['plugin_options'] = serialize( $_plugin_options ); } /** @@ -187,7 +180,7 @@ class definition implements iface_egw_record { public function get_record_array() { $definition = $this->definition; $definition['allowed_users'] = $this->get_allowed_users(); - $definition['options'] = $this->get_options(); + $definition['plugin_options'] = $this->get_options(); return $definition; } @@ -205,8 +198,20 @@ class definition implements iface_egw_record { * * @return void */ - public function set_record(array $_record) { - $this->definition = $_record; + 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; + } + } + + // convert plugin_options into internal representation + $this->set_allowed_users($this->definition['allowed_users']); + $this->set_options($this->definition['plugin_options']); } /** @@ -225,11 +230,13 @@ class definition implements iface_egw_record { * @return string identifier */ public function save ( $_dst_identifier ) { - if ($owner = $this->get_owner() && $owner != $this->user && !$this->is_admin) { - throw ('Error: User '. $this->user. ' is not allowed to save this definition!'); + if ( strlen($this->definition['name']) < 3 ) { + throw new Exception('Error: Can\'t save definition, no valid name given!'); } - if ($this->so_sql->save($_dst_identifier)) { - throw('Error: so_sql was not able to save definition: '.$this->get_identifier()); + + $this->so_sql->data = $this->definition; + 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']; } diff --git a/importexport/inc/class.iface_export_plugin.inc.php b/importexport/inc/class.iface_export_plugin.inc.php index ef0507b4b2..667f059cf9 100644 --- a/importexport/inc/class.iface_export_plugin.inc.php +++ b/importexport/inc/class.iface_export_plugin.inc.php @@ -10,14 +10,12 @@ * @version $Id$ */ -//require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.iface_egw_record.inc.php'); - /** * class 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/class.export_.inc.php + * EGW_INCLUDE_ROOT/appname/inc/importexport/class.export_.inc.php * to attend the importexport framwork with your export. * * NOTE: This is an easy interface, cause plugins live in theire own diff --git a/importexport/inc/class.iface_import_plugin.inc.php b/importexport/inc/class.iface_import_plugin.inc.php new file mode 100644 index 0000000000..553ba6199b --- /dev/null +++ b/importexport/inc/class.iface_import_plugin.inc.php @@ -0,0 +1,79 @@ + + * @copyright Cornelius Weiss + * @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_.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 iface_import_plugin { + + /** + * imports entries according to given definition object. + * + * @param definition $_definition + */ + public function import($_stream, $_charset, 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(); + +} // end of iface_export_plugin +?> diff --git a/importexport/inc/class.import_csv.inc.php b/importexport/inc/class.import_csv.inc.php index f8d380526a..bc75912eb9 100755 --- a/importexport/inc/class.import_csv.inc.php +++ b/importexport/inc/class.import_csv.inc.php @@ -24,16 +24,10 @@ class import_csv implements iface_import_record { //, Iterator { const csv_max_linelength = 8000; - /** Aggregations: */ - - /** Compositions: */ - /** * @static import_export_helper_functions */ - /*** Attributes: ***/ - /** * array with field mapping in form column number => new_field_name * @access public @@ -235,7 +229,7 @@ class import_csv implements iface_import_record { //, Iterator { foreach ($this->mapping as $cvs_idx => $new_idx) { $this->record[$new_idx] = $record[$cvs_idx]; } - return; + return true; } // end of member function do_fieldmapping /** diff --git a/importexport/inc/class.import_export_helper_functions.inc.php b/importexport/inc/class.import_export_helper_functions.inc.php index 638413975e..f9d3e51af8 100755 --- a/importexport/inc/class.import_export_helper_functions.inc.php +++ b/importexport/inc/class.import_export_helper_functions.inc.php @@ -16,14 +16,7 @@ * class import_export_helper_functions (only static methods) * use import_export_helper_functions::method */ -class import_export_helper_functions -{ - - /** Aggregations: */ - - /** Compositions: */ - - /*** Attributes: ***/ +class import_export_helper_functions { /** * nothing to construct here, only static functions! @@ -236,13 +229,13 @@ class import_export_helper_functions * @param string $_appname { | all} * @return array( => array( => array( => ))) */ - public static function get_plugins($_appname, $_type){ + public static function get_plugins( $_appname = 'all', $_type = 'all' ) { $appnames = $_appname == 'all' ? array_keys($GLOBALS['egw_info']['apps']) : (array)$_appname; - $types = $_types == 'all' ? array('import','export') : (array)$_type; + $types = $_type == 'all' ? array('import','export') : (array)$_type; $plugins = array(); foreach ($appnames as $appname) { - $appdir = EGW_INCLUDE_ROOT. "/$appname/inc"; + $appdir = EGW_INCLUDE_ROOT. "/$appname/importexport"; if(!is_dir($appdir)) continue; $d = dir($appdir); @@ -250,9 +243,9 @@ class import_export_helper_functions while (false !== ($entry = $d->read())) { list( ,$classname, ,$extension) = explode('.',$entry); $file = $appdir. '/'. $entry; - + foreach ($types as $type) { - if(!is_file($file) || substr($classname,0,7) != $type.'_' || $extension != 'php') continue; + if( !is_file($file) || substr($classname,0,7) != $type.'_' || $extension != 'php' ) continue; require_once($file); try { @@ -269,6 +262,7 @@ class import_export_helper_functions } $d->close(); } + //error_log(__CLASS__.__FUNCTION__.print_r($plugins,true)); return $plugins; } @@ -282,5 +276,8 @@ class import_export_helper_functions return array_keys(self::get_plugins('all',$_type)); } + public static function guess_filetype( $_file ) { + + } } // end of import_export_helper_functions ?> diff --git a/importexport/inc/class.uidefinitions.inc.php b/importexport/inc/class.uidefinitions.inc.php index 7eff2dbcd9..2a4e217bfd 100644 --- a/importexport/inc/class.uidefinitions.inc.php +++ b/importexport/inc/class.uidefinitions.inc.php @@ -13,11 +13,6 @@ require_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.uietemplate.inc.php'); require_once('class.bodefinitions.inc.php'); -if (!defined('IMPORTEXPORT_APP')) -{ - define('IMPORTEXPORT_APP','importexport'); -} - /** * Userinterface to define {im|ex}ports * @@ -27,6 +22,8 @@ class uidefinitions { const _debug = true; + const _appname = 'importexport'; + public $public_functions = array( 'edit' => true, 'index' => true, @@ -59,8 +56,8 @@ class uidefinitions { // 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(IMPORTEXPORT_APP); - $GLOBALS['egw_info']['flags']['currentapp'] = IMPORTEXPORT_APP; + $GLOBALS['egw']->translation->add_app(self::_appname); + $GLOBALS['egw_info']['flags']['currentapp'] = self::_appname; $GLOBALS['egw_info']['flags']['include_xajax'] = true; if(!@is_object($GLOBALS['egw']->js)) @@ -68,7 +65,7 @@ class uidefinitions $GLOBALS['egw']->js =& CreateObject('phpgwapi.javascript'); } $this->etpl =& new etemplate(); - $this->clock = $GLOBALS['egw']->html->image(IMPORTEXPORT_APP,'clock'); + $this->clock = $GLOBALS['egw']->html->image(self::_appname,'clock'); $this->steps = array( 'wizzard_step10' => lang('Choose an application'), 'wizzard_step20' => lang('Choose a plugin'), @@ -77,7 +74,7 @@ class uidefinitions 'wizzard_finish' => '', ); //register plugins (depricated) - $this->plugins = bodefinitions::plugins(); + //$this->plugins = bodefinitions::plugins(); } /** @@ -107,7 +104,7 @@ class uidefinitions 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'; + $name = 'importexport_definition.xml'; header('Content-Type: ' . $mime_type); header('Content-Disposition: attachment; filename="'.$name.'"'); echo $bodefinitions->export($selected); @@ -120,7 +117,7 @@ class uidefinitions } } - $etpl =& new etemplate(IMPORTEXPORT_APP.'.definition_index'); + $etpl =& new etemplate(self::_appname.'.definition_index'); // we need an offset because of autocontinued rows in etemplate ... $definitions = array('row0'); @@ -131,7 +128,7 @@ class uidefinitions unset($definition); } $content = $definitions; - return $etpl->exec(IMPORTEXPORT_APP.'.uidefinitions.index',$content,array(),$readonlys,$preserv); + return $etpl->exec(self::_appname.'.uidefinitions.index',$content,array(),$readonlys,$preserv); } function edit() @@ -203,7 +200,7 @@ class uidefinitions $this->wizzard_content_template = $this->$next_step($content,$sel_options,$readonlys,$preserv); } - $html = $this->etpl->exec(IMPORTEXPORT_APP.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); + $html = $this->etpl->exec(self::_appname.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); } else { @@ -216,7 +213,7 @@ class uidefinitions unset ($content['edit']); $this->wizzard_content_template = $this->wizzard_step10($content, $sel_options, $readonlys, $preserv); - $html = $this->etpl->exec(IMPORTEXPORT_APP.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); + $html = $this->etpl->exec(self::_appname.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); } if(class_exists('xajaxResponse')) @@ -254,7 +251,7 @@ class uidefinitions if ($GLOBALS['egw_info']['user']['apps']['manual']) { $manual =& new etemplate('etemplate.popup.manual'); - echo $manual->exec(IMPORTEXPORT_APP.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); + echo $manual->exec(self::_appname.'.uidefinitions.wizzard',$content,$sel_options,$readonlys,$preserv,1); unset($manual); } @@ -448,14 +445,14 @@ class uidefinitions $bodefinitions = new bodefinitions(); if (is_array($content)) { - $bodefinitions->import($content['import_file']); + $bodefinitions->import($content['import_file']['tmp_name']); // TODO make redirect here! return $this->index(); } else { - $etpl =& new etemplate(IMPORTEXPORT_APP.'.import_definition'); - return $etpl->exec(IMPORTEXPORT_APP.'.uidefinitions.import_definition',$content,array(),$readonlys,$preserv); + $etpl =& new etemplate(self::_appname.'.import_definition'); + return $etpl->exec(self::_appname.'.uidefinitions.import_definition',$content,array(),$readonlys,$preserv); } } } diff --git a/importexport/inc/class.uiexport.inc.php b/importexport/inc/class.uiexport.inc.php index 56224c8428..8465f55273 100644 --- a/importexport/inc/class.uiexport.inc.php +++ b/importexport/inc/class.uiexport.inc.php @@ -57,10 +57,11 @@ class uiexport { if(empty($_content)) { $et = new etemplate(self::_appname. '.export_dialog'); $_appname = $_GET['appname']; - $_definition =$_GET['definition']; + $_definition =$_GET['definition'] = 'expert'; $_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; @@ -84,7 +85,7 @@ class uiexport { unset($definitions); $sel_options['definition']['expert'] = lang('Expert options'); - if(isset($_definition) && array_key_exists($_definition,$sel_options[$_definition])) { + if(isset($_definition) && array_key_exists($_definition,$sel_options)) { $content['definition'] = $_definition; } else { @@ -101,6 +102,7 @@ class uiexport { if(isset($_plugin) && array_key_exists($_plugin,$sel_options['plugin'])) { $content['plugin'] = $_plugin; $selected_plugin = $_plugin; + error_log('hallo'); } else { $plugins_classnames = array_keys($plugins); @@ -181,19 +183,19 @@ class uiexport { $definition = new definition($_content['definition']); } - if (isset($definition->options['selection'])) { - //$definition->options = parse(...) + if (isset($definition->plugin_options['selection'])) { + //$definition->plugin_options = parse(...) } else { - $definition->options = array_merge( - $definition->options, + $definition->plugin_options = array_merge( + $definition->plugin_options, array('selection' => $_content['selection']) ); } $tmpfname = tempnam('/tmp','export'); $file = fopen($tmpfname, "w+"); - if (! $charset = $definition->options['charset']) { + if (! $charset = $definition->plugin_options['charset']) { $charset = $GLOBALS['egw']->translation->charset(); } $plugin_object = new $definition->plugin; @@ -234,6 +236,7 @@ class uiexport { //nothing else expected! throw new Exception('Error: unexpected submit in export_dialog!'); } + //error_log(print_r($content,true)); return $et->exec(self::_appname. '.uiexport.export_dialog',$content,$sel_options,$readonlys,$preserv,2); } diff --git a/importexport/setup/default_records.inc.php b/importexport/setup/default_records.inc.php index 2247705bee..be7c97be9e 100644 --- a/importexport/setup/default_records.inc.php +++ b/importexport/setup/default_records.inc.php @@ -1,53 +1,31 @@ <?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$ - */ +/** + * 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$ + */ - $definition_table = 'egw_importexport_definitions'; +require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.bodefinitions.inc.php'); + +// apps, whose definitions should be installed automatically +$appnames = array ( + 'addressbook', +); + +foreach ($appnames as $appname) { + $defdir = EGW_INCLUDE_ROOT. "/$appname/importexport/definitions"; + if(!is_dir($defdir)) continue; + $d = dir($defdir); - // Add two rooms to give user an idea of what resources is... - $plugin_options = serialize(array( - 'fieldsep' => ',', - 'charset' => 'ISO-8859-1', - 'addressbook' => 'n', - 'owner' => 5, - 'field_mapping' => array( - 0 => '#kundennummer', - 1 => 'n_given', - 2 => 'n_family', - 3 => 'adr_one_street', - 4 => 'adr_one_countryname', - 5 => 'adr_one_postalcode', - 6 => 'adr_one_locality', - 7 => 'tel_work', - 8 => '', - 9 => '', - 10 => '', - 11 => '', - ), - 'field_tanslation' => array(), - 'has_header_line' => false, - 'max' => false, - 'conditions' => array( - 0 => array( - 'type' => 0, // exists - 'string' => '#kundennummer', - 'true' => array( - 'action' => 1, // update - 'last' => true, - ), - 'false' => array( - 'action' => 2, // insert - 'last' => true, - ), - - )), - )); - $oProc->query("INSERT INTO {$definition_table } (name,application,plugin,type,allowed_users,plugin_options) VALUES ( 'oelheld','addressbook','addressbook_csv_import','import','5','$plugin_options')"); - + // step through each file in appdir + while (false !== ($entry = $d->read())) { + $file = $appdir. '/'. $entry; + list( $filename, $extension) = explode('.',$entry); + if ( $extension != 'xml' ) continue; + bodefinitions::import( $file ); + } +}