infolog_customfields::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 13
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * InfoLog - Custom fields
4
 *
5
 * @link http://www.egroupware.org
6
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
7
 * @package infolog
8
 * @copyright (c) 2003-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
9
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
10
 * @version $Id$
11
 */
12
13
use EGroupware\Api;
14
use EGroupware\Api\Etemplate;
15
16
/**
17
 * Administration of custom fields, type and status
18
 */
19
class infolog_customfields extends admin_customfields
20
{
21
	public $appname = 'infolog';
22
	/**
23
	 * Instance of the infolog BO class
24
	 *
25
	 * @var infolog_bo
26
	 */
27
	var $bo;
28
	/**
29
	 * instance of the config class for infolog
30
	 *
31
	 * @var Api\Config
32
	 */
33
	var $config_data;
34
	/**
35
	 * Group owners for certain types read from the infolog config
36
	 *
37
	 * @var array
38
	 */
39
	var $group_owners;
40
41
	function __construct( )
42
	{
43
		parent::__construct('infolog');
44
45
		$this->bo = new infolog_bo();
46
		$this->tmpl = new Etemplate();
47
		$this->content_types = &$this->bo->enums['type'];
48
		$this->status = &$this->bo->status;
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
49
		$this->config_data = Api\Config::read('infolog');
0 ignored issues
show
Documentation Bug introduced by
It seems like EGroupware\Api\Config::read('infolog') of type array is incompatible with the declared type EGroupware\Api\Config of property $config_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
50
		$this->fields = &$this->bo->customfields;
51
		$this->group_owners =& $this->bo->group_owners;
52
53
		Api\Translation::add_app('infolog');
54
	}
55
56
57
	/**
58
	 * Hook from parent class so we can interfere and add owner & status
59
	 */
60
	protected function app_index(&$content, &$sel_options, &$readonlys, &$preserve)
61
	{
62
		unset($sel_options);	// not used, but required by function signature
63
64
		$n = 0;
65
		foreach($this->status[$this->content_type] as $name => $label)
66
		{
67
			$content['content_type_options']['status'][++$n] = array(
68
				'name'     => $name,
69
				'label'    => $label,
70
				'disabled' => False
71
			);
72
			$preserve['content_type_options']['status'][$n]['old_name'] = $name;
73
			if (isset($this->bo->stock_status[$this->content_type][$name]))
74
			{
75
				$readonlys['content_type_options']['status']["delete[$name]"] =
76
				$readonlys['content_type_options']['status'][$n.'[name]'] = True;
77
			}
78
			$readonlys['content_type_options']['status']["create$name"] = True;
79
		}
80
		$content['content_type_options']['status'][++$n] = array(
81
			'name'     => '',
82
			'label'    => '',
83
			'disabled' => False
84
		);
85
		$content['content_type_options']['status']['default'] = $this->status['defaults'][$this->content_type];
86
		$content['content_type_options']['group_owner'] = $this->group_owners[$this->content_type];
87
		$readonlys['content_types']['delete'] = isset($this->bo->stock_enums['type'][$this->content_type]);
88
	}
89
90
	function update_fields(&$content)
91
	{
92
		$fields = &$content['fields'];
93
94
		$create = $fields['create'];
95
		unset($fields['create']);
96
97
		if ($fields['delete'])
98
		{
99
			$delete = key($fields['delete']);
100
			unset($fields['delete']);
101
		}
102
103
		foreach($fields as $field)
104
		{
105
			$name = trim($field['name']);
106
			$old_name = $field['old_name'];
107
108
			if (!empty($delete) && $delete == $old_name)
109
			{
110
				unset($this->fields[$old_name]);
111
				continue;
112
			}
113
			if (isset($field['name']) && empty($name) && ($create || !empty($old_name)))	// empty name not allowed
114
			{
115
				$content['error_msg'] = lang('Name must not be empty !!!');
116
			}
117
			if (isset($field['old_name']))
118
			{
119
				if (!empty($name) && $old_name != $name)	// renamed
120
				{
121
					unset($this->fields[$old_name]);
122
				}
123
				elseif (empty($name))
124
				{
125
					$name = $old_name;
126
				}
127
			}
128
			elseif (empty($name))		// new item and empty ==> ignore it
129
			{
130
				continue;
131
			}
132
			$values = array();
133
			if (!empty($field['values']))
134
			{
135
				foreach(explode("\n",$field['values']) as $line)
136
				{
137
					list($var2,$value) = explode('=',trim($line),2);
138
					$var = trim($var2);
139
					$values[$var] = empty($value) ? $var : $value;
140
				}
141
			}
142
			$this->fields[$name] = array(
143
				'type2'   => $field['type2'],
144
				'type'  => $field['type'],
145
				'label' => empty($field['label']) ? $name : $field['label'],
146
				'help'  => $field['help'],
147
				'values'=> $values,
148
				'len'   => $field['len'],
149
				'rows'  => (int)$field['rows'],
150
				'order' => (int)$field['order'],
151
				'needed' => $field['needed'],
152
			);
153
		}
154
		if (!function_exists('sort_by_order'))
155
		{
156
			function sort_by_order($arr1,$arr2)
157
			{
158
				return $arr1['order'] - $arr2['order'];
159
			}
160
		}
161
		uasort($this->fields,sort_by_order);
0 ignored issues
show
Bug introduced by
The constant sort_by_order was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
162
163
		$n = 0;
164
		foreach(array_keys($this->fields) as $name)
165
		{
166
			$this->fields[$name]['order'] = ($n += 10);
167
		}
168
	}
169
170
	function update_status(&$content)
171
	{
172
		$typ = $this->content_type;
173
		$status = &$content['content_type_options']['status'];
174
175
		$default = $status['default'];
176
		unset($status['default']);
177
178
		$create = $status['create'];
179
		unset($status['create']);
180
181
		if ($status['delete'])
182
		{
183
			$delete = key($status['delete']);
184
			unset($status['delete']);
185
		}
186
187
		foreach($status as $stat)
188
		{
189
			$name = trim($stat['name']);
190
			$old_name = $stat['old_name'];
191
192
			if (!empty($delete) && $delete == $old_name)
193
			{
194
				unset($this->status[$typ][$old_name]);
195
				continue;
196
			}
197
			if (isset($stat['name']) && empty($name) && ($create || !empty($old_name)))	// empty name not allowed
198
			{
199
				$content['error_msg'] = lang('Name must not be empty !!!');
200
			}
201
			if (isset($stat['old_name']))
202
			{
203
				if (!empty($name) && $old_name != $name)	// renamed
204
				{
205
					unset($this->status[$typ][$old_name]);
206
207
					if ($default == $old_name)
208
					{
209
						$default = $name;
210
					}
211
				}
212
				elseif (empty($name))
213
				{
214
					$name = $old_name;
215
				}
216
			}
217
			elseif (empty($name))		// new item and empty ==> ignore it
218
			{
219
				continue;
220
			}
221
			$this->status[$typ][$name] = empty($stat['label']) ? $name : $stat['label'];
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
222
		}
223
		$this->status['defaults'][$typ] = empty($default) ? $name : $default;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $name seems to be defined by a foreach iteration on line 187. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
224
		if (!isset($this->status[$typ][$this->status['defaults'][$typ]]))
225
		{
226
			$this->status['defaults'][$typ] = @key($this->status[$typ]);
227
		}
228
	}
229
230
	function update(&$content)
231
	{
232
		$old = array(
233
			'status' => $this->status,
234
			'group_owners' => $this->group_owners
235
		);
236
		$this->update_status($content);
237
238
		if ($content['content_type_options']['group_owner'])
239
		{
240
			$this->group_owners[$this->content_type] = $content['content_type_options']['group_owner'];
241
		}
242
		else
243
		{
244
			unset($this->group_owners[$this->content_type]);
245
		}
246
		$changed = array();
247
		foreach($old as $key => $value)
248
		{
249
			if($this->$key != $value)
250
			{
251
				// NB: Statuses are monolithic - we can't record just the one type
252
				// that was changed, or we loose the other types.  All status must
253
				// be recorded.
254
				$changed[$key] = $this->$key;
255
			}
256
			else
257
			{
258
				unset($old[$key]);
259
			}
260
		}
261
		if($changed)
262
		{
263
			$cmd = new admin_cmd_config('infolog',$changed, $old);
264
			$cmd->run();
265
		}
266
	}
267
268
	function delete(&$content)
269
	{
270
		if (isset($this->bo->stock_enums['type'][$content['type2']]))
271
		{
272
			$content['error_msg'] .= lang("You can't delete one of the stock types !!!");
273
			return;
274
		}
275
		unset($this->content_types[$content['type2']]);
276
		unset($this->status[$content['type2']]);
277
		unset($this->status['defaults'][$content['type2']]);
278
		unset($this->group_owners[$content['type2']]);
279
		$content['type2'] = key($this->content_types);
280
281
		// save changes to repository
282
		$this->save_repository();
283
	}
284
285
	function create_content_type(&$content)
286
	{
287
		$new_name = trim($content['content_types']['name']);
288
		if (empty($new_name))
289
		{
290
			$this->tmpl->set_validation_error('content_types[name]',lang('You have to enter a name, to create a new type!'));
291
			return false;
292
		}
293
		else
294
		{
295
			foreach($this->content_types as $name)
296
			{
297
				if($name == $new_name)
298
				{
299
					$this->tmpl->set_validation_error('content_types[name]',lang("type '%1' already exists !!!",$new_name));
0 ignored issues
show
Unused Code introduced by
The call to lang() has too many arguments starting with $new_name. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

299
					$this->tmpl->set_validation_error('content_types[name]',/** @scrutinizer ignore-call */ lang("type '%1' already exists !!!",$new_name));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
300
					return false;
301
				}
302
			}
303
		}
304
		$this->content_types[$new_name] = $new_name;
305
		$this->status[$new_name] = array(
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
306
			'ongoing' => 'ongoing',
307
			'done' => 'done'
308
		);
309
		$this->status['defaults'][$new_name] = 'ongoing';
310
311
		// save changes to repository
312
		$this->save_repository();
313
		return $new_name;
314
	}
315
316
	function save_repository()
317
	{
318
		// save changes to repository
319
		Api\Config::save_value('types',$this->content_types,'infolog');
320
		//echo '<p>'.__METHOD__.'() \$this->status=<pre style="text-aling: left;">'; print_r($this->status); echo "</pre>\n";
321
		Api\Config::save_value('status',$this->status,'infolog');
322
		//echo '<p>'.__METHOD__.'() \$this->fields=<pre style="text-aling: left;">'; print_r($this->fields); echo "</pre>\n";
323
		Api\Storage\Customfields::save('infolog', $this->fields);
324
		Api\Config::save_value('group_owners',$this->group_owners,'infolog');
325
	}
326
327
	/**
328
	 * Change account_ids in group_owners configuration hook called from admin_cmd_change_account_id
329
	 *
330
	 * @param array $changes
331
	 * @return int number of changed account_ids
332
	 */
333
	public static function change_account_ids(array $changes)
334
	{
335
		unset($changes['location']);	// no change, but the hook name
336
		$changed = 0;
337
338
		// migrate staff account_ids
339
		$config = Api\Config::read('infolog');
340
		$old = $config['group_owners'];
341
		if (!empty($config['group_owners']))
342
		{
343
			foreach($config['group_owners'] as &$account_id)
344
			{
345
				if (isset($changes[$account_id]))
346
				{
347
					$account_id = $changes[$account_id];
348
					$changed++;
349
					$needs_save = true;
350
				}
351
			}
352
			if ($needs_save)
353
			{
354
				$cmd = new admin_cmd_config('infolog',
355
						array('group_owners' => $config['group_owners']),
356
						array('group_owners' => $old)
357
				);
358
				$cmd->exec();
359
			}
360
		}
361
362
		return $changed;
363
	}
364
}
365