forked from extern/egroupware
361 lines
11 KiB
PHP
361 lines
11 KiB
PHP
<?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$
|
|
*/
|
|
|
|
use EGroupware\Api;
|
|
|
|
/** 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 Api\Storage\Base
|
|
*/
|
|
private $so_sql;
|
|
|
|
/**
|
|
* @var array hold definitions
|
|
*/
|
|
private $definitions;
|
|
|
|
public function __construct($_query=false, $ignore_acl = false)
|
|
{
|
|
$this->so_sql = new Api\Storage\Base(self::_appname, self::_defintion_table );
|
|
if ($_query) {
|
|
$definitions = $this->so_sql->search($_query, false);
|
|
foreach ((array)$definitions as $definition) {
|
|
if(self::is_permitted($definition) || $ignore_acl) $this->definitions[] = $definition['definition_id'];
|
|
}
|
|
}
|
|
}
|
|
|
|
public function get_rows(&$query, &$rows, &$readonlys)
|
|
{
|
|
// Filter only definitions user is allowed to use
|
|
if(!$GLOBALS['egw_info']['user']['apps']['admin']) {
|
|
$this_membership = $GLOBALS['egw']->accounts->memberships($GLOBALS['egw_info']['user']['account_id'], true);
|
|
$this_membership[] = $GLOBALS['egw_info']['user']['account_id'];
|
|
$sql .= ' (';
|
|
$read = array();
|
|
foreach($this_membership as $id)
|
|
{
|
|
$read[] = 'allowed_users '.
|
|
$GLOBALS['egw']->db->capabilities['case_insensitive_like'].' '.
|
|
$GLOBALS['egw']->db->quote('%,'.str_replace('_','\\_',$id) .',%');
|
|
}
|
|
$sql .= implode(' OR ', $read);
|
|
$sql .= ') OR owner = '.$GLOBALS['egw_info']['user']['account_id'];
|
|
$query['col_filter'][] = $sql;
|
|
}
|
|
|
|
// Handle allowed filter
|
|
if($query['col_filter']['allowed_users'])
|
|
{
|
|
$allowed = array();
|
|
foreach((array)$query['col_filter']['allowed_users'] as $id)
|
|
{
|
|
$allowed[] = 'allowed_users '.
|
|
$GLOBALS['egw']->db->capabilities['case_insensitive_like'].' '.
|
|
$GLOBALS['egw']->db->quote('%,'.str_replace('_','\\_',$id) .',%');
|
|
}
|
|
if($allowed)
|
|
{
|
|
unset($query['col_filter']['allowed_users']);
|
|
$query['col_filter'][] = '('.implode(' OR ', $allowed) . ')';
|
|
}
|
|
}
|
|
|
|
$total = $this->so_sql->get_rows($query, $rows, $readonlys);
|
|
$ro_count = 0;
|
|
foreach($rows as &$row) {
|
|
// Strip off leading + trailing ,
|
|
$row['allowed_users'] = substr($row['allowed_users'],1,-1);
|
|
|
|
$readonlys["edit[{$row['definition_id']}]"] = $readonlys["delete[{$row['definition_id']}]"] =
|
|
($row['owner'] != $GLOBALS['egw_info']['user']['account_id']) &&
|
|
!$GLOBALS['egw_info']['user']['apps']['admin'];
|
|
if($readonlys["edit[{$row['definition_id']}]"])
|
|
{
|
|
$row['class'] .= 'rowNoEdit rowNoDelete';
|
|
$ro_count++;
|
|
}
|
|
$row['class'] .= ' ' . $row['type'];
|
|
}
|
|
$readonlys['delete_selected'] = $ro_count == count($rows);
|
|
return $total;
|
|
}
|
|
|
|
/**
|
|
* gets array of definition ids
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_definitions() {
|
|
return $this->definitions;
|
|
}
|
|
public function read($definition_id) {
|
|
if(is_numeric($definition_id)) {
|
|
$this->so_sql->read($definition_id);
|
|
$definition = new importexport_definition($this->so_sql->data['name']);
|
|
} else {
|
|
$definition = new importexport_definition( $definition_id['name'] );
|
|
}
|
|
return $definition->get_record_array();
|
|
}
|
|
/**
|
|
* deletes a defintion
|
|
*
|
|
* @param array $keys
|
|
*/
|
|
public function delete($keys) {
|
|
foreach ($keys as $index => $key) {
|
|
// Check for ownership
|
|
$definition = $this->read($key);
|
|
if($definition['owner'] && $definition['owner'] == $GLOBALS['egw_info']['user']['account_id'] || $GLOBALS['egw_info']['user']['apps']['admin']) {
|
|
// clear private cache
|
|
if(is_array($this->definitions))
|
|
{
|
|
unset($this->definitions[array_search($key, $this->definitions)]);
|
|
}
|
|
} else {
|
|
unset($keys[$index]);
|
|
}
|
|
}
|
|
if(count($keys) > 0) {
|
|
$this->so_sql->delete(array('definition_id' => $keys));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 = is_array($_definition['allowed_users']) ? $_definition['allowed_users'] : explode(',',$_definition['allowed_users']);
|
|
$this_user_id = $GLOBALS['egw_info']['user']['account_id'];
|
|
$this_membership = $GLOBALS['egw']->accounts->memberships($this_user_id, true);
|
|
$this_membership[] = $this_user_id;
|
|
$this_membership[] = 'all';
|
|
$alluser = array_intersect($allowed_user,$this_membership);
|
|
return ($this_user_id == $_definition['owner'] || count($alluser) > 0);
|
|
}
|
|
|
|
/**
|
|
* exports definitions
|
|
*
|
|
* @param array $keys to export
|
|
*/
|
|
public function export($keys)
|
|
{
|
|
$export_data = array('metainfo' => array(
|
|
'type' => 'importexport definitions',
|
|
'charset' => Api\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']
|
|
);
|
|
if($export_date['definitions'][$definition->name]['owner']) {
|
|
$export_data['definitions'][$definition->name]['owner'] =
|
|
importexport_helper_functions::account_id2name(
|
|
$export_data['definitions'][$definition->name]['owner']
|
|
);
|
|
} else {
|
|
unset($export_data['definitions'][$definition->name]['owner']);
|
|
}
|
|
unset($export_data['definitions'][$definition->name]['definition_id']);
|
|
unset($export_data['definitions'][$definition->name]['description']);
|
|
unset($export_data['definitions'][$definition->name]['user_timezone_read']);
|
|
if(is_array($export_data['definitions'][$definition->name]['plugin_options'])) {
|
|
unset($export_data['definitions'][$definition->name]['plugin_options']['user_timezone_read']);
|
|
}
|
|
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 = Api\Translation::convert(
|
|
$definitions,
|
|
$metainfo['charset'],
|
|
Api\Translation::charset()
|
|
);
|
|
|
|
// Avoid warning if no definitions found
|
|
if(!is_array($definitions)) return lang('None found');
|
|
|
|
// 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'] );
|
|
if($definition_data['all_users'] && !$definition_data['allowed_users']) $definition_data['allowed_users'] = 'all';
|
|
|
|
$definition_data['owner'] = importexport_helper_functions::account_name2id( $definition_data['owner'] );
|
|
|
|
$definition = new importexport_definition( $definition_data['name'] );
|
|
|
|
// Only update if the imported is newer
|
|
if(!$definition->modified || strtotime($definition->modified) < strtotime($definition_data['modified']))
|
|
{
|
|
$definition_id = $definition->get_identifier() ? $definition->get_identifier() : NULL;
|
|
|
|
$definition->set_record( $definition_data );
|
|
$definition->save( $definition_id );
|
|
}
|
|
}
|
|
return $definitions;
|
|
}
|
|
|
|
/**
|
|
* Create a matching export definition from the given import definition.
|
|
*
|
|
* Sets up the field mapping as closely as possible, and sets charset,
|
|
* header, conversion, etc. using the associated export plugin. Plugin
|
|
* is determined by replacing 'import' with 'export'.
|
|
*
|
|
* It is not possible to handle some plugin options automatically, because they
|
|
* just don't have equivalents. (eg: What to do with unknown categories)
|
|
*
|
|
* @param importexport_definition $definition Import definition
|
|
*
|
|
* @return importexport_definition Export definition
|
|
*/
|
|
public static function export_from_import(importexport_definition $import)
|
|
{
|
|
// Only operates on import definitions
|
|
if($import->type != 'import') throw new Api\Exception\WrongParameter('Only import definitions');
|
|
|
|
// Find export plugin
|
|
$plugin = str_replace('import', 'export',$import->plugin);
|
|
$plugin_list = importexport_helper_functions::get_plugins($import->application, 'export');
|
|
foreach($plugin_list as $appname => $type)
|
|
{
|
|
$plugins = $type['export'];
|
|
foreach($plugins as $name => $label)
|
|
{
|
|
if($plugin == $name) break;
|
|
}
|
|
if($plugin !== $name) $plugin = $name;
|
|
}
|
|
|
|
$export = new importexport_definition();
|
|
|
|
// Common settings
|
|
$export->name = str_replace('import', 'export',$import->name);
|
|
if($export->name == $import->name) $export->name = $export->name . '-export';
|
|
$test = new importexport_definition($export->name);
|
|
if($test->name) $export->name = $export->name .'-'.$GLOBALS['egw_info']['user']['account_lid'];
|
|
|
|
$export->application = $import->application;
|
|
$export->plugin = $plugin;
|
|
$export->type = 'export';
|
|
|
|
// Options
|
|
$i_options = $import->plugin_options;
|
|
$e_options = array(
|
|
'delimiter' => $i_options['fieldsep'],
|
|
'charset' => $i_options['charset'],
|
|
'begin_with_fieldnames' => $i_options['num_header_lines'] ? ($i_options['convert'] ? 'label' : 1) : 0,
|
|
'convert' => $i_options['convert']
|
|
);
|
|
|
|
// Mapping
|
|
foreach($i_options['field_mapping'] as $col_num => $field)
|
|
{
|
|
// Try to use heading from import file, if possible
|
|
$e_options['mapping'][$field] = $i_options['csv_fields'][$col_num] ? $i_options['csv_fields'][$col_num] : $field;
|
|
}
|
|
// Keep field names
|
|
$e_options['no_header_translation'] = true;
|
|
|
|
$export->plugin_options = $e_options;
|
|
|
|
// Permissions
|
|
$export->owner = $import->owner;
|
|
$export->allowed_users = $import->allowed_users;
|
|
|
|
return $export;
|
|
}
|
|
/**
|
|
*
|
|
* changes or deletes entries with a specified owner (for deleteaccount hook)
|
|
*
|
|
* @param array $args hook arguments
|
|
* @param int $args['account_id'] account to delete
|
|
* @param int $args['new_owner']=0 new owner
|
|
* @todo test deleting an owner with replace and without
|
|
*/
|
|
function change_delete_owner(array $args) // new_owner=0 means delete
|
|
{
|
|
if (!(int) $args['new_owner'])
|
|
{
|
|
$this->so_sql->delete(array('owner'=>$args['account_id']));
|
|
}
|
|
else
|
|
{
|
|
$GLOBALS['egw']->db->update(
|
|
self::_defintion_table,
|
|
array('owner'=>$args['new_owner']),
|
|
array('owner'=>$args['account_id']),
|
|
__LINE__,__FILE__,'importexport'
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
} |