Passed
Push — 16.1 ( db562c...7e0086 )
by Nathan
18:08
created

importexport_definition::__get()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 5
nop 1
dl 0
loc 15
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * eGroupWare importexport
4
 *
5
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
6
 * @package importexport
7
 * @link http://www.egroupware.org
8
 * @author Cornelius Weiss <[email protected]>
9
 * @copyright Cornelius Weiss <[email protected]>
10
 * @version $Id$
11
 */
12
13
use EGroupware\Api;
14
15
/**
16
 * class definition
17
 *
18
 * definitions are ojects with all nessesary information to do
19
 * complete import or export. All options needed for an explicit {Im|Ex}port
20
 * are in one assiozative array which is complely managed by {Im|Ex}port plugins
21
 * @todo testing
22
 */
23
class importexport_definition implements importexport_iface_egw_record {
24
25
	const _appname = 'importexport';
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected _APPNAME).
Loading history...
26
	const _defintion_talbe = 'egw_importexport_definitions';
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected _DEFINTION_TALBE).
Loading history...
27
28
	private $attributes = array(
29
		'definition_id' => 'string',
30
		'name' => 'string',
31
		'application' => 'string',
32
		'plugin' => 'string',
33
		'type' => 'string',
34
		'allowed_users' => 'array',
35
		'plugin_options' => 'array',
36
		'filter' => 'array',
37
		'owner' => 'int',
38
		'description' => 'string',
39
		'modified' => 'timestamp'
40
	);
41
42
	/**
43
	 * @var so_sql holds Api\Storage\Base object
44
	 */
45
	private $so_sql;
46
47
	/**
48
	 * @var array internal representation of definition
49
	 */
50
	private $definition = array();
51
52
	/**
53
	 * @var int holds current user
54
	 */
55
	private $user;
56
57
	/**
58
	 * @var bool is current user an admin?
59
	 */
60
	private $is_admin;
61
62
	/**
63
	 * constructor
64
	 * reads record from backend if identifier is given.
65
	 *
66
	 * @param string $_identifier
67
	 */
68
	public function __construct( $_identifier='' ) {
69
		$this->so_sql = new Api\Storage\Base(self::_appname ,self::_defintion_talbe);
70
		$this->user = $GLOBALS['egw_info']['user']['user_id'];
71
		$this->is_admin = $GLOBALS['egw_info']['user']['apps']['admin'] || $GLOBALS['egw_setup'] ? true : false;
72
		// compability to string identifiers
73
		if (!is_numeric($_identifier) && strlen($_identifier) > 3) $_identifier = $this->name2identifier($_identifier);
74
75
		if ((int)$_identifier != 0) {
76
			$this->definition = $this->so_sql->read(array('definition_id' => $_identifier));
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->so_sql->read(arra...n_id' => $_identifier)) can also be of type false. However, the property $definition is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
77
			if ( empty( $this->definition ) ) {
78
				throw new Exception('Error: No such definition with identifier :"'.$_identifier.'"!');
79
			}
80
			if ( !( importexport_definitions_bo::is_permitted($this->get_record_array()) || $this->is_admin)) {
81
				throw new Exception('Error: User "'.$this->user.'" is not permitted to get definition with identifier "'.$_identifier.'"!');
82
			}
83
			try
84
			{
85
				$options_data = importexport_arrayxml::xml2array( $this->definition['plugin_options'] );
86
				$this->definition['plugin_options'] = (array)$options_data['root'];
87
				if($this->definition['filter']) $filter = importexport_arrayxml::xml2array( $this->definition['filter']  );
88
				$this->definition['filter'] = $filter['root'];
89
			}
90
			catch (Exception $e)
91
			{
92
				error_log($e->getMessage());
93
			}
94
		}
95
	}
96
97
	/**
98
	 * compability function for string identifiers e.g. used by cli
99
	 *
100
	 * @param string $_name
101
	 * @return int
102
	 */
103
	private function name2identifier( $_name ) {
104
		$identifiers = $this->so_sql->search(array('name' => $_name),true);
105
		if (isset($identifiers[1])) {
106
			throw new Exception('Error: Definition: "'.$_name. '" is not unique! Can\'t convert to identifier');
107
		}
108
		if ( empty( $identifiers[0] ) ) {
109
			// not a good idea, till we don't have different exceptions so far
110
			// throw new Exception('Error: No such definition :"'.$_name.'"!');
111
			$identifiers = array( array( 'definition_id' => 0 ) );
112
		}
113
		return $identifiers[0]['definition_id'];
114
	}
115
116
	public function __get($_attribute_name) {
117
		if (!array_key_exists($_attribute_name,$this->attributes)) {
118
			throw new Exception('Error: "'. $_attribute_name. '" is not an attribute defintion');
119
		}
120
		switch ($_attribute_name) {
121
			case 'allowed_users' :
122
				return $this->get_allowed_users();
123
			case 'plugin_options' :
124
				return $this->get_options();
125
			case 'filter':
126
				return $this->get_filter();
127
			default :
128
				return $this->definition[$_attribute_name];
129
		}
130
	}
131
132
	public function __set($_attribute_name,$_data) {
133
		if (!array_key_exists($_attribute_name,$this->attributes)) {
134
			throw new Exception('Error: "'. $_attribute_name. '" is not an attribute defintion');
135
		}
136
		switch ($_attribute_name) {
137
			case 'allowed_users' :
138
				return $this->set_allowed_users($_data);
139
			case 'plugin_options' :
140
				return $this->set_options($_data);
141
			case 'filter':
142
				return $this->set_filter((Array)$_data);
143
			default :
144
				$this->definition[$_attribute_name] = $_data;
145
				return;
146
		}
147
	}
148
149
	/**
150
	 * gets users who are allowd to use this definition
151
	 *
152
	 * @return array
153
	 */
154
	private function get_allowed_users() {
155
		return explode(',',substr($this->definition['allowed_users'],1,-1));
156
	}
157
158
	/**
159
	 * sets allowed users
160
	 *
161
	 * @param array $_allowed_users
162
	 */
163
	private function set_allowed_users( $_allowed_users ) {
164
		$this->definition['allowed_users'] = ','.implode(',',(array)$_allowed_users) .',';
165
	}
166
167
	/**
168
	 * gets options
169
	 *
170
	 * @return array
171
	 */
172
	private function get_options() {
173
		return $this->definition['plugin_options'];
174
	}
175
176
	/**
177
	 * sets options
178
	 *
179
	 * @param array $options
180
	 */
181
	private function set_options(array $_plugin_options) {
182
		// Check conditions
183
		foreach ( $_plugin_options['conditions'] as $key => $condition ) {
184
			if(!$condition['string'])
185
			{
186
				unset($_plugin_options['conditions'][$key]);
187
			}
188
		}
189
		$this->definition['plugin_options'] = $_plugin_options;
190
	}
191
192
	/**
193
	 * Get stored data filter
194
	 *
195
	 * @return array
196
	 */
197
	private function get_filter() {
198
		return $this->definition['filter'];
199
	}
200
201
	/**
202
	 * Set stored data filter
203
	 *
204
	 * @param filter array of field => settings
205
	 */
206
	private function set_filter(Array $filter) {
207
		$this->definition['filter'] = $filter;
208
	}
209
210
	/**
211
	 * converts this object to array.
212
	 * @abstract We need such a function cause PHP5
213
	 * dosn't allow objects do define it's own casts :-(
214
	 * once PHP can deal with object casts we will change to them!
215
	 *
216
	 * @return array complete record as associative array
217
	 */
218
	public function get_record_array() {
219
		$definition = $this->definition;
220
		$definition['allowed_users'] = $this->get_allowed_users();
221
		$definition['plugin_options'] = $this->get_options();
222
		$definition['filter'] = $this->get_filter();
223
		return $definition;
224
	}
225
226
	/**
227
	 * gets title of record
228
	 *
229
	 *@return string tiltle
230
	 */
231
	public function get_title() {
232
		return $this->definition['name'];
233
	}
234
235
	/**
236
	 * sets complete record from associative array
237
	 *
238
	 * @return void
239
	 */
240
	public function set_record( array $_record ) {
241
		$this->definition = array_intersect_key( $_record, $this->attributes );
242
243
		// anything which is not an attribute is perhaps a plugin_option.
244
		// If not, it gets whiped out on save time.
245
		foreach ( $_record as $attribute => $value) {
246
			if ( !array_key_exists( $attribute, $this->attributes ) ) {
247
				$this->definition['plugin_options'][$attribute] = $value;
248
			}
249
		}
250
251
		$this->plugin = $_record['plugin'];
0 ignored issues
show
Documentation introduced by
The property plugin does not exist on object<importexport_definition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
252
253
		// convert plugin_options into internal representation
254
		$this->set_allowed_users( $this->definition['allowed_users'] );
255
		$this->set_options( $this->definition['plugin_options'] ? $this->definition['plugin_options'] : array());
256
		$this->set_filter( $this->definition['filter'] ? $this->definition['filter'] : array());
257
	}
258
259
	/**
260
	 * gets identifier of this record
261
	 *
262
	 * @return int identifier of this record
263
	 */
264
	public function get_identifier() {
265
		return $this->definition['definition_id'];
266
	}
267
268
269
	/**
270
	 * Gets the URL icon representitive of the record
271
	 * This could be as general as the application icon, or as specific as a contact photo
272
	 *
273
	 * @return string Full URL of an icon, or appname/icon_name
274
	 */
275
	public function get_icon() {
276
		return self::_appname . '/navbar';
277
	}
278
279
	/**
280
	 * saves record into backend
281
	 *
282
	 * @return string identifier
283
	 */
284
	public function save ( $_dst_identifier ) {
285
		if ( strlen($this->definition['name']) < 3 ) {
286
			throw new Exception('Error: Can\'t save definition, no valid name given!');
287
		}
288
289
		$this->so_sql->data = $this->definition;
290
		$this->so_sql->data['plugin_options'] = importexport_arrayxml::array2xml( $this->definition['plugin_options'] );
291
		$this->so_sql->data['filter'] = importexport_arrayxml::array2xml( $this->definition['filter'] );
292
		$this->so_sql->data['modified'] = time();
293
		if ($this->so_sql->save( array( 'definition_id' => $_dst_identifier ))) {
294
			throw new Exception('Error: Api\Storage\Base was not able to save definition: '.$this->get_identifier());
295
		}
296
297
		return $this->definition['definition_id'];
298
	}
299
300
	/**
301
	 * copys current record to record identified by $_dst_identifier
302
	 *
303
	 * @param string $_dst_identifier
304
	 * @return string dst_identifier
305
	 */
306
	public function copy ( $_dst_identifier ) {
307
		$dst_object = clone $this;
308
		try {
309
			$dst_object->set_owner($this->user);
0 ignored issues
show
Bug introduced by
The method set_owner() does not seem to exist on object<importexport_definition>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
310
			$dst_identifier = $dst_object->save($_dst_identifier);
311
		}
312
		catch(exception $Exception) {
313
			unset($dst_object);
314
			throw $Exception;
315
		}
316
		unset ($dst_object);
317
		return $dst_identifier;
318
	}
319
320
	/**
321
	 * moves current record to record identified by $_dst_identifier
322
	 * $this will become moved record
323
	 *
324
	 * @param string $_dst_identifier
325
	 * @return string dst_identifier
326
	 */
327
	public function move ( $_dst_identifier ) {
328 View Code Duplication
		if ($this->user != $this->get_owner() && !$this->is_admin) {
0 ignored issues
show
Bug introduced by
The method get_owner() does not seem to exist on object<importexport_definition>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
329
			throw('Error: User '. $this->user. 'does not have permissions to move definition '.$this->get_identifier());
330
		}
331
		$old_object = clone $this;
332
		try {
333
			$dst_identifier = $this->save($_dst_identifier);
334
			$old_object->delete();
335
		}
336
		catch(exception $Exception) {
337
			unset($old_object);
338
			throw $Exception;
339
		}
340
		unset($old_object);
341
		return $dst_identifier;
342
	}
343
344
	/**
345
	 * delets current record from backend
346
	 * @return void
347
	 *
348
	 */
349
	public function delete () {
350 View Code Duplication
		if($this->user != $this->get_owner() && !$this->is_admin) {
0 ignored issues
show
Bug introduced by
The method get_owner() does not seem to exist on object<importexport_definition>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
351
			throw('Error: User '. $this->user. 'does not have permissions to delete definition '.$this->get_identifier());
352
		}
353
		if(!$this->so_sql->delete()) {
354
			throw('Error: Api\Storage\Base was not able to delete definition: '.$this->get_identifier());
355
		}
356
	}
357
358
	/**
359
	 * destructor
360
	 *
361
	 */
362
	public function __destruct() {
363
		unset($this->so_sql);
364
	}
365
366
}
367