egroupware_official/importexport/inc/class.basic_import_csv.inc.php
Nathan Gray 54b4454d51 Add some base classes to make it easier for other applications to implement importing CSVs
To use them, you need to create two files in the app/importexport directory, 'class.import_appname_csv.inc.php' and 'class.wizzard_import_appname_csv.inc.php'.
The minimum required files are shown below, but they can be modified as needed to override the basics and add capabilities.


class.import_appname_csv.inc.php:
<?php

        require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.basic_import_csv.inc.php');

        class import_appname_csv extends basic_import_csv {

                protected function import_record(&$record, &$import_csv) {
			// Handle one record here.  Handle conditions and call action() as appropriate.
			// See basic_import_csv.
                }

                protected function action($action, Array $record, $record_num = 0) {
			// Take the given action (none, insert, delete, update) etc.  as understood for your app.
			// See basic_import_csv.
                }
        }
?>

class.wizzard_import_appname_csv.inc.php:
<?php

        require_once(EGW_INCLUDE_ROOT . '/appname/importexport/class.import_appname_csv.inc.php');
        require_once(EGW_INCLUDE_ROOT . '/importexport/inc/class.wizzard_basic_import_csv.inc.php');

        class wizzard_import_appname_csv extends wizzard_basic_import_csv {
		public function __construct() {
			$this->mapping_fields = array(
				// List of destination fields available in appname
				'field' => lang('name')
			);
			$this->conditions = array(
				// List of conditions supported by import_appname_csv
				'field' => lang('name')
			);
			$this->actions = array(
				// List of actions supported by import_appname_csv
				'field' => lang('name')
			);
		}
        }
?>
2010-03-10 16:31:25 +00:00

283 lines
7.8 KiB
PHP

<?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
*/
require_once(EGW_INCLUDE_ROOT. '/importexport/inc/class.iface_import_plugin.inc.php');
require_once(EGW_INCLUDE_ROOT.'/importexport/inc/class.import_csv.inc.php');
/**
* 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.
*
* NB: The name of your import plugin must start with import_.
*/
abstract class basic_import_csv implements 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, definition $_definition ) {
$import_csv = new 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
?>