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
![]() |
|||||
49 | $this->config_data = Api\Config::read('infolog'); |
||||
0 ignored issues
–
show
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.. ![]() |
|||||
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
|
|||||
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
|
|||||
222 | } |
||||
223 | $this->status['defaults'][$typ] = empty($default) ? $name : $default; |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
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
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
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. ![]() |
|||||
300 | return false; |
||||
301 | } |
||||
302 | } |
||||
303 | } |
||||
304 | $this->content_types[$new_name] = $new_name; |
||||
305 | $this->status[$new_name] = array( |
||||
0 ignored issues
–
show
|
|||||
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 |