egroupware/importexport/inc/class.importexport_definition.inc.php

384 lines
10 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;
use EGroupware\Api\Exception\WrongParameter;
/**
* 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',
'filter' => 'array',
'owner' => 'int',
'description' => 'string',
'modified' => 'timestamp'
);
/**
* @var so_sql holds Api\Storage\Base 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 Api\Storage\Base(self::_appname ,self::_defintion_talbe);
$this->user = $GLOBALS['egw_info']['user']['user_id'];
$this->is_admin = $GLOBALS['egw_info']['user']['apps']['admin'] || $GLOBALS['egw_setup'] ? true : false;
// compability to string identifiers
if (!is_numeric($_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 ( !( importexport_definitions_bo::is_permitted($this->get_record_array()) || $this->is_admin)) {
throw new Exception('Error: User "'.$this->user.'" is not permitted to get definition with identifier "'.$_identifier.'"!');
}
set_error_handler(function($errorno, $errorstr, $errorfile, $errorline)
{
if(0=== error_reporting())
{
return false;
}
throw new WrongParameter($errorstr);
});
try
{
$options_data = importexport_arrayxml::xml2array( $this->definition['plugin_options'] );
$this->definition['plugin_options'] = (array)$options_data['root'];
if($this->definition['filter'])
{
$filter = importexport_arrayxml::xml2array( $this->definition['filter'] );
$this->definition['filter'] = $filter['root'];
}
}
catch (Throwable $e)
{
error_log(__METHOD__ . " Error constructing definition " .
($this->definition && $this->definition['name'] ? $this->definition['name'] : $_identifier));
error_log($e->getMessage());
}
restore_error_handler();
}
}
/**
* 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();
case 'filter':
return $this->get_filter();
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);
case 'filter':
return $this->set_filter((Array)$_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(',',substr($this->definition['allowed_users'],1,-1));
}
/**
* 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)
{
// Check conditions
foreach ((array)$_plugin_options['conditions'] as $key => $condition)
{
if (is_array($condition) && empty($condition['string']) && array_key_exists($key, $_plugin_options['conditions']))
{
unset($_plugin_options['conditions'][$key]);
}
}
$this->definition['plugin_options'] = $_plugin_options;
}
/**
* Get stored data filter
*
* @return array
*/
private function get_filter() {
return $this->definition['filter'];
}
/**
* Set stored data filter
*
* @param filter array of field => settings
*/
private function set_filter(Array $filter) {
$this->definition['filter'] = $filter;
}
/**
* 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();
$definition['filter'] = $this->get_filter();
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());
$this->set_filter( $this->definition['filter'] ? $this->definition['filter'] : array());
}
/**
* gets identifier of this record
*
* @return int identifier of this record
*/
public function get_identifier() {
return $this->definition['definition_id'];
}
/**
* Gets the URL icon representitive of the record
* This could be as general as the application icon, or as specific as a contact photo
*
* @return string Full URL of an icon, or appname/icon_name
*/
public function get_icon() {
return self::_appname . '/navbar';
}
/**
* 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'] );
$this->so_sql->data['filter'] = importexport_arrayxml::array2xml( $this->definition['filter'] );
$this->so_sql->data['modified'] = time();
if ($this->so_sql->save( array( 'definition_id' => $_dst_identifier ))) {
throw new Exception('Error: Api\Storage\Base 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 new Api\Exception('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 new Api\Exception('Error: User '. $this->user. 'does not have permissions to delete definition '.$this->get_identifier());
}
if(!$this->so_sql->delete()) {
throw new Api\Exception('Error: Api\Storage\Base was not able to delete definition: '.$this->get_identifier());
}
}
/**
* destructor
*
*/
public function __destruct() {
unset($this->so_sql);
}
}