egroupware/importexport/inc/class.importexport_definitions_bo.inc.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'
);
}
}
}