Completed
Push — master ( 53db16...82065a )
by Nathan
17:56
created

admin_cmd_edit_group::as_array()   C

Complexity

Conditions 12
Paths 48

Size

Total Lines 54
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 12
eloc 28
c 1
b 1
f 0
nc 48
nop 0
dl 0
loc 54
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * EGgroupware admin - admin command: edit/add a group
4
 *
5
 * @link http://www.egroupware.org
6
 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
7
 * @package admin
8
 * @copyright (c) 2007-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
15
/**
16
 * admin command: edit/add a user
17
 */
18
class admin_cmd_edit_group extends admin_cmd
19
{
20
	/**
21
	 * Constructor
22
	 *
23
	 * @param string|int|array $account account name or id (!$account to add a new account), or array with all parameters
24
	 * @param array $set =null array with all data to change
25
	 */
26
	function __construct($account,$set=null)
27
	{
28
		if (!is_array($account))
29
		{
30
			$account = array(
31
				'account' => $account,
32
				'set' => $set,
33
			);
34
		}
35
		admin_cmd::__construct($account);
36
	}
37
38
	/**
39
	 * change the password of a given user
40
	 *
41
	 * @param boolean $check_only =false only run the checks (and throw the exceptions), but not the command itself
42
	 * @return string success message
43
	 * @throws Api\Exception\NoPermission\Admin
44
	 * @throws Api\Exception\WrongUserinput(lang("Unknown account: %1 !!!",$this->account),15);
45
	 */
46
	protected function exec($check_only=false)
47
	{
48
		// check creator is still admin and not explicitly forbidden to edit accounts/groups
49
		if ($this->creator) $this->_check_admin('group_access',$this->account ? 16 : 4);
50
51
		admin_cmd::_instanciate_accounts();
52
53
		$data = $this->set;
54
55
		if ($this->account)	// existing account
56
		{
57
			$data['account_id'] = admin_cmd::parse_account($this->account,false);
58
		}
59
		$data += array(
60
			'account_type' => 'g',
61
			'account_status' => 'A',	// not used, but so we do the same thing as the web-interface
62
			'account_expires' => -1,
63
		);
64
		if (!$data['account_lid'] && (!$this->account || !is_null($data['account_lid'])))
65
		{
66
			throw new Api\Exception\WrongUserinput(lang('You must enter a group name.'), 17);
67
		}
68
		if (!is_null($data['account_lid']) && ($id = admin_cmd::$accounts->name2id($data['account_lid'],'account_lid','g')) &&
69
			$id !== $data['account_id'])
70
		{
71
			throw new Api\Exception\WrongUserinput(lang('That loginid has already been taken'), 11);
72
		}
73
		if (!$data['account_members'] && !$this->account)
74
		{
75
			throw new Api\Exception\WrongUserinput(lang('You must select at least one group member.'), 18);
76
		}
77
		if ($data['account_members'])
78
		{
79
			$data['account_members'] = admin_cmd::parse_accounts($data['account_members'],true);
80
		}
81
		if ($check_only) return true;
82
83
		if (($update = $this->account))
84
		{
85
			// invalidate account, before reading it, to code with changed to DB or LDAP outside EGw
86
			Api\Accounts::cache_invalidate($data['account_id']);
87
			if (!($old = admin_cmd::$accounts->read($data['account_id'])))
88
			{
89
				throw new Api\Exception\WrongUserinput(lang("Unknown account: %1 !!!",$this->account),15);
0 ignored issues
show
Unused Code introduced by
The call to lang() has too many arguments starting with $this->account. ( Ignorable by Annotation )

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

89
				throw new Api\Exception\WrongUserinput(/** @scrutinizer ignore-call */ lang("Unknown account: %1 !!!",$this->account),15);

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...
90
			}
91
			// as the current account class always sets all values, we have to add the not specified ones
92
			foreach($data as $name => &$value)
93
			{
94
				if (is_null($value)) $value = $old[$name];
95
			}
96
		}
97
		if (!($data['account_id'] = admin_cmd::$accounts->save($data)))
98
		{
99
			//_debug_array($data);
100
			throw new Api\Db\Exception(lang("Error saving account!"),11);
101
		}
102
		// Make sure we have lid for hook even if not changed, also set deprecated name
103
		$data['account_name'] = $data['account_lid'] = $data['account_lid'] ?
104
				$data['account_lid'] :
105
				admin_cmd::$accounts->id2name($data['account_id']);
106
107
		if ($update) $data['old_name'] = $old['account_lid'];	// make old name available for hooks
108
		$GLOBALS['hook_values'] =& $data;
109
		Api\Hooks::process($GLOBALS['hook_values']+array(
110
			'location' => $update ? 'editgroup' : 'addgroup'
111
		),False,True);	// called for every app now, not only enabled ones)
112
113
		if ($data['account_members'])
114
		{
115
			admin_cmd::$accounts->set_members($data['account_members'],$data['account_id']);
116
		}
117
		// make new account_id available to caller
118
		$this->account = $data['account_id'];
0 ignored issues
show
Bug introduced by
The property account is declared read-only in admin_cmd.
Loading history...
119
120
		return lang("Group %1 %2", $data['account_lid'] ? $data['account_lid'] : Api\Accounts::id2name($this->account),
121
			$update ? lang('updated') : lang("created with id #%1", $this->account));
122
	}
123
124
	/**
125
	 * Return a title / string representation for a given command, eg. to display it
126
	 *
127
	 * @return string
128
	 */
129
	function __tostring()
130
	{
131
		return lang('%1 group %2',$this->account ? lang('Edit') : lang('Add'),
0 ignored issues
show
Unused Code introduced by
The call to lang() has too many arguments starting with $this->account ? lang('Edit') : lang('Add'). ( Ignorable by Annotation )

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

131
		return /** @scrutinizer ignore-call */ lang('%1 group %2',$this->account ? lang('Edit') : lang('Add'),

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...
132
			admin_cmd::display_account($this->account ? $this->account : $this->set['account_lid']));
133
	}
134
135
	/**
136
	 * Return (human readable) labels for keys of changes
137
	 *
138
	 * Reading them from admin.account template
139
	 *
140
	 * @return array
141
	 */
142
	function get_etemplate_name()
143
	{
144
		return ($GLOBALS['egw_info']['apps']['stylite'] ? 'stylite' : 'groups').'.group.edit';
145
	}
146
147
	/**
148
	 * Return (human readable) labels for keys of changes
149
	 *
150
	 * Reading them from admin.account template
151
	 *
152
	 * @return array
153
	 */
154
	function get_change_labels()
155
	{
156
		$labels = parent::get_change_labels();
157
		unset($labels['${row}[run]']);
158
159
		$labels['account_members'] = 'Members';
160
		$labels['account_email'] = 'Email';
161
162
		return $labels;
163
	}
164
	/**
165
	 * Return widget types (indexed by field key) for changes
166
	 *
167
	 * Used by historylog widget to show the changes the command recorded.
168
	 */
169
	function get_change_widgets()
170
	{
171
		$widgets = parent::get_change_widgets();
172
173
		$widgets['account_id'] = 'integer';	// normaly not displayed
174
		$widgets['run'] = 'select-app';
175
176
		return $widgets;
177
	}
178
179
	/**
180
	 * Return the whole object-data as array, it's a cast of the object to an array
181
	 *
182
	 * Reimplement to supress data not relevant for groups, but historically stored
183
	 *
184
	 * @todo Fix command to store it's data in a more sane way, like we use it.
185
	 * @return array
186
	 */
187
	function as_array()
188
	{
189
		$data = parent::as_array();
190
191
		// for some reason old is stored under set
192
		if (isset($data['set']['old']))
193
		{
194
			$data['old'] = $data['set']['old'];
195
			unset($data['set']['old']);
196
		}
197
		if (!empty($data['set']['old_run']))
198
		{
199
			$data['old']['run'] = $data['set']['old_run'];
200
			usort($data['old']['run'], function($a, $b)
201
			{
202
				return strcasecmp(lang($a), lang($b));
203
			});
204
			unset($data['set']['old_run']);
205
		}
206
		if (!empty($data['set']['apps']))
207
		{
208
			$data['set']['run'] = array_diff(array_map(function($data)
209
			{
210
				return $data['run'] ? $data['appname'] : null;
211
			}, $data['set']['apps']), [null]);
212
			usort($data['set']['run'], function($a, $b)
213
			{
214
				return strcasecmp(lang($a), lang($b));
215
			});
216
			unset($data['set']['apps']);
217
		}
218
219
		// remove values not relevant to groups
220
		foreach(['old', 'set'] as $name)
221
		{
222
			$data[$name] = array_diff_key($data[$name], array_flip([
223
				'account_pwd', 'account_status', 'account_type',
224
				'account_expires', 'account_primary_group',
225
				'account_lastlogin', 'account_lastloginfrom',
226
				'account_lastpwd_change', 'members-active',
227
				'account_firstname', 'account_lastname', 'account_fullname',
228
			]));
229
		}
230
231
		// remove unchanged values (null == '' and arrays might not be sorted)
232
		foreach($data['set'] as $name => $value)
233
		{
234
			if ($data['old'][$name] == $value ||
235
				is_array($value) && sort($value) && sort($data['old'][$name]) && $value == $data['old'][$name])
236
			{
237
				unset($data['old'][$name], $data['set'][$name]);
238
			}
239
		}
240
		return $data;
241
	}
242
243
}
244