GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Docman_Actions   F
last analyzed

Complexity

Total Complexity 410

Size/Duplication

Total Lines 2254
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 40
Metric Value
wmc 410
lcom 1
cbo 40
dl 0
loc 2254
rs 0.5217

71 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A _getEventManager() 0 4 1
A expandFolder() 0 4 1
A expandAll() 0 3 1
A collapseFolder() 0 4 1
F _storeFile() 0 165 23
A createFolder() 0 3 1
A createDocument() 0 3 1
A _getFolderFromRequest() 0 7 1
B _checkOwnerChange() 0 18 5
A _raiseMetadataChangeEvent() 0 11 1
A _raiseLockEvent() 0 6 1
A _raiseUnlockEvent() 0 6 1
A newVersionApprovalTable() 0 9 2
F createItem() 0 209 43
F update() 0 178 41
B new_version() 0 22 6
B updateLink() 0 26 2
A manageLockNewVersion() 0 14 4
A _getFileStorage() 0 6 2
A _getItemFactory() 0 3 1
A _getFolderFactory() 0 3 1
A _getVersionFactory() 0 6 2
A _getPermissionsManagerInstance() 0 6 2
A _getDocmanPermissionsManagerInstance() 0 3 1
A _getUserManagerInstance() 0 6 2
B _doCutPaste() 0 23 5
B _doCopyPaste() 0 41 3
C move() 0 33 8
A action_cut() 0 19 1
A action_copy() 0 20 1
A doPaste() 0 15 3
A paste() 0 7 1
A _get_definition_index_for_permission() 0 16 4
B permissions() 0 17 5
B setPermissionsOnItem() 0 59 5
A recursivePermissions() 0 8 2
C _setPermission() 0 75 13
A _getBiggerOrEqualParent() 0 19 4
C change_view() 0 23 7
B delete() 0 24 5
D deleteVersion() 0 44 10
A _getActionsDeleteVisitor() 0 3 1
A admin_change_view() 0 14 4
A install() 0 6 1
A admin_set_permissions() 0 8 2
D admin_md_details_update() 0 75 12
B admin_create_metadata() 0 42 3
A admin_delete_metadata() 0 21 2
B admin_create_love() 0 26 4
B admin_delete_love() 0 34 5
A admin_update_love() 0 23 2
B admin_import_metadata() 0 17 5
D monitor() 0 46 21
A _raiseMonitoringListEvent() 0 7 1
D add_monitoring() 0 46 16
D remove_monitoring() 0 26 10
D _approval_update_settings() 0 36 10
D _approval_update_add_users() 0 63 16
A _approval_update_del_users() 0 14 4
B _approval_update_notify_users() 0 21 5
A _approval_update_notif_resend() 0 8 2
D approval_update() 0 71 19
A approval_delete() 0 12 2
A approval_upd_user() 0 10 1
B approval_user_commit() 0 41 3
C report_del() 0 25 7
B report_upd() 0 27 4
C report_import() 0 69 13
C action_lock_add() 0 34 8
A action_lock_del() 0 9 2

How to fix   Complexity   

Complex Class

Complex classes like Docman_Actions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Docman_Actions, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Copyright (c) STMicroelectronics, 2006. All Rights Reserved.
4
 *
5
 * Originally written by Manuel Vacelet, 2006
6
 *
7
 * This file is a part of Codendi.
8
 *
9
 * Codendi is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * Codendi is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
21
 */
22
require_once('service.php');
23
require_once('www/project/admin/permissions.php');
24
require_once('www/news/news_utils.php');
25
26
class Docman_Actions extends Actions {
27
28
    var $event_manager;
29
30
    function __construct(&$controler, $view=null) {
31
        parent::Actions($controler);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (Actions() instead of __construct()). Are you sure this is correct? If so, you might want to change this to $this->Actions().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
32
        $this->event_manager =& $this->_getEventManager();
33
    }
34
35
    function &_getEventManager() {
36
        $em =& EventManager::instance();
37
        return $em;
38
    }
39
40
    function expandFolder() {
41
        $folderFactory = new Docman_FolderFactory();
42
        $folderFactory->expand($this->_getFolderFromRequest());
43
    }
44
    function expandAll($params) {
45
        $params['hierarchy']->accept(new Docman_ExpandAllHierarchyVisitor(), array('folderFactory' => new Docman_FolderFactory()));
46
    }
47
    function collapseFolder() {
48
        $folderFactory = new Docman_FolderFactory();
49
        $folderFactory->collapse($this->_getFolderFromRequest());
50
    }
51
    function &_getFolderFromRequest() {
52
        $request =& HTTPRequest::instance();
53
        $folder = new Docman_Folder();
54
        $folder->setId((int) $request->get('id'));
55
        $folder->setGroupId((int) $request->get('group_id'));
56
        return $folder;
57
    }
58
59
    //@todo need to check owner rights on parent
60
    function _checkOwnerChange($owner, &$user) {
61
        $ret_id = null;
62
63
        $_owner = UserManager::instance()->findUser($owner);
64
        if(!$_owner) {
65
            $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'warning_missingowner'));
66
            $ret_id = $user->getId();
67
        }
68
        else {
69
            if(!$_owner->isAnonymous() && ($_owner->isActive() || $_owner->isRestricted())) {
70
                $ret_id = $_owner->getId();
71
            } else {
72
                $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'warning_invalidowner'));
73
                $ret_id = $user->getId();
74
            }
75
        }
76
        return $ret_id;
77
    }
78
79
    private function _raiseMetadataChangeEvent(&$user, &$item, $group_id, $old, $new, $field) {
80
        $logEventParam = array('group_id' => $group_id,
81
                               'item'     => &$item,
82
                               'user'     => &$user,
83
                               'old_value' => $old,
84
                               'new_value' => $new,
85
                               'field'     => $field);
86
87
        $this->event_manager->processEvent('plugin_docman_event_metadata_update',
88
                                           $logEventParam);
89
    }
90
91
    /**
92
     * Raise "Lock add" event
93
     *
94
     * @param Docman_Item $item Locked item
95
     * @param PFUser        $user Who locked the item
96
     *
97
     * @return void
98
     */
99
    function _raiseLockEvent($item, $user) {
100
        $p = array('group_id' => $item->getGroupId(),
101
                   'item'     => $item,
102
                   'user'     => $user);
103
        $this->event_manager->processEvent('plugin_docman_event_lock_add', $p);
104
    }
105
106
    /**
107
     * Raise "Lock deletion" event
108
     *
109
     * @param Docman_Item $item Unlocked item
110
     * @param PFUser        $user Who unlocked the item
111
     *
112
     * @return void
113
     */
114
    function _raiseUnlockEvent($item, $user) {
115
        $p = array('group_id' => $item->getGroupId(),
116
                   'item'     => $item,
117
                   'user'     => $user);
118
        $this->event_manager->processEvent('plugin_docman_event_lock_del', $p);
119
    }
120
121
    /**
122
     * This function handle file storage regarding user parameters.
123
     *
124
     * @access: private
125
     */
126
    function _storeFile($item) {
127
        $fs       =& $this->_getFileStorage();
128
        $user     =& $this->_controler->getUser();
129
        $request  =& $this->_controler->request;
130
        $iFactory =& $this->_getItemFactory();
131
        $vFactory =& $this->_getVersionFactory();
132
133
        $uploadSucceded = false;
134
        $newVersion     = null;
135
136
        $_label     = '';
137
        $_changelog = '';
138
139
        $nextNb = $vFactory->getNextVersionNumber($item);
140
        if($nextNb === false) {
141
            $number       = 1;
142
            $_action_type = 'initversion';
143
            $_changelog   = 'Initial version';
144
        } else {
145
            $number       = $nextNb;
146
            $_action_type = 'newversion';
147
        }
148
149
        // Prepare label and changelog from user input
150
        $data_version = $request->get('version');
151
        if ($data_version) {
152
            if (isset($data_version['label'])) {
153
                $_label = $data_version['label'];
154
            }
155
            if (isset($data_version['changelog'])) {
156
                $_changelog = $data_version['changelog'];
157
            }
158
        }
159
160
        switch ($iFactory->getItemTypeForItem($item)) {
161
        case PLUGIN_DOCMAN_ITEM_TYPE_FILE:
162
            if ($request->exist('upload_content')) {
163
164
                if ($request->exist('chunk_offset') && $request->exist('chunk_size')) {
165
                    $path = $fs->store($request->get('upload_content'), $request->get('group_id'), $item->getId(), $number, $request->get('chunk_offset'), $request->get('chunk_size'));
166
                } else {
167
                    $path = $fs->store($request->get('upload_content'), $request->get('group_id'), $item->getId(), $number);
168
                }
169
170
                if ($path) {
171
                    $uploadSucceded = true;
172
173
                    if ($request->exist('file_name')) {
174
                        $_filename = basename($request->get('file_name'));
175
                    } else {
176
                        $_filename = basename($path);
177
                    }
178
179
                    if ($request->exist('file_size')) {
180
                        $_filesize = $request->get('file_size');
181
                    } else {
182
                        $_filesize = filesize($path);
183
                    }
184
185
                    if ($request->exist('mime_type')) {
186
                        $_filetype = $request->get('mime_type');
187
                    } else {
188
                        $_filetype = mime_content_type($path); //be careful with false detection
189
                    }
190
                }
191
            } else {
192
                $path = $fs->upload($_FILES['file'], $item->getGroupId(), $item->getId(), $number);
193
                if ($path) {
194
                    $uploadSucceded = true;
195
                    $_filename = $_FILES['file']['name'];
196
                    $_filesize = $_FILES['file']['size'];
197
                    $_filetype = $_FILES['file']['type']; //TODO detect mime type server side
198
                }
199
            }
200
201
            $mime_type_detector = new Docman_MIMETypeDetector();
202
            if ($path && $mime_type_detector->isAnOfficeFile($_filename)) {
203
                $_filetype = $mime_type_detector->getRightOfficeType($_filename);
204
            }
205
206
            break;
207
        case PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE:
208
            if ($path = $fs->store($request->get('content'), $item->getGroupId(), $item->getId(), $number)) {
209
                $uploadSucceded = true;
210
211
                //TODO take mimetype once the file has been written ?
212
                $_filename = basename($path);
213
                $_filesize = filesize($path);
214
                $_filetype = 'text/html';
215
            }
216
            break;
217
        default:
218
            break;
219
        }
220
221
        if($uploadSucceded) {
222
            $userId = $user->getId();
223
            if ($request->exist('author') && ($request->get('author') != $userId)) {
224
                $versionAuthor = $request->get('author');
225
226
                $eArray = array('group_id'  => $item->getGroupId(),
227
                                'item'      => &$item,
228
                                'new_value' => $this->_getUserManagerInstance()->getUserById($versionAuthor)->getName(),
229
                                'user'      => &$user);
230
231
                $this->event_manager->processEvent('plugin_docman_event_set_version_author', $eArray);
232
            } else {
233
                $versionAuthor = $userId;
234
            }
235
236
            $date = '';
237
            if ($request->exist('date')) {
238
                $date = $request->get('date');
239
240
                $eArray = array('group_id'  => $item->getGroupId(),
241
                                'item'      => &$item,
242
                                'old_value' => null,
243
                                'new_value' => $date,
244
                                'user'      => &$user);
245
246
                $this->event_manager->processEvent('plugin_docman_event_set_version_date', $eArray);
247
            }
248
249
            $vArray = array('item_id'   => $item->getId(),
250
                            'number'    => $number,
251
                            'user_id'   => $versionAuthor,
252
                            'label'     => $_label,
253
                            'changelog' => $_changelog,
254
                            'filename'  => $_filename,
255
                            'filesize'  => $_filesize,
256
                            'filetype'  => $_filetype,
257
                            'path'      => $path,
258
                            'date'      => $date);
259
            $vId = $vFactory->create($vArray);
260
261
            // Create a new version object
262
            $vArray['id'] = $vId;
263
            $vArray['date'] = $_SERVER['REQUEST_TIME'];
264
            $newVersion = new Docman_Version($vArray);
265
266
            $eArray = array('group_id' => $item->getGroupId(),
267
                            'item'     => &$item,
268
                            'version'  => $newVersion,
269
                            'user'     => &$user);
270
            $this->event_manager->processEvent('plugin_docman_event_new_version', $eArray);
271
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_create_'.$_action_type));
272
273
            // Approval table
274
            if($number > 0) {
275
                // Approval table creation needs the item currentVersion to be set.
276
                $vArray['id']   = $vId;
277
                $vArray['date'] = $_SERVER['REQUEST_TIME'];
278
                $newVersion     = new Docman_Version($vArray);
279
                $item->setCurrentVersion($newVersion);
280
281
                $this->newVersionApprovalTable($request, $item, $user);
282
            }
283
        }
284
        else {
285
            //TODO What should we do if upload failed ?
286
            //Maybe cancel item ?
287
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_create_'.$_action_type));
288
        }
289
        return $newVersion;
290
    }
291
292
    private function newVersionApprovalTable(Codendi_Request $request, Docman_Item $item, PFUser $user) {
293
        $vImport = new Valid_WhiteList('app_table_import', array('copy', 'reset', 'empty'));
294
        $vImport->required();
295
        $import = $request->getValidated('app_table_import', $vImport, false);
296
        if ($import) {
297
            $atf = Docman_ApprovalTableFactoriesFactory::getFromItem($item);
298
            $atf->createTable($user->getId(), $request->get('app_table_import'));
299
        }
300
    }
301
302
    function createFolder() {
303
        $this->createItem();
304
    }
305
306
    function createDocument() {
307
        $this->createItem();
308
    }
309
310
    function createItem() {
311
        $request =& $this->_controler->request;
312
        $item_factory =& $this->_getItemFactory();
313
        if ($request->exist('item')) {
314
            $item = $request->get('item');
315
316
            if (isset($item['title'])) {
317
                $item['title'] = trim($item['title']);
318
            }
319
320
            $fs =& $this->_getFileStorage();
321
            if (
322
                    $item['item_type'] != PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE
323
                    ||
324
                    (
325
                        $this->_controler->getProperty('embedded_are_allowed')
326
                        &&
327
                        $request->exist('content')
328
                    )
329
                )
330
            {
331
332
                // Special handling of obsolescence date
333
                if(isset($item['obsolescence_date']) && $item['obsolescence_date'] != 0) {
334
                    if (preg_match('/^([0-9]+)-([0-9]+)-([0-9]+)$/', $item['obsolescence_date'], $d)) {
335
                        $item['obsolescence_date'] = mktime(0, 0, 0, $d[2], $d[3], $d[1]);
336
                    } else if (!preg_match('/^[0-9]*$/', $item['obsolescence_date'])) {
337
                        $item['obsolescence_date'] = 0;
338
                    }
339
                } else {
340
                    $item['obsolescence_date'] = 0;
341
                }
342
343
                $user =& $this->_controler->getUser();
344
345
                // Change owner
346
                $userId = $user->getId();
347
                if (isset($item['owner'])) {
348
                    $um = $this->_getUserManagerInstance();
349
                    $new_owner = $um->getUserByUserName($item['owner']);
350
                    if ($new_owner !== null) {
351
                        $owner = $new_owner->getId();
352
                    } else {
353
                        $owner = $userId;
354
                    }
355
                } else {
356
                    $owner = $userId;
357
                }
358
                $item['user_id'] = $owner;
359
360
                // Change creation date
361
                if (isset($item['create_date']) && $item['create_date'] != '') {
362
                    $create_date_changed = true;
363
                } else {
364
                    $create_date_changed = false;
365
                }
366
367
                // Change update date
368
                if (isset($item['update_date']) && $item['update_date'] != '') {
369
                    $update_date_changed = true;
370
                } else {
371
                    $update_date_changed = false;
372
                }
373
374
                $item['group_id'] = $request->get('group_id');
375
                $id = $item_factory->create($item, $request->get('ordering'));
376
                if ($id) {
377
                    $this->_controler->_viewParams['action_result'] = $id;
378
                    $this->_controler->_viewParams['redirect_anchor'] = "#item_$id";
379
                    $new_item = $item_factory->getItemFromDb($id);
380
                    $parent   = $item_factory->getItemFromDb($item['parent_id']);
381
                    if ($request->exist('permissions') && $this->_controler->userCanManage($parent->getId())) {
382
                        $force = true;
383
                        $this->setPermissionsOnItem($new_item, $force, $user);
0 ignored issues
show
Bug introduced by
It seems like $new_item defined by $item_factory->getItemFromDb($id) on line 379 can also be of type null; however, Docman_Actions::setPermissionsOnItem() does only seem to accept object<Docman_Item>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
384
                    } else {
385
                        $pm = $this->_getPermissionsManagerInstance();
386
                        $pm->clonePermissions($item['parent_id'], $id, array('PLUGIN_DOCMAN_READ', 'PLUGIN_DOCMAN_WRITE', 'PLUGIN_DOCMAN_MANAGE'));
387
                    }
388
                    $new_item->fireEvent('plugin_docman_event_add', $user, $parent);
389
390
                    // Log change owner
391
                    if ($owner != $userId) {
392
                        $this->_raiseMetadataChangeEvent($user, $new_item, $request->get('group_id'), null, $item['owner'], 'owner');
393
                    }
394
395
                    // Log change creation date
396
                    if ($create_date_changed) {
397
                        $this->_raiseMetadataChangeEvent($user, $new_item, $request->get('group_id'), null, $item['create_date'], 'create_date');
398
                    }
399
400
                    // Log change update date
401
                    if ($update_date_changed) {
402
                        $this->_raiseMetadataChangeEvent($user, $new_item, $request->get('group_id'), null, $item['update_date'], 'update_date');
403
                    }
404
405
                    $info_item_created = 'info_document_created';
406
                    if($item['item_type'] == PLUGIN_DOCMAN_ITEM_TYPE_FOLDER) {
407
                        $info_item_created = 'info_folder_created';
408
                    }
409
                    $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_document_created'));
410
411
                    $new_version = null;
412
                    if($item['item_type'] == PLUGIN_DOCMAN_ITEM_TYPE_FILE ||
413
                       $item['item_type'] == PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE) {
414
                        $new_version = $this->_storeFile($new_item);
415
                    }
416
417
                    if ($item['item_type'] ==  PLUGIN_DOCMAN_ITEM_TYPE_LINK) {
418
                        $link_version_factory = new Docman_LinkVersionFactory();
419
                        $link_version_factory->create(
420
                            $new_item,
421
                            $GLOBALS['Language']->getText('plugin_docman', 'initversion'),
422
                            $GLOBALS['Language']->getText('plugin_docman', 'initversion'),
423
                            $_SERVER['REQUEST_TIME']
424
                        );
425
                    }
426
427
                    // Create metatata
428
                    if($request->exist('metadata')) {
429
                        $metadata_array = $request->get('metadata');
430
                        $mdvFactory = new Docman_MetadataValueFactory($request->get('group_id'));
431
                        $mdvFactory->createFromRow($id, $metadata_array);
432
                        if($mdvFactory->isError()) {
433
                            $this->_controler->feedback->log('error', $mdvFactory->getErrorMessage());
434
                        }
435
                    }
436
437
                    //Submit News about this document
438
                    if ($request->exist('news')) {
439
                        if ($user->isMember($request->get('group_id'), 'A') || $user->isMember($request->get('group_id'), 'N1') || $user->isMember($request->get('group_id'), 'N2')) { //only for allowed people
440
                            $news = $request->get('news');
441
                            if (isset($news['summary']) && trim($news['summary']) && isset($news['details']) && trim($news['details']) && isset($news['is_private'])) {
442
                                news_submit($request->get('group_id'), $news['summary'], $news['details'], $news['is_private']);
0 ignored issues
show
Bug introduced by
The call to news_submit() misses a required argument $send_news_to.

This check looks for function calls that miss required arguments.

Loading history...
443
                                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_news_created'));
444
                            }
445
                        } else {
446
                            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_create_news'));
447
                        }
448
                    }
449
450
                    $folderFactory = $this->_getFolderFactory();
451
                    $folderFactory->expand($parent);
452
453
                    $item_type = $item_factory->getItemTypeForItem($new_item);
454
455
                    switch ($item_type) {
456
                        case PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE:
457
                        case PLUGIN_DOCMAN_ITEM_TYPE_FILE:
458
                            $this->event_manager->processEvent(
459
                                'plugin_docman_after_new_document',
460
                                array(
461
                                    'item'     => $new_item,
462
                                    'user'     => $user,
463
                                    'version'  => $new_version,
464
                                    'docmanControler' => $this->_controler
465
                                )
466
                            );
467
468
                            break;
469
470
                        case PLUGIN_DOCMAN_ITEM_TYPE_WIKI:
471
                            $this->event_manager->processEvent(
472
                                'plugin_docman_event_new_wikipage',
473
                                array(
474
                                    'item'      => $new_item,
475
                                    'group_id'  => $new_item->getGroupId(),
476
                                    'wiki_page' => $new_item->getPagename()
477
                                ));
478
479
                            break;
480
481
                        case PLUGIN_DOCMAN_ITEM_TYPE_EMPTY:
482
                            $this->event_manager->processEvent(
483
                                PLUGIN_DOCMAN_EVENT_NEW_EMPTY,
484
                                array(
485
                                    'item' => $new_item
486
                                )
487
                            );
488
489
                            break;
490
491
                        case PLUGIN_DOCMAN_ITEM_TYPE_LINK:
492
                            $this->event_manager->processEvent(
493
                                PLUGIN_DOCMAN_EVENT_NEW_LINK,
494
                                array(
495
                                    'item' => $new_item
496
                                )
497
                            );
498
499
                            break;
500
501
                        case PLUGIN_DOCMAN_ITEM_TYPE_FOLDER:
502
                            $this->event_manager->processEvent(
503
                                PLUGIN_DOCMAN_EVENT_NEW_FOLDER,
504
                                array(
505
                                    'item' => $new_item
506
                                )
507
                            );
508
509
                            break;
510
511
                        default:
512
                            break;
513
                    }
514
                }
515
            }
516
        }
517
        $this->event_manager->processEvent('send_notifications', array());
518
    }
519
520
    function update() {
521
        $request =& $this->_controler->request;
522
        if ($request->exist('item')) {
523
            $user =& $this->_controler->getUser();
524
525
            $data = $request->get('item');
526
527
            if (isset($data['title'])) {
528
                $data['title'] = trim($data['title']);
529
            }
530
531
            $item_factory =& $this->_getItemFactory($request->get('group_id'));
532
            $item =& $item_factory->getItemFromDb($data['id']);
533
534
            // Update Owner
535
            $ownerChanged = false;
536
            if(isset($data['owner'])) {
537
                $_owner_id = $this->_checkOwnerChange($data['owner'], $user);
538
                if($_owner_id != $item->getOwnerId()) {
539
                    $ownerChanged = true;
540
                    $um = $this->_getUserManagerInstance();
541
                    $_oldowner = $um->getUserById($item->getOwnerId())->getName();
542
                    $_newowner = $um->getUserById($_owner_id)->getName();
543
                    $data['user_id'] = $_owner_id;
544
                }
545
                unset($data['owner']);
546
            }
547
548
            // Change creation date
549
            if (isset($data['create_date']) && $data['create_date'] != '') {
550
                $old_create_date = $item->getCreateDate();
551
                if ($old_create_date == $data['create_date']) {
552
                    $create_date_changed = false;
553
                } else {
554
                    $create_date_changed = true;
555
                }
556
            } else {
557
                $create_date_changed = false;
558
            }
559
560
            // Change update date
561
            if (isset($data['update_date']) && $data['update_date'] != '') {
562
                $old_update_date = $item->getUpdateDate();
563
                if ($old_update_date == $data['update_date']) {
564
                    $update_date_changed = false;
565
                } else {
566
                    $update_date_changed = true;
567
                }
568
            } else {
569
                $update_date_changed = false;
570
            }
571
572
            // Special handling of obsolescence date
573
            if(isset($data['obsolescence_date']) && $data['obsolescence_date'] != 0) {
574
                if(preg_match('/^([0-9]+)-([0-9]+)-([0-9]+)$/', $data['obsolescence_date'], $d)) {
575
                    $data['obsolescence_date'] = gmmktime(0, 0, 0, $d[2], $d[3], $d[1]);
576
                } else if (!preg_match('/^[0-9]*$/', $data['obsolescence_date'])) {
577
                    $data['obsolescence_date'] = 0;
578
                }
579
            }
580
581
            // Check is status change
582
            $statusChanged = false;
583
            if(array_key_exists('status', $data)) {
584
                $old_st = $item->getStatus();
585
                if($old_st != $data['status']) {
586
                    $statusChanged = true;
587
                }
588
            }
589
590
            // For empty document, check if type changed
591
            $createFile = false;
592
            $itemType = $item_factory->getItemTypeForItem($item);
593
594
            if($itemType == PLUGIN_DOCMAN_ITEM_TYPE_EMPTY && isset($data['item_type']) && $itemType != $data['item_type'] &&
595
                ($data['item_type'] != PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE || $this->_controler->getProperty('embedded_are_allowed'))) {
596
597
                if($data['item_type'] == PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE
598
                   || $data['item_type'] == PLUGIN_DOCMAN_ITEM_TYPE_FILE) {
599
                    $createFile = true;
600
                }
601
            }
602
            else {
603
                $data['item_type'] =  $itemType;
604
            }
605
606
            $updated = $item_factory->update($data);
607
            if ($updated) {
608
                $this->event_manager->processEvent('plugin_docman_event_update', array(
609
                    'group_id' => $request->get('group_id'),
610
                    'item'     => $item,
611
                    'new'      => $data,
612
                    'user'     => $user)
613
                );
614
            }
615
616
            // Log the 'edit' event if link_url or wiki_page are set
617
            if (isset($data['link_url']) || isset($data['wiki_page'])) {
618
                $this->event_manager->processEvent('plugin_docman_event_edit', array(
619
                    'group_id' => $request->get('group_id'),
620
                    'item'     => &$item,
621
                    'user'     => &$user)
622
                );
623
            }
624
625
            if($ownerChanged) {
626
                $this->_raiseMetadataChangeEvent($user, $item, $request->get('group_id'), $_oldowner, $_newowner, 'owner');
627
            }
628
629
            if($statusChanged) {
630
               $this->_raiseMetadataChangeEvent($user, $item, $request->get('group_id'), $old_st, $data['status'], 'status');
631
            }
632
633
            if($create_date_changed) {
634
                $this->_raiseMetadataChangeEvent($user, $item, $request->get('group_id'), $old_create_date, $data['create_date'], 'create_date');
635
            }
636
637
            if($update_date_changed) {
638
                $this->_raiseMetadataChangeEvent($user, $item, $request->get('group_id'), $old_update_date, $data['update_date'], 'update_date');
639
            }
640
641
            if($createFile) {
642
                // Re-create from DB (because of type changed)
643
                $item = $item_factory->getItemFromDb($data['id']);
644
                $this->_storeFile($item);
645
            }
646
647
            // Update real metatata
648
            if($request->exist('metadata')) {
649
                $groupId = (int) $request->get('group_id');
650
                $metadata_array = $request->get('metadata');
651
                $mdvFactory = new Docman_MetadataValueFactory($groupId);
652
                $mdvFactory->updateFromRow($data['id'], $metadata_array);
653
                if($mdvFactory->isError()) {
654
                    $this->_controler->feedback->log('error', $mdvFactory->getErrorMessage());
655
                } else {
656
                    // Recursive update of properties
657
                    if($request->exist('recurse')) {
658
                        $recurseArray = $request->get('recurse');
659
660
                        // Check if all are actually inheritable
661
                        $metadataFactory = new Docman_MetadataFactory($groupId);
662
                        $inheritableMdLabelArray = $metadataFactory->getInheritableMdLabelArray();
663
                        if(count(array_diff($recurseArray, $inheritableMdLabelArray)) == 0) {
664
                            $dPm =& Docman_PermissionsManager::instance($groupId);
665
                            if($dPm->currentUserCanWriteSubItems($data['id'])) {
666
                                $subItemsWritableVisitor =& $dPm->getSubItemsWritableVisitor();
667
                                if($this->_controler->_actionParams['recurseOnDocs']) {
668
                                    $itemIdArray = $subItemsWritableVisitor->getItemIdList();
669
                                } else {
670
                                    $itemIdArray = $subItemsWritableVisitor->getFolderIdList();
671
                                }
672
                                // Remove the first element (parent item) to keep
673
                                // only the children.
674
                                array_shift($itemIdArray);
675
                                if(count($itemIdArray) > 0) {
676
                                    $recurseArray = $request->get('recurse');
677
                                    $mdvFactory->massUpdateFromRow($data['id'], $recurseArray, $itemIdArray);
678
                                    // extract cross references
679
                                    $reference_manager =& ReferenceManager::instance();
680
                                    foreach ($metadata_array as $curr_metadata_value) {
681
                                        foreach ($itemIdArray as $curr_item_id) {
682
                                            $reference_manager->extractCrossRef($curr_metadata_value, $curr_item_id, ReferenceManager::REFERENCE_NATURE_DOCUMENT, $groupId);
683
                                        }
684
                                    }
685
                                } else {
686
                                    $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'warning_no_item_recurse'));
687
                                }
688
                            }
689
                        }
690
                    }
691
                }
692
            }
693
694
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_item_updated'));
695
        }
696
        $this->event_manager->processEvent('send_notifications', array());
697
    }
698
699
    function new_version() {
700
        $request =& $this->_controler->request;
701
        if ($request->exist('id')) {
702
            $user         = $this->_controler->getUser();
703
            $item_factory = $this->_getItemFactory();
704
            $item         = $item_factory->getItemFromDb($request->get('id'));
705
            $item_type    = $item_factory->getItemTypeForItem($item);
706
            if ($item_type == PLUGIN_DOCMAN_ITEM_TYPE_FILE || $item_type == PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE) {
707
                $new_version =& $this->_storeFile($item);
708
709
                // We update the update_date of the document only if no version date was given
710
                if (! $request->existAndNonEmpty('date')) {
711
                    $item_factory->update(array('id' => $item->getId()));
712
                }
713
714
                $this->manageLockNewVersion($user, $item, $request);
715
            } elseif ($item_type == PLUGIN_DOCMAN_ITEM_TYPE_LINK) {
716
                $this->updateLink($request, $item, $user);
717
            }
718
        }
719
        $this->event_manager->processEvent('send_notifications', array());
720
    }
721
722
    private function updateLink(Codendi_Request $request, Docman_Link $item, PFUser $user) {
723
        $data = $request->get('item');
724
        $item->setUrl($data['link_url']);
725
        $updated = $this->_getItemFactory()->updateLink($item, $request->get('version'));
726
727
        $this->manageLockNewVersion($user, $item, $request);
728
729
        // Approval table
730
        $link_version_factory = new Docman_LinkVersionFactory();
731
        $last_version = $link_version_factory->getLatestVersion($item);
732
        if($last_version) {
733
            // Approval table creation needs the item currentVersion to be set.
734
            $item->setCurrentVersion($last_version);
735
            $this->newVersionApprovalTable($request, $item, $user);
736
        }
737
738
        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_create_newversion'));
739
740
        $event_data = array(
741
            'item'     => $item,
742
            'version'  => $last_version,
743
        );
744
        $this->event_manager->processEvent(PLUGIN_DOCMAN_EVENT_NEW_LINKVERSION, $event_data);
745
746
        return $updated;
747
    }
748
749
    private function manageLockNewVersion(PFUser $user, Docman_Item $item, Codendi_Request $request) {
750
        $permission_manager = $this->_getDocmanPermissionsManagerInstance($item->getGroupId());
751
        if ($request->existAndNonEmpty('lock_document')) {
752
            if (! $permission_manager->getLockFactory()->itemIsLocked($item)) {
753
                $permission_manager->getLockFactory()->lock($item);
0 ignored issues
show
Bug introduced by
The call to lock() misses a required argument $user.

This check looks for function calls that miss required arguments.

Loading history...
754
                $this->_raiseLockEvent($item, $user);
755
            }
756
        } else {
757
            if ($permission_manager->getLockFactory()->itemIsLocked($item)) {
758
                $permission_manager->getLockFactory()->unlock($item);
759
                $this->_raiseUnlockEvent($item, $user);
760
            }
761
        }
762
    }
763
764
    protected $filestorage;
765
    function &_getFileStorage() {
766
        if (!$this->filestorage) {
767
            $this->filestorage =& new Docman_FileStorage($this->_controler->getProperty('docman_root'));
768
        }
769
        return $this->filestorage;
770
    }
771
772
    function _getItemFactory($groupId=null) {
773
        return new Docman_ItemFactory($groupId);
774
    }
775
776
    function _getFolderFactory($groupId=null) {
777
        return new Docman_FolderFactory($groupId);
778
    }
779
780
    protected $version_factory;
781
    function &_getVersionFactory() {
782
        if (!$this->version_factory) {
783
            $this->version_factory =& new Docman_VersionFactory();
784
        }
785
        return $this->version_factory;
786
    }
787
    protected $permissions_manager;
788
    function &_getPermissionsManagerInstance(){
789
        if(!$this->permissions_manager){
790
            $this->permissions_manager =& PermissionsManager::instance();
791
        }
792
        return $this->permissions_manager;
793
    }
794
795
    function _getDocmanPermissionsManagerInstance($groupId) {
796
        return Docman_PermissionsManager::instance($groupId);
797
    }
798
799
    protected $userManager;
800
    function _getUserManagerInstance(){
801
        if(!$this->userManager){
802
            $this->userManager = UserManager::instance();
803
        }
804
        return $this->userManager;
805
    }
806
807
    /**
808
     * Perform paste operation after cut
809
     *
810
     * @param Docman_Item   $itemToMove    Item to move
811
     * @param Docman_Folder $newParentItem New parent item
812
     * @param PFUser          $user          User who perform the paste
813
     * @param String        $ordering      Where the item should be paste within the new folder
814
     *
815
     * @return void
816
     */
817
    protected function _doCutPaste($itemToMove, $newParentItem, $user, $ordering) {
818
        if ($itemToMove && $newParentItem && $newParentItem->getId() != $itemToMove->getId()) {
819
            $item_factory = $this->_getItemFactory();
820
            $old_parent   = $item_factory->getItemFromDb($itemToMove->getParentId());
821
            if ($item_factory->setNewParent($itemToMove->getId(), $newParentItem->getId(), $ordering)) {
822
                $itemToMove->fireEvent('plugin_docman_event_move', $user, $newParentItem);
823
                $hp = Codendi_HTMLPurifier::instance();
824
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_item_moved', array(
825
                            $itemToMove->getGroupId(),
826
                            $old_parent->getId(),
827
                            $hp->purify($old_parent->getTitle(), CODENDI_PURIFIER_CONVERT_HTML) ,
828
                            $newParentItem->getId(),
829
                            $hp->purify($newParentItem->getTitle(), CODENDI_PURIFIER_CONVERT_HTML)
830
                            )
831
                        ),
832
                    CODENDI_PURIFIER_DISABLED);
833
                    $item_factory->delCopyPreference();
834
                    $item_factory->delCutPreference();
835
            } else {
836
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_item_not_moved'));
837
            }
838
        }
839
    }
840
841
    /**
842
     * Perform paste operation after a copy
843
     *
844
     * @param Docman_Item   $itemToPaste   Item to paste
845
     * @param Docman_Folder $newParentItem New parent item
846
     * @param PFUser          $user          User who perform the paste
847
     * @param String        $ordering      Where the item should be paste within the new folder
848
     * @param Boolean       $importMd      Do we need to import metadata from another project
849
     * @param String        $dataRoot      Where the docman data stand on hard drive
850
     *
851
     * @return void
852
     */
853
    protected function _doCopyPaste($itemToPaste, $newParentItem, $user, $ordering, $importMd, $dataRoot) {
854
        $srcMdFactory = new Docman_MetadataFactory($itemToPaste->getGroupId());
855
856
        // Import metadata if asked
857
        if($importMd) {
858
            $srcMdFactory->exportMetadata($newParentItem->getGroupId());
859
        }
860
861
        // Get mapping between the 2 definitions
862
        $mdMapping = array();
863
        $srcMdFactory->getMetadataMapping($newParentItem->getGroupId(), $mdMapping);
864
865
        // Permissions
866
        if($itemToPaste->getGroupId() != $newParentItem->getGroupId()) {
867
            $ugroupsMapping = false;
868
        } else {
869
            $ugroupsMapping = true;
870
        }
871
872
        //
873
        // Action
874
        $itemFactory  = $this->_getItemFactory();
875
        $item_mapping = $itemFactory->cloneItems($itemToPaste->getGroupId(),
876
            $newParentItem->getGroupId(),
877
            $user,
878
            $mdMapping,
879
            $ugroupsMapping,
880
            $dataRoot,
881
            $itemToPaste->getId(),
882
            $newParentItem->getId(),
883
            $ordering);
884
885
886
        $event_manager = EventManager::instance();
887
        $event_manager->processEvent(PLUGIN_DOCMAN_EVENT_COPY, array(
888
            'item' => $itemFactory->getItemFromDb($item_mapping[$itemToPaste->getId()])
889
        ));
890
891
        $itemFactory->delCopyPreference();
892
        $itemFactory->delCutPreference();
893
    }
894
895
    function move() {
896
        $request =& $this->_controler->request;
897
        if ($request->exist('id')) {
898
            $item_factory =& $this->_getItemFactory();
899
            //Move in a specific folder (maybe the same)
900
            if ($request->exist('item_to_move')) {
901
                $item          =& $item_factory->getItemFromDb($request->get('item_to_move'));
902
                $new_parent_id = $request->get('id');
903
                $ordering      = $request->get('ordering');
904
            } else {
905
                //Move in the same folder
906
                if ($request->exist('quick_move')) {
907
                    $item          =& $item_factory->getItemFromDb($request->get('id'));
908
                    $new_parent_id = $item->getParentId();
909
                    switch($request->get('quick_move')) {
910
                        case 'move-up':
911
                        case 'move-down':
912
                        case 'move-beginning':
913
                        case 'move-end':
914
                            $ordering = substr($request->get('quick_move'), 5);
915
                            break;
916
                        default:
917
                            $ordering = 'beginning';
918
                            break;
919
                    }
920
                }
921
            }
922
            $newParentItem = $item_factory->getItemFromDb($new_parent_id);
923
            $user          = $this->_controler->getUser();
924
            $this->_doCutPaste($item, $newParentItem, $user, $ordering);
0 ignored issues
show
Bug introduced by
It seems like $item can also be of type null; however, Docman_Actions::_doCutPaste() does only seem to accept object<Docman_Item>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
It seems like $newParentItem defined by $item_factory->getItemFromDb($new_parent_id) on line 922 can also be of type null or object<Docman_Empty> or object<Docman_File> or object<Docman_Link> or object<Docman_Wiki>; however, Docman_Actions::_doCutPaste() does only seem to accept object<Docman_Folder>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
925
        }
926
        $this->event_manager->processEvent('send_notifications', array());
927
    }
928
929
    function action_cut($params) {
930
        //
931
        // Param
932
        $user = $this->_controler->getUser();
933
        $item = $this->_controler->_actionParams['item'];
934
        $hp   = Codendi_HTMLPurifier::instance();
935
936
        //
937
        // Action
938
        $itemFactory =& $this->_getItemFactory();
939
940
        $itemFactory->delCopyPreference();
941
        $itemFactory->delCutPreference();
942
        $itemFactory->setCutPreference($item);
943
944
        //
945
        // Message
946
        $this->_controler->feedback->log('info', $hp->purify($item->getTitle()).' '.$GLOBALS['Language']->getText('plugin_docman', 'info_cut_notify_cut'));
947
    }
948
949
    function action_copy($params) {
950
        //
951
        // Param
952
        $user = $this->_controler->getUser();
953
        $item = $this->_controler->_actionParams['item'];
954
        $hp   = Codendi_HTMLPurifier::instance();
955
956
        //
957
        // Action
958
        $itemFactory =& $this->_getItemFactory();
959
960
        $itemFactory->delCopyPreference();
961
        $itemFactory->delCutPreference();
962
        $itemFactory->setCopyPreference($item);
963
964
        //
965
        // Message
966
        $msg = $hp->purify($item->getTitle()).' '.$GLOBALS['Language']->getText('plugin_docman', 'info_copy_notify_cp');
967
        $this->_controler->feedback->log('info', $msg, CODENDI_PURIFIER_DISABLED);
968
    }
969
970
    /**
971
     * Perform paste action (after a copy or a cut)
972
     *
973
     * @param Docman_Item $itemToPaste
974
     * @param Docman_Item $newParentItem
975
     * @param String      $rank
976
     * @param Boolean     $importMd
977
     * @param String      $srcMode
978
     *
979
     * @return void
980
     */
981
	function doPaste($itemToPaste, $newParentItem, $rank, $importMd, $srcMode) {
982
		$user      = $this->_controler->getUser();
983
	    $mdMapping = false;
984
	    switch ($srcMode) {
985
	        case 'copy':
986
				$dataRoot = $this->_controler->getProperty('docman_root');
987
	            $this->_doCopyPaste($itemToPaste, $newParentItem, $user, $rank, $importMd, $dataRoot);
0 ignored issues
show
Compatibility introduced by
$newParentItem of type object<Docman_Item> is not a sub-type of object<Docman_Folder>. It seems like you assume a child class of the class Docman_Item to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
988
	            break;
989
990
	        case 'cut':
991
	            $this->_doCutPaste($itemToPaste, $newParentItem, $user, $rank);
0 ignored issues
show
Compatibility introduced by
$newParentItem of type object<Docman_Item> is not a sub-type of object<Docman_Folder>. It seems like you assume a child class of the class Docman_Item to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
992
	            break;
993
	    }
994
	    $this->event_manager->processEvent('send_notifications', array());
995
	}
996
997
    function paste($params) {
998
		$this->doPaste($this->_controler->_actionParams['itemToPaste'],
999
					   $this->_controler->_actionParams['item'],
1000
					   $this->_controler->_actionParams['rank'],
1001
					   $this->_controler->_actionParams['importMd'],
1002
                       $this->_controler->_actionParams['srcMode']);
1003
    }
1004
1005
    function _get_definition_index_for_permission($p) {
1006
        switch ($p) {
1007
            case 'PLUGIN_DOCMAN_READ':
1008
                return 1;
1009
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1010
            case 'PLUGIN_DOCMAN_WRITE':
1011
                return 2;
1012
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1013
            case 'PLUGIN_DOCMAN_MANAGE':
1014
                return 3;
1015
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1016
            default:
1017
                return 100;
1018
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1019
        }
1020
    }
1021
1022
    /**
1023
    * User has asked to set or to change permissions on an item
1024
    * This method is the direct action of the docman controler
1025
    *
1026
    * To call it directly, you have to give two extra parameters (in $params):
1027
    * - id : the id of the item
1028
    * - force : true if you want to bypass permissions checking (@see permission_add_ugroup).
1029
    *           Pretty difficult to know if a user can update the permissions which does not exist for a new item...
1030
    *
1031
    * The asked permissions are given in the request, in the param 'permissions' as an array (ugroup => permission)
1032
    *
1033
    * Once the permissions on the top item are set (thanks to
1034
    * Docman_Actions::_setPermissions) we can assume that those permissions are
1035
    * correct so the algorithm to apply them recursively is just a clone. This
1036
    * is done thanks to a callback.
1037
    *
1038
    * Docman_ItemFactory::breathFirst allows to navigate in children of
1039
    * top item. And for each child node, there is a callback to
1040
    * Docman_Actions::recursivePermission (see each method for details).
1041
    */
1042
    public function permissions($params) {
1043
        $id    = isset($params['id'])    ? $params['id']    : $this->_controler->request->get('id');
1044
        $force = isset($params['force']) ? $params['force'] : false;
1045
        if ($id && $this->_controler->request->exist('permissions')) {
1046
            $user =& $this->_controler->getUser();
1047
            $item =& $this->_getItemFactory()->getItemFromDb($id);
1048
            $this->setPermissionsOnItem($item, $force, $user);
0 ignored issues
show
Bug introduced by
It seems like $item defined by $this->_getItemFactory()->getItemFromDb($id) on line 1047 can also be of type null; however, Docman_Actions::setPermissionsOnItem() does only seem to accept object<Docman_Item>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1049
            $this->event_manager->processEvent(
1050
                'plugin_docman_event_perms_change',
1051
                array(
1052
                    'group_id' => $item->getGroupId(),
1053
                    'item'     => $item,
1054
                    'user'     => $user,
1055
                )
1056
            );
1057
        }
1058
    }
1059
1060
    /**
1061
     * @param Docman_Item  $item  The id of the item
1062
     * @param bool         $force true if you want to bypass permissions checking (@see permission_add_ugroup)
1063
     * @param PFUser         $user  The current user
1064
     */
1065
    private function setPermissionsOnItem(Docman_Item $item, $force, PFUser $user) {
1066
        $permission_definition = array(
1067
            100 => array(
1068
                'order' => 0,
1069
                'type'  => null,
1070
                'label' => null,
1071
                'previous' => null
1072
            ),
1073
            1 => array(
1074
                'order' => 1,
1075
                'type'  => 'PLUGIN_DOCMAN_READ',
1076
                'label' => permission_get_name('PLUGIN_DOCMAN_READ'),
1077
                'previous' => 0
1078
            ),
1079
            2 => array(
1080
                'order' => 2,
1081
                'type'  => 'PLUGIN_DOCMAN_WRITE',
1082
                'label' => permission_get_name('PLUGIN_DOCMAN_WRITE'),
1083
                'previous' => 1
1084
            ),
1085
            3 => array(
1086
                'order' => 3,
1087
                'type'  => 'PLUGIN_DOCMAN_MANAGE',
1088
                'label' => permission_get_name('PLUGIN_DOCMAN_MANAGE'),
1089
                'previous' => 2
1090
            )
1091
        );
1092
        $permissions = $this->_controler->request->get('permissions');
1093
        $old_permissions = permission_get_ugroups_permissions($item->getGroupId(), $item->getId(), array('PLUGIN_DOCMAN_READ','PLUGIN_DOCMAN_WRITE','PLUGIN_DOCMAN_MANAGE'), false);
1094
        $done_permissions = array();
1095
        $history = array(
1096
            'PLUGIN_DOCMAN_READ'  => false,
1097
            'PLUGIN_DOCMAN_WRITE' => false,
1098
            'PLUGIN_DOCMAN_MANAGE' => false
1099
        );
1100
        foreach($permissions as $ugroup_id => $wanted_permission) {
1101
            $this->_setPermission($item->getGroupId(), $item->getId(), $permission_definition, $old_permissions, $done_permissions, $ugroup_id, $permissions, $history, $force);
1102
        }
1103
1104
        $updated = false;
1105
        foreach($history as $perm => $put_in_history) {
1106
            if ($put_in_history) {
1107
                permission_add_history($item->getGroupId(), $perm, $item->getId());
1108
                $updated = true;
1109
            }
1110
        }
1111
1112
        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_perms_updated'));
1113
1114
        // If requested by user, apply permissions recursively on sub items
1115
        if ($this->_controler->request->get('recursive')) {
1116
            //clone permissions for sub items
1117
            // Recursive application via a callback of Docman_Actions::recursivePermissions in
1118
            // Docman_ItemFactory::breathFirst
1119
            $item_factory = $this->_getItemFactory();
1120
            $item_factory->breathFirst($item->getId(), array(&$this, 'recursivePermissions'), array('id' => $item->getId()));
1121
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_perms_recursive_updated'));
1122
        }
1123
    }
1124
1125
    /**
1126
     * Apply permissions of the reference item on the target item.
1127
     *
1128
     * This method is used as a callback by Docman_ItemFactory::breathFirst. It
1129
     * aims to clone the permissions set on the reference item ($params['id'])
1130
     * on a given item ($data['item_id']).
1131
     *
1132
     * Current user must have 'manage' permissions on the item to update its permissions.
1133
     *
1134
     * @see Docman_ItemFactory::breathFirst
1135
     *
1136
     * $params['id']    Reference item id.
1137
     * $data['item_id'] Item id on which permissions applies.
1138
     */
1139
    function recursivePermissions($data, $params) {
1140
        if ($this->_controler->userCanManage($data["item_id"])) {
1141
            $pm =& $this->_getPermissionsManagerInstance();
1142
            $pm->clonePermissions($params['id'], $data["item_id"], array('PLUGIN_DOCMAN_READ', 'PLUGIN_DOCMAN_WRITE', 'PLUGIN_DOCMAN_MANAGE'));
1143
        } else {
1144
            $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'warning_recursive_perms', $data['title']));
1145
        }
1146
    }
1147
1148
    /**
1149
    * Set the permission for a ugroup on an item.
1150
    *
1151
    * The difficult part of the algorithm comes from two point:
1152
    * - There is a hierarchy between ugroups (@see ugroup_get_parent)
1153
    * - There is a hierarchy between permissions (READ < WRITE < MANAGE)
1154
    *
1155
    * Let's see a scenario:
1156
    * I've selected WRITE permission for Registered users and READ permission for Project Members
1157
    * => Project Members ARE registered users therefore they have WRITE permission.
1158
    * => WRITE is stronger than READ permission.
1159
    * So the permissions wich will be set are: WRITE for registered and WRITE for project members
1160
    *
1161
    * The force parameter must be set to true if you want to bypass permissions checking (@see permission_add_ugroup).
1162
    * Pretty difficult to know if a user can update the permissions which does not exist for a new item...
1163
    *
1164
    * @param $group_id integer The id of the project
1165
    * @param $item_id integer The id of the item
1166
    * @param $permission_definition array The definission of the permission (pretty name, relations between perms, internal name, ...)
1167
    * @param $old_permissions array The permissions before
1168
    * @param &$done_permissions array The permissions after
1169
    * @param $ugroup_id The ugroup_id we want to set permission now
1170
    * @param $wanted_permissions array The permissions the user has asked
1171
    * @param &$history array Does a permission has been set ?
1172
    * @param $force boolean true if you want to bypass permissions checking (@see permission_add_ugroup).
1173
    *
1174
    * @access protected
1175
    */
1176
    function _setPermission($group_id, $item_id, $permission_definition, $old_permissions, &$done_permissions, $ugroup_id, $wanted_permissions, &$history, $force = false) {
1177
        //Do nothing if we have already choose a permission for ugroup
1178
        if (!isset($done_permissions[$ugroup_id])) {
1179
1180
            //if the ugroup has a parent
1181
            if (($parent = ugroup_get_parent($ugroup_id)) !== false) {
1182
1183
                //first choose the permission for the parent
1184
                $this->_setPermission($group_id, $item_id, $permission_definition, $old_permissions, $done_permissions, $parent, $wanted_permissions, $history, $force);
1185
1186
                //is there a conflict between given permissions?
1187
                if ($parent = $this->_getBiggerOrEqualParent($permission_definition, $done_permissions, $parent, $wanted_permissions[$ugroup_id])) {
1188
1189
                    //warn the user that there was a conflict
1190
                    $this->_controler->feedback->log(
1191
                        'warning',
1192
                        $GLOBALS['Language']->getText(
1193
                            'plugin_docman',
1194
                            'warning_perms',
1195
                            array(
1196
                                $old_permissions[$ugroup_id]['ugroup']['name'],
1197
                                $old_permissions[$parent]['ugroup']['name'],
1198
                                $permission_definition[$done_permissions[$parent]]['label']
1199
                            )
1200
                        )
1201
                    );
1202
1203
                    //remove permissions which was set for the ugroup
1204
                    if (count($old_permissions[$ugroup_id]['permissions'])) {
1205
                        foreach($old_permissions[$ugroup_id]['permissions'] as $permission => $nop) {
1206
                            permission_clear_ugroup_object($group_id, $permission, $ugroup_id, $item_id);
1207
                            $history[$permission] = true;
1208
                        }
1209
                    }
1210
1211
                    //The permission is none (default) for this ugroup
1212
                    $done_permissions[$ugroup_id] = 100;
1213
                }
1214
            }
1215
1216
            //If the permissions have not been set (no parent || no conflict)
1217
            if (!isset($done_permissions[$ugroup_id])) {
1218
1219
                //remove permissions if needed
1220
                $perms_cleared = false;
1221
                if (count($old_permissions[$ugroup_id]['permissions'])) {
1222
                    foreach($old_permissions[$ugroup_id]['permissions'] as $permission => $nop) {
1223
                        if ($permission != $permission_definition[$wanted_permissions[$ugroup_id]]['type']) {
1224
                            //The permission has been changed
1225
                            permission_clear_ugroup_object($group_id, $permission, $ugroup_id, $item_id);
1226
                            $history[$permission] = true;
1227
                            $perms_cleared = true;
1228
                            $done_permissions[$ugroup_id] = 100;
1229
                        } else {
1230
                            //keep the old permission
1231
                            $done_permissions[$ugroup_id] = Docman_PermissionsManager::getDefinitionIndexForPermission($permission);
1232
                        }
1233
                    }
1234
                }
1235
1236
                //If the user set an explicit permission and there was no perms before or they have been removed
1237
                if ($wanted_permissions[$ugroup_id] != 100 && (!count($old_permissions[$ugroup_id]['permissions']) || $perms_cleared)){
1238
                    //Then give the permission
1239
                    $permission = $permission_definition[$wanted_permissions[$ugroup_id]]['type'];
1240
                    permission_add_ugroup($group_id, $permission, $item_id, $ugroup_id, $force);
1241
1242
                    $history[$permission] = true;
1243
                    $done_permissions[$ugroup_id] = $wanted_permissions[$ugroup_id];
1244
                } else {
1245
                    //else set none(default) permission
1246
                    $done_permissions[$ugroup_id] = 100;
1247
                }
1248
            }
1249
        }
1250
    }
1251
1252
    /**
1253
    * Return the parent (or grand parent) of ugroup $parent which has a bigger permission
1254
    * @return integer the ugroup id which has been found or false
1255
    */
1256
    function _getBiggerOrEqualParent($permission_definition, $done_permissions, $parent, $wanted_permission) {
1257
        //No need to search for parent if the wanted permission is the default one
1258
        if ($wanted_permission == 100) {
1259
            return false;
1260
        } else {
1261
            //If the parent permission is bigger than the wanted permission
1262
            if ($permission_definition[$done_permissions[$parent]]['order'] >= $permission_definition[$wanted_permission]['order']) {
1263
                //then return parent
1264
                return $parent;
1265
            } else {
1266
                //else compare with grand parents (recursively)
1267
                if (($parent = ugroup_get_parent($parent)) !== false) {
1268
                    return $this->_getBiggerOrEqualParent($permission_definition, $done_permissions, $parent, $wanted_permission);
1269
                } else {
1270
                    return false;
1271
                }
1272
            }
1273
        }
1274
    }
1275
1276
    function change_view() {
1277
        $request =& HTTPRequest::instance();
1278
        $group_id = (int) $request->get('group_id');
1279
        if ($request->exist('selected_view')) {
1280
            if(is_numeric($request->get('selected_view'))) {
1281
                $this->_controler->setReportId($request->get('selected_view'));
1282
                $this->_controler->forceView('Table');
1283
            } else if (is_array($request->get('selected_view')) && count($request->get('selected_view'))) {
1284
                list($selected_view,) = each($request->get('selected_view'));
0 ignored issues
show
Bug introduced by
$request->get('selected_view') cannot be passed to each() as the parameter $array expects a reference.
Loading history...
1285
                if (Docman_View_Browse::isViewAllowed($selected_view)) {
1286
                    $item_factory =& $this->_getItemFactory();
1287
                    $folder = $item_factory->getItemFromDb($request->get('id'));
1288
                    if ($folder) {
1289
                        user_set_preference(
1290
                            PLUGIN_DOCMAN_VIEW_PREF .'_'. $folder->getGroupId(),
1291
                            $selected_view
1292
                        );
1293
                        $this->_controler->forceView($selected_view);
1294
                    }
1295
                }
1296
            }
1297
        }
1298
    }
1299
1300
    function delete() {
1301
        $user =& $this->_controler->getUser();
1302
        $request =& $this->_controler->request;
1303
1304
        $_sGroupId = (int) $request->get('group_id');
1305
        $_sId      = (int) $request->get('id');
1306
1307
        if($request->exist('cascadeWikiPageDeletion') && $request->get('cascadeWikiPageDeletion') == 'on'){
1308
            $cascade = true;
1309
        } else {
1310
            $cascade = false;
1311
        }
1312
1313
        $itemFactory = new Docman_ItemFactory($_sGroupId);
1314
        $parentItem = $itemFactory->getItemFromDb($_sId);
1315
        try {
1316
            if ($itemFactory->deleteSubTree($parentItem, $user, $cascade)) {
0 ignored issues
show
Bug introduced by
It seems like $parentItem defined by $itemFactory->getItemFromDb($_sId) on line 1314 can also be of type null; however, Docman_ItemFactory::deleteSubTree() does only seem to accept object<Docman_Item>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1317
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_item_deleted'));
1318
            }
1319
        } catch (Exception $e) {
1320
            $this->_controler->feedback->log('error', $e->getMessage());
1321
        }
1322
        $this->event_manager->processEvent('send_notifications', array());
1323
    }
1324
1325
    function deleteVersion() {
1326
        $request =& $this->_controler->request;
1327
1328
        $_sGroupId = (int) $request->get('group_id');
1329
        $_sId      = (int) $request->get('id');
1330
        $vVersion  = new Valid_UInt('version');
1331
        $vVersion->required();
1332
        if ($request->valid($vVersion)) {
1333
            $_sVersion = $request->get('version');
1334
        } else {
1335
            $_sVersion = false;
1336
        }
1337
1338
        $itemFactory = $this->_getItemFactory($_sGroupId);
1339
        $item        = $itemFactory->getItemFromDb($_sId);
1340
        if ($item) {
1341
            $type = $itemFactory->getItemTypeForItem($item);
1342
            if ($type == PLUGIN_DOCMAN_ITEM_TYPE_FILE || $type == PLUGIN_DOCMAN_ITEM_TYPE_EMBEDDEDFILE) {
1343
                $versions = $this->_getVersionFactory()->getAllVersionForItem($item);
1344
                if (count($versions) > 1) {
1345
                    $version = false;
1346
                    foreach ($versions as $v) {
1347
                        if ($v->getNumber() == $_sVersion) {
1348
                            $version = $v;
1349
                        }
1350
                    }
1351
                    if ($version !== false) {
1352
                        $user    = $this->_controler->getUser();
1353
                        $deletor = $this->_getActionsDeleteVisitor();
1354
                        if ($item->accept($deletor, array('user' => $user, 'version' => $version))) {
1355
                            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_item_version_deleted', array($version->getNumber(), $version->getLabel())));
1356
                        }
1357
                    } else {
1358
                        $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_item_not_deleted_unknown_version'));
1359
                    }
1360
                } else {
1361
                    $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_item_not_deleted_last_file_version'));
1362
                }
1363
            } else {
1364
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_item_not_deleted_nonfile_version'));
1365
            }
1366
        }
1367
        $this->_getEventManager()->processEvent('send_notifications', array());
1368
    }
1369
1370
    /**
1371
     * Wrapper for Docman_ActionsDeleteVisitor
1372
     *
1373
     * @return Docman_ActionsDeleteVisitor
1374
     */
1375
    function _getActionsDeleteVisitor() {
1376
        return new Docman_ActionsDeleteVisitor();
1377
    }
1378
1379
    function admin_change_view() {
1380
        $request =& HTTPRequest::instance();
1381
        $group_id = (int) $request->get('group_id');
1382
1383
        if ($request->exist('selected_view') && Docman_View_Browse::isViewAllowed($request->get('selected_view'))) {
1384
            require_once('Docman_SettingsBo.class.php');
1385
            $sBo =& Docman_SettingsBo::instance($group_id);
1386
            if ($sBo->updateView($request->get('selected_view'))) {
1387
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_settings_updated'));
1388
            } else {
1389
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_settings_updated'));
1390
            }
1391
        }
1392
    }
1393
1394
    /**
1395
    * @deprecated
1396
    */
1397
    function install() {
1398
        $request =& HTTPRequest::instance();
1399
        $_gid = (int) $request->get('group_id');
1400
1401
        die('Install forbidden. Please contact administrator');
0 ignored issues
show
Coding Style Compatibility introduced by
The method install() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
1402
    }
1403
1404
    function admin_set_permissions() {
1405
        list ($return_code, $feedback) = permission_process_selection_form($_POST['group_id'], $_POST['permission_type'], $_POST['object_id'], $_POST['ugroups']);
0 ignored issues
show
Deprecated Code introduced by
The function permission_process_selection_form() has been deprecated.

This function has been deprecated.

Loading history...
1406
        if (!$return_code) {
1407
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_perms_updated', $feedback));
1408
        } else {
1409
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'info_perms_updated'));
1410
        }
1411
    }
1412
1413
    function admin_md_details_update() {
1414
        $request =& HTTPRequest::instance();
1415
        $_label = $request->get('label');
1416
        $_gid = (int) $request->get('group_id');
1417
1418
        $mdFactory = new Docman_MetadataFactory($_gid);
1419
        $md =& $mdFactory->getFromLabel($_label);
1420
1421
        if($md !== null) {
1422
            if($md->getGroupId() == $_gid) {
1423
1424
                // Name
1425
                if($md->canChangeName()) {
1426
                    $_name = trim($request->get('name'));
1427
                    $md->setName($_name);
1428
                }
1429
1430
                // Description
1431
                if($md->canChangeDescription()) {
1432
                    $_descr = $request->get('descr');
1433
                    $md->setDescription($_descr);
1434
                }
1435
1436
                // Is empty allowed
1437
                if($md->canChangeIsEmptyAllowed()) {
1438
                    $_isEmptyAllowed = (int) $request->get('empty_allowed');
1439
1440
                    if($_isEmptyAllowed === 1) {
1441
                        $md->setIsEmptyAllowed(PLUGIN_DOCMAN_DB_TRUE);
1442
                    }
1443
                    else {
1444
                        $md->setIsEmptyAllowed(PLUGIN_DOCMAN_DB_FALSE);
1445
                    }
1446
                }
1447
1448
                if($md->canChangeIsMultipleValuesAllowed()) {
1449
                    $_isMultipleValuesAllowed = (int) $request->get('multiplevalues_allowed');
1450
1451
                    if($_isMultipleValuesAllowed === 1) {
1452
                        $md->setIsMultipleValuesAllowed(PLUGIN_DOCMAN_DB_TRUE);
1453
                    }
1454
                    else {
1455
                        $md->setIsMultipleValuesAllowed(PLUGIN_DOCMAN_DB_FALSE);
1456
                    }
1457
                }
1458
1459
                // Usage
1460
                if(!$md->isRequired()) {
1461
                    $_useIt = (int) $request->get('use_it');
1462
                    if($_useIt === 1) {
1463
                        $md->setUseIt(PLUGIN_DOCMAN_METADATA_USED);
1464
                    }
1465
                    else {
1466
                        $md->setUseIt(PLUGIN_DOCMAN_METADATA_UNUSED);
1467
                    }
1468
                }
1469
1470
                $updated = $mdFactory->update($md);
1471
                if($updated) {
1472
                    $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_update'));
1473
                }
1474
                else {
1475
                    $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_not_update'));
1476
                }
1477
            }
1478
            else {
1479
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_id_mismatched'));
1480
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_not_update'));
1481
            }
1482
        }
1483
        else {
1484
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_bad_label'));
1485
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_not_update'));
1486
        }
1487
    }
1488
1489
    function admin_create_metadata() {
1490
        $request =& HTTPRequest::instance();
1491
1492
        $_gid                   = (int) $request->get('group_id');
1493
        $_name                  = trim($request->get('name'));
1494
        $_description           = $request->get('descr');
1495
        $_emptyallowed          = (int) $request->get('empty_allowed');
1496
        $_multiplevaluesallowed = (int) $request->get('multiplevalues_allowed');
1497
        $_dfltvalue             = $request->get('dflt_value');
1498
        $_useit                 = $request->get('use_it');
1499
        $_type                  = (int) $request->get('type');
1500
1501
        $mdFactory = new Docman_MetadataFactory($_gid);
1502
1503
        //$mdrow['group_id'] = $_gid;
1504
        $mdrow['name'] = $_name;
1505
        $mdrow['description'] = $_description;
1506
        $mdrow['data_type'] = $_type;
1507
        //$mdrow['label'] =
1508
        $mdrow['required'] = false;
1509
        $mdrow['empty_ok'] = $_emptyallowed;
1510
1511
        if ($_type == PLUGIN_DOCMAN_METADATA_TYPE_LIST) {
1512
            $mdrow['mul_val_ok'] = $_multiplevaluesallowed;
1513
        } else {
1514
            $mdrow['mul_val_ok'] = false;
1515
        }
1516
1517
        $mdrow['special'] = false;
1518
        $mdrow['default_value'] = $_dfltvalue;
1519
        $mdrow['use_it'] = $_useit;
1520
1521
        $md =& $mdFactory->_createFromRow($mdrow);
1522
1523
        $mdId = $mdFactory->create($md);
1524
        if($mdId !== false) {
1525
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_create'));
1526
        }
1527
        else {
1528
            $this->_controler->feedback->log('error',$GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_error_creation'));
1529
        }
1530
    }
1531
1532
1533
    function admin_delete_metadata() {
1534
        $md = $this->_controler->_actionParams['md'];
1535
1536
        $name = $md->getName();
1537
1538
        $mdFactory = new Docman_MetadataFactory($md->getGroupId());
1539
1540
        $deleted = $mdFactory->delete($md);
1541
        if($deleted) {
1542
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman',
1543
                                                                                   'md_del_success',
1544
                                                                                   array($name)));
1545
        }
1546
        else {
1547
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman',
1548
                                                                                    'md_del_failure',
1549
                                                                                    array($name)));
1550
        }
1551
        $this->_controler->view = 'RedirectAfterCrud';
1552
        $this->_controler->_viewParams['default_url_params'] = array('action' => 'admin_metadata');
1553
    }
1554
1555
    function admin_create_love() {
1556
        $request =& HTTPRequest::instance();
1557
1558
        $_name         = $request->get('name');
1559
        $_description  = $request->get('descr');
1560
        $_rank         = $request->get('rank');
1561
        //$_dfltvalue    = (int) $request->get('dflt_value');
1562
        $_mdLabel      = $request->get('md');
1563
        $_gid          = (int) $request->get('group_id');
1564
1565
        $mdFactory = new Docman_MetadataFactory($_gid);
1566
        $md =& $mdFactory->getFromLabel($_mdLabel);
1567
1568
        if($md !== null
1569
           && $md->getType() == PLUGIN_DOCMAN_METADATA_TYPE_LIST
1570
           && $md->getLabel() != 'status') {
1571
1572
            $loveFactory = new Docman_MetadataListOfValuesElementFactory($md->getId());
1573
1574
            $love = new Docman_MetadataListOfValuesElement();
1575
            $love->setName($_name);
1576
            $love->setDescription($_description);
1577
            $love->setRank($_rank);
1578
            $loveFactory->create($love);
1579
        }
1580
    }
1581
1582
    function admin_delete_love() {
1583
        $request =& HTTPRequest::instance();
1584
1585
        $_loveId  = (int) $request->get('loveid');
1586
        $_mdLabel = $request->get('md');
1587
        $_gid = (int) $request->get('group_id');
1588
1589
        $mdFactory = new Docman_MetadataFactory($_gid);
1590
        $md =& $mdFactory->getFromLabel($_mdLabel);
1591
1592
        if($md !== null
1593
           && $md->getType() == PLUGIN_DOCMAN_METADATA_TYPE_LIST
1594
           && $md->getLabel() != 'status') {
1595
1596
            $love = new Docman_MetadataListOfValuesElement($md->getId());
1597
            $love->setId($_loveId);
1598
1599
            // Delete value
1600
            $loveFactory = new Docman_MetadataListOfValuesElementFactory($md->getId());
1601
            $deleted = $loveFactory->delete($love);
1602
            if($deleted) {
1603
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_delete_element'));
1604
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_reset_delete_element'));
1605
            } else {
1606
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_error_delete_element'));
1607
            }
1608
        }
1609
        else {
1610
            // Sth really strange is happening... user try to delete a value
1611
            // that do not belong to a metadata with a List type !?
1612
            // If this happen, shutdown the server, format the hard drive and
1613
            // leave computer science to keep goat on the Larzac.
1614
        }
1615
    }
1616
1617
    function admin_update_love() {
1618
        $md   = $this->_controler->_actionParams['md'];
1619
        $love = $this->_controler->_actionParams['love'];
1620
1621
        $loveFactory = new Docman_MetadataListOfValuesElementFactory($md->getId());
1622
        $updated = $loveFactory->update($love);
1623
1624
        if($updated) {
1625
            $this->_controler->feedback->log('info',  $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_element_update'));
1626
1627
            $this->_controler->view = 'RedirectAfterCrud';
1628
            $this->_controler->_viewParams['default_url_params']  = array('action' => 'admin_md_details',
1629
                                                                          'md'     => $md->getLabel());
1630
        }
1631
        else {
1632
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'admin_metadata_element_not_update'));
1633
1634
            $this->_controler->view = 'RedirectAfterCrud';
1635
            $this->_controler->_viewParams['default_url_params']  = array('action' => 'admin_display_love',
1636
                                                                          'md'     => $md->getLabel(),
1637
                                                                          'loveid' => $love->getId());
1638
        }
1639
    }
1640
1641
    function admin_import_metadata() {
1642
        $groupId    = $this->_controler->_actionParams['sGroupId'];
1643
        $srcGroupId = $this->_controler->_actionParams['sSrcGroupId'];
1644
1645
        $pm = ProjectManager::instance();
1646
        $srcGo = $pm->getProject($srcGroupId);
1647
        if($srcGo != false &&
1648
           ($srcGo->isPublic()
1649
            || (!$srcGo->isPublic() && $srcGo->userIsMember()))) {
1650
            $mdFactory = new Docman_MetadataFactory($srcGo->getGroupId());
1651
            $mdFactory->exportMetadata($groupId);
1652
1653
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'admin_md_import_success', array($srcGo->getPublicName())));
1654
        } else {
1655
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_perms_generic'));
1656
        }
1657
    }
1658
1659
    function monitor($params) {
1660
        $user = $this->_controler->getUser();
1661
        if (!$user->isAnonymous()) {
1662
            $something_happen  = false;
1663
            $already_monitored = $this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId());
1664
            $already_cascaded  = $this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE);
1665
            if ($params['monitor'] && !$already_monitored) {
1666
                //monitor
1667
                if (!$this->_controler->notificationsManager->add($user->getId(), $params['item']->getId())) {
1668
                    $this->_controler->feedback->log('error', "Unable to add monitoring on '". $params['item']->getTitle() ."'.");
1669
                }
1670
                $something_happen = true;
1671
            } else if(!$params['monitor'] && $already_monitored) {
1672
                //unmonitor
1673
                if (!$this->_controler->notificationsManager->remove($user->getId(), $params['item']->getId())) {
1674
                    $this->_controler->feedback->log('error', "Unable to remove monitoring on '". $params['item']->getTitle() ."'.");
1675
                }
1676
                $something_happen = true;
1677
            }
1678
            if (isset($params['cascade']) && $params['cascade'] && $params['monitor'] && !$already_cascaded) {
1679
                //cascade
1680
                if (!$this->_controler->notificationsManager->add($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE)) {
1681
                    $this->_controler->feedback->log('error', "Unable to add cascade on '". $params['item']->getTitle() ."'.");
1682
                }
1683
                $something_happen = true;
1684
            } else if(!(isset($params['cascade']) && $params['cascade'] && $params['monitor']) && $already_cascaded) {
1685
                //uncascade
1686
                if (!$this->_controler->notificationsManager->remove($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE)) {
1687
                    $this->_controler->feedback->log('error', "Unable to remove cascade on '". $params['item']->getTitle() ."'.");
1688
                }
1689
                $something_happen = true;
1690
            }
1691
            //Feedback
1692
            if ($something_happen) {
1693
                if ($this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId())) {
1694
                    if ($this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE)) {
1695
                        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'notifications_cascade_on', array($params['item']->getTitle())));
1696
                    } else {
1697
                        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'notifications_on', array($params['item']->getTitle())));
1698
                    }
1699
                } else {
1700
                    $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'notifications_off', array($params['item']->getTitle())));
1701
                }
1702
            }
1703
        }
1704
    }
1705
1706
    /**
1707
     * Raise item monitoring list event
1708
     *
1709
     * @param Docman_Item $item Locked item
1710
     * @param String      $eventType
1711
     * @param Array       $subscribers
1712
     *
1713
     * @return void
1714
     */
1715
    function _raiseMonitoringListEvent($item, $subscribers, $eventType) {
1716
        $p = array('group_id' => $item->getGroupId(),
1717
                                       'item'     => $item,
1718
                                       'listeners' => $subscribers,
1719
                                       'event'    => $eventType);
1720
        $this->event_manager->processEvent('plugin_docman_event_subcribers', $p);
1721
    }
1722
1723
    /**
1724
     * Add monitoring for more than one user
1725
     *
1726
     * @param Array $params contains list if users to subscribe and the item
1727
     *
1728
     * @return void
1729
     */
1730
    function add_monitoring($params) {
1731
        if (isset($params['listeners_to_add']) && is_array($params['listeners_to_add']) && !empty($params['listeners_to_add'])) {
1732
                $cascade = false;
1733
                if (isset($params['monitor_cascade']) && $params['monitor_cascade']) {
1734
                    $cascade = true;
1735
                }
1736
                $users = array();
1737
                $existingUsers = array();
1738
                $dpm = $this->_getDocmanPermissionsManagerInstance($params['item']->getGroupId());
1739
                $invalidUsers = $params['invalid_users'];
1740
                foreach ($params['listeners_to_add'] as $user) {
1741
                    if ($user instanceof PFUser) {
1742
                        if (!$this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId())) {
1743
                            if ($dpm->userCanRead($user, $params['item']->getId())) {
1744
                                if ($this->_controler->notificationsManager->add($user->getId(), $params['item']->getId())) {
1745
                                    if ($cascade && !$this->_controler->notificationsManager->add($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE)) {
1746
                                        $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_cascade_not_added', array($user->getName())));
1747
                                    }
1748
                                    $users[] = $user->getName();
1749
                                } else {
1750
                                    $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_not_added', array($user->getName())));
1751
                                }
1752
                            } else {
1753
                                $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'notifications_no_access_rights', array($user->getName())));
1754
                            }
1755
                        } else {
1756
                            $existingUsers[$user->getId()] = $user->getName();
1757
                        }
1758
                    } else {
1759
                        $invalidUsers = true;
1760
                    }
1761
                }
1762
                if ($invalidUsers) {
1763
                    $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_some_users_not_added'));
1764
                }
1765
                if (!empty($existingUsers)) {
1766
                    $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'notifications_already_exists', array(implode(',', $existingUsers))));
1767
                }
1768
                if (!empty($users)) {
1769
                    $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'notifications_added', array(implode(',', $users))));
1770
                    $this->_raiseMonitoringListEvent($params['item'], $params['listeners_to_add'],'plugin_docman_add_monitoring');
1771
                }
1772
        } else {
1773
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_no_user_added'));
1774
        }
1775
    }
1776
1777
    /**
1778
     * Remove monitoring for more than one user
1779
     *
1780
     * @param Array $params contains list if users to remove and the item
1781
     *
1782
     * @return void
1783
     */
1784
    function remove_monitoring($params) {
1785
        if (isset($params['listeners_to_delete']) && is_array($params['listeners_to_delete']) && !empty($params['listeners_to_delete'])) {
1786
                $users = array();
1787
                foreach ($params['listeners_to_delete'] as $user) {
1788
                    if ($this->_controler->notificationsManager->exist($user->getId(), $params['item']->getId())) {
1789
                        if ($this->_controler->notificationsManager->remove($user->getId(), $params['item']->getId()) && $this->_controler->notificationsManager->remove($user->getId(), $params['item']->getId(), PLUGIN_DOCMAN_NOTIFICATION_CASCADE)) {
1790
                            $users[] = $user;
1791
                        } else {
1792
                            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_not_removed', array($user->getName())));
1793
                        }
1794
                    } else {
1795
                        $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'notifications_not_present', array($user->getName())));
1796
                    }
1797
                }
1798
                if (!empty($users)) {
1799
                    $removedUsers = array();
1800
                    foreach ($users as $user) {
1801
                        $removedUsers[] = $user->getName();
1802
                    }
1803
                    $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'notifications_removed', array(implode(',', $removedUsers))));
1804
                    $this->_raiseMonitoringListEvent($params['item'], $users, 'plugin_docman_remove_monitoring');
1805
                }
1806
        } else {
1807
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'notifications_no_user'));
1808
        }
1809
    }
1810
1811
    /**
1812
     * @access private
1813
     */
1814
    function _approval_update_settings(Docman_ApprovalTableFactory $atf, $sStatus, $notification, $notificationOccurence, $description, $owner) {
1815
        $table = $atf->getTable();
1816
        $newOwner = false;
1817
        if(!$table->isCustomizable()) {
1818
            // Cannot set status of an old table to something else than 'close'
1819
            // or 'deleted'
1820
            if ($sStatus != PLUGIN_DOCMAN_APPROVAL_TABLE_CLOSED &&
1821
                $sStatus != PLUGIN_DOCMAN_APPROVAL_TABLE_DELETED) {
1822
                $sStatus = PLUGIN_DOCMAN_APPROVAL_TABLE_CLOSED;
1823
            }
1824
            // Ensure that, once the table belong to an old version, user
1825
            // cannot change the notification type.
1826
            $notification = $table->getNotification();
1827
            $newOwner = $table->getOwner();
1828
        }
1829
1830
        // Change owner
1831
        if($newOwner === false) {
1832
            $_owner = UserManager::instance()->findUser($owner);
1833
            if(!$_owner) {
1834
                $newOwner = $table->getOwner();
1835
            } else {
1836
                if(!$_owner->isAnonymous() && ($_owner->isActive() || $_owner->isRestricted())) {
1837
                    $newOwner = $_owner->getId();
1838
                } else {
1839
                    $newOwner = $table->getOwner();
1840
                }
1841
            }
1842
        }
1843
1844
        // Update settings
1845
        $updated = $atf->updateTable($sStatus, $notification, $notificationOccurence, $description, $newOwner);
1846
        if($updated) {
1847
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_tableupd_success'));
1848
        }
1849
    }
1850
1851
    /**
1852
     * @access private
1853
     */
1854
    function _approval_update_add_users($atrf, $usUserList, $sUgroups) {
1855
        $noError = true;
1856
        $userAdded = false;
1857
1858
        // Update users
1859
        if(trim($usUserList) != '') {
1860
            $usUserArray = explode(',', $usUserList);
1861
            // First add individual users
1862
            if(count($usUserArray) > 0) {
1863
                $nbUserAdded = $atrf->addUsers($usUserArray);
1864
                if($nbUserAdded < count($usUserArray)) {
1865
                    $noError = false;
1866
                } else {
1867
                    $userAdded = true;
1868
                }
1869
            }
1870
        }
1871
1872
     // Then add ugroups.
1873
        if($sUgroups !== null && count($sUgroups) > 0) {
1874
            foreach($sUgroups as $ugroup) {
1875
                $ugroupAdded = false;
1876
                if($ugroup > 0 && $ugroup != 100) {
1877
                    if($atrf->addUgroup($ugroup)) {
1878
                        $ugroupAdded = true;
1879
                    } else {
1880
                        $noError = false;
1881
                    }
1882
                }
1883
            }
1884
        }
1885
1886
        $purifier =& Codendi_HTMLPurifier::instance();
1887
1888
        if(count($atrf->err['db']) > 0) {
1889
            $ua  = array_unique($atrf->err['db']);
1890
            $ua  = $purifier->purifyMap($ua);
1891
            $uas = implode(', ', $ua);
1892
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_useradd_err_db', $uas));
1893
        }
1894
        if(count($atrf->err['perm']) > 0) {
1895
            $ua  = array_unique($atrf->err['perm']);
1896
            $ua  = $purifier->purifyMap($ua);
1897
            $uas = implode(', ', $ua);
1898
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_useradd_err_perm', $uas));
1899
        }
1900
        if(count($atrf->err['notreg']) > 0) {
1901
            $ua  = array_unique($atrf->err['notreg']);
1902
            $ua  = $purifier->purifyMap($ua);
1903
            $uas = implode(', ', $ua);
1904
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_useradd_err_notreg', $uas));
1905
        }
1906
        if(count($atrf->warn['double']) > 0) {
1907
            $ua  = array_unique($atrf->warn['double']);
1908
            $ua  = $purifier->purifyMap($ua);
1909
            $uas = implode(', ', $ua);
1910
            $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'approval_useradd_warn_double', $uas));
1911
        }
1912
1913
        if($userAdded && $noError) {
1914
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_useradd_success'));
1915
        }
1916
    }
1917
1918
    /**
1919
     * @access private
1920
     */
1921
    function _approval_update_del_users($atrf, $selectedUsers) {
1922
        $deletedUsers = 0;
1923
        foreach($selectedUsers as $userId) {
1924
            if($atrf->delUser($userId)) {
1925
                $deletedUsers++;
1926
            }
1927
        }
1928
1929
        if(count($selectedUsers) == $deletedUsers) {
1930
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_userdel_success'));
1931
        } else {
1932
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_userdel_failure'));
1933
        }
1934
    }
1935
1936
    /**
1937
     * @access private
1938
     */
1939
    function _approval_update_notify_users($atrf, $selectedUsers) {
1940
        $notifiedUsers = 0;
1941
        $atnc = $atrf->_getApprovalTableNotificationCycle(true);
1942
        // For each reviewer, if he is selected, notify it
1943
        // This allow us to verify that we actully notify people
1944
        // member of the table!
1945
        $table = $atnc->getTable();
1946
        $ri = $table->getReviewerIterator();
1947
        while($ri->valid()) {
1948
            $reviewer = $ri->current();
1949
            if(in_array($reviewer->getId(), $selectedUsers)) {
1950
                if($atnc->notifyIndividual($reviewer->getId())) {
1951
                    $notifiedUsers++;
1952
                }
1953
            }
1954
            $ri->next();
1955
        }
1956
        if(count($selectedUsers) == $notifiedUsers) {
1957
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_force_notify_success'));
1958
        }
1959
    }
1960
1961
    /**
1962
     * @access private
1963
     */
1964
    function _approval_update_notif_resend($atrf) {
1965
        $res = $atrf->notifyReviewers();
1966
        if($res) {
1967
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_notification_success'));
1968
        } else {
1969
            $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'approval_notification_failure'));
1970
        }
1971
    }
1972
1973
    function approval_update() {
1974
        // Params
1975
        $item         = $this->_controler->_actionParams['item'];
1976
        $user         = $this->_controler->getUser();
1977
        $sStatus      = $this->_controler->_actionParams['status'];
1978
        $notification = $this->_controler->_actionParams['notification'];
1979
        $reminder     = $this->_controler->_actionParams['reminder'];
1980
        if ($reminder) {
1981
            $occurence             = $this->_controler->_actionParams['occurence'];
1982
            $period                = $this->_controler->_actionParams['period'];
1983
            $notificationOccurence = $occurence * $period;
1984
        } else {
1985
            $notificationOccurence = 0;
1986
        }
1987
        $description  = $this->_controler->_actionParams['description'];
1988
        $usUserList   = $this->_controler->_actionParams['user_list'];
1989
        $sUgroup      = $this->_controler->_actionParams['ugroup_list'];
1990
        $sSelUser     = $this->_controler->_actionParams['sel_user'];
1991
        $sSelUserAct  = $this->_controler->_actionParams['sel_user_act'];
1992
        $resendNotif  = $this->_controler->_actionParams['resend_notif'];
1993
        $version      = $this->_controler->_actionParams['version'];
1994
        $import       = $this->_controler->_actionParams['import'];
1995
        $owner        = $this->_controler->_actionParams['table_owner'];
1996
1997
        $atf =& Docman_ApprovalTableFactoriesFactory::getFromItem($item, $version);
1998
        $table = $atf->getTable();
1999
        $oldTable = null;
2000
        if($table !== null) {
2001
            $oldTable = clone $atf->getTable();
2002
        }
2003
2004
        $tableEditable = false;
2005
        if($oldTable === null || ($import !== false && $import !== 'keep')) {
2006
            $created = $atf->createTable($user->getId(), $import);
2007
            if(!$created) {
2008
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_tableins_failure'));
2009
            }
2010
        }
2011
2012
        if($import === false || $import == 'keep') {
2013
            // New table created "from scratch" (ie. without the import
2014
            // selector) are directly editable.
2015
            $tableEditable = true;
2016
        }
2017
2018
        if($tableEditable) {
2019
            $this->_approval_update_settings($atf, $sStatus, $notification, $notificationOccurence, $description, $owner);
0 ignored issues
show
Bug introduced by
It seems like $atf defined by \Docman_ApprovalTableFac...omItem($item, $version) on line 1997 can also be of type null; however, Docman_Actions::_approval_update_settings() does only seem to accept object<Docman_ApprovalTableFactory>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2020
            $table =& $atf->getTable();
2021
            if(!$table->isClosed()) {
2022
                $atrf =& new Docman_ApprovalTableReviewerFactory($table, $item, $this->_controler->notificationsManager);
2023
                $this->_approval_update_add_users($atrf, $usUserList, $sUgroup);
2024
                if(is_array($sSelUser) && count($sSelUser) > 0) {
2025
                    switch($sSelUserAct){
2026
                    case 'del':
2027
                        $this->_approval_update_del_users($atrf, $sSelUser);
2028
                        break;
2029
                    case 'mail':
2030
                        $this->_approval_update_notify_users($atrf, $sSelUser);
2031
                        break;
2032
                    }
2033
                }
2034
                // If needed, notify next reviewer
2035
                if(($oldTable !== null
2036
                    && $oldTable->getStatus() != PLUGIN_DOCMAN_APPROVAL_TABLE_ENABLED
2037
                    && $table->getStatus() == PLUGIN_DOCMAN_APPROVAL_TABLE_ENABLED)
2038
                   || $resendNotif) {
2039
                    $this->_approval_update_notif_resend($atrf);
2040
                }
2041
            }
2042
        }
2043
    }
2044
2045
    function approval_delete() {
2046
        // Params
2047
        $item = $this->_controler->_actionParams['item'];
2048
        $version = $this->_controler->_actionParams['version'];
2049
        $atf =& Docman_ApprovalTableFactoriesFactory::getFromItem($item, $version);
2050
        $deleted = $atf->deleteTable();
2051
        if($deleted) {
2052
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_tabledel_success'));
2053
        } else {
2054
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_tabledel_failure'));
2055
        }
2056
    }
2057
2058
   function approval_upd_user() {
2059
        // Params
2060
        $item    = $this->_controler->_actionParams['item'];
2061
        $sUserId = $this->_controler->_actionParams['user_id'];
2062
        $usRank  = $this->_controler->_actionParams['rank'];
2063
2064
        // Action
2065
        $atrf =& Docman_ApprovalTableFactory::getReviewerFactoryFromItem($item);
2066
        $atrf->updateUser($sUserId, $usRank);
2067
    }
2068
2069
    function approval_user_commit() {
2070
        // Params
2071
        $item      = $this->_controler->_actionParams['item'];
2072
        $svState   = $this->_controler->_actionParams['svState'];
2073
        $sVersion  = $this->_controler->_actionParams['sVersion'];
2074
        $usComment = $this->_controler->_actionParams['usComment'];
2075
        $user      = $this->_controler->getUser();
2076
2077
        $review = new Docman_ApprovalReviewer();
2078
        $review->setId($user->getId());
2079
        $review->setState($svState);
2080
        $review->setComment($usComment);
2081
        if($svState != PLUGIN_DOCMAN_APPROVAL_STATE_NOTYET) {
2082
            $review->setVersion($sVersion);
2083
            $review->setReviewDate(time());
2084
        }
2085
        else {
2086
            $review->setVersion(null);
2087
            $review->setReviewDate(null);
2088
        }
2089
2090
        $atrf =& Docman_ApprovalTableFactory::getReviewerFactoryFromItem($item);
2091
        $atrf->setNotificationManager($this->_controler->notificationsManager);
2092
        $updated = $atrf->updateReview($review);
2093
        if($updated) {
2094
            $this->event_manager->processEvent(
2095
                PLUGIN_DOCMAN_EVENT_APPROVAL_TABLE_COMMENT,
2096
                array(
2097
                    'item'       => $item,
2098
                    'version_nb' => $sVersion,
2099
                    'table'      => $atrf->getTable(),
2100
                    'review'     => $review,
2101
                )
2102
            );
2103
            $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'approval_review_success'));
2104
        } else {
2105
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'approval_review_failure'));
2106
        }
2107
2108
        $this->monitor($this->_controler->_actionParams);
2109
    }
2110
2111
    function report_del() {
2112
        $user      = $this->_controler->getUser();
2113
        $reportId  = $this->_controler->_actionParams['sReportId'];
2114
        $groupId   = $this->_controler->_actionParams['sGroupId'];
2115
2116
        $reportFactory = new Docman_ReportFactory($groupId);
2117
        $r = $reportFactory->getReportById($reportId);
2118
        if($r == null) {
2119
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_del_notfound'));
2120
        } else {
2121
            if($r->getScope() == 'I' && $r->getUserId() != $user->getId()) {
2122
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_del_notowner'));
2123
            } else {
2124
                if($r->getScope() == 'P' && !$this->_controler->userCanAdmin()) {
2125
                    $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_del_notadmin'));
2126
                } else {
2127
                    if($reportFactory->deleteReport($r)) {
2128
                        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'report_del_success'));
2129
                    } else {
2130
                        $this->_controler->feedback->log('warning', $GLOBALS['Language']->getText('plugin_docman', 'report_del_failure'));
2131
                    }
2132
                }
2133
            }
2134
        }
2135
    }
2136
2137
    function report_upd() {
2138
        $reportId = $this->_controler->_actionParams['sReportId'];
2139
        $groupId  = $this->_controler->_actionParams['sGroupId'];
2140
        $scope    = $this->_controler->_actionParams['sScope'];
2141
        $title    = $this->_controler->_actionParams['title'];
2142
        $description = $this->_controler->_actionParams['description'];
2143
        $image    = $this->_controler->_actionParams['sImage'];
2144
2145
2146
        $reportFactory = new Docman_ReportFactory($groupId);
2147
        $r = $reportFactory->getReportById($reportId);
2148
        if($r == null) {
2149
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_upd_notfound'));
2150
        } else {
2151
            if($r->getGroupId() != $groupId) {
2152
                $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_upd_groupmismatch'));
2153
            } else {
2154
                if($this->_controler->userCanAdmin()) {
2155
                    $r->setScope($scope);
2156
                }
2157
                $r->setTitle($title);
2158
                $r->setDescription($description);
2159
                $r->setImage($image);
2160
                $reportFactory->updateReportSettings($r);
2161
            }
2162
        }
2163
    }
2164
2165
    function report_import() {
2166
        $groupId        = $this->_controler->_actionParams['sGroupId'];
2167
        $importReportId = $this->_controler->_actionParams['sImportReportId'];
2168
        $importGroupId  = $this->_controler->_actionParams['sImportGroupId'];
2169
        $user           =& $this->_controler->getUser();
2170
2171
        // Any user can importreports from any public projects and from
2172
        // Private projects he is member of.
2173
        $pm = ProjectManager::instance();
2174
        $go = $pm->getProject($importGroupId);
2175
        if($go != false &&
2176
           ($go->isPublic()
2177
            || (!$go->isPublic() && $go->userIsMember()))) {
2178
            $srcReportFactory = new Docman_ReportFactory($importGroupId);
2179
2180
            // Get the mapping between src and current project metadata definition.
2181
            $mdMap = array();
2182
            $srcMdFactory = new Docman_MetadataFactory($importGroupId);
2183
            $srcMdFactory->getMetadataMapping($groupId, $mdMap);
2184
2185
            // Get the mapping between src and current project items definition for the item involved
2186
            // in the reports.
2187
            $itemMapping = array();
2188
            // Get involved items
2189
            $srcReportItems = $srcReportFactory->getReportsItems($importReportId);
2190
            if(count($srcReportItems) > 0) {
2191
                // Get the subtree from the original docman on which reports applies
2192
                $srcItemFactory = new Docman_ItemFactory($importGroupId);
2193
                $srcItemTree = $srcItemFactory->getItemTreeFromLeaves($srcReportItems, $user);
2194
                if($srcItemTree !== null) {
2195
                    // Final step: find in the current ($groupId) docman
2196
                    $dstItemFactory = new Docman_ItemFactory($groupId);
2197
                    $itemMapping = $dstItemFactory->getItemMapping($srcItemTree);
2198
                }
2199
            }
2200
2201
            // If user is admin he can create 'P' report otherwise everything is 'I'
2202
            $forceScope = true;
2203
            if($this->_controler->userCanAdmin()) {
2204
                $forceScope = false;
2205
            }
2206
2207
            if($importReportId !== null) {
2208
                // Import only one report
2209
                $report = $srcReportFactory->getReportById($importReportId);
2210
2211
                if($report !== null) {
2212
                    // User can import Project wide reports or his own Individual reports.
2213
                    if($report->getScope() == 'P' ||
2214
                       ($report->getScope() == 'I' && $report->getUserId() == $user->getId())) {
2215
2216
                        $srcReportFactory->cloneReport($report, $groupId, $mdMap, $user, $forceScope, $itemMapping);
2217
2218
                        $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'report_clone_success'));
2219
                    } else {
2220
                        $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_err_clone_iorp'));
2221
                    }
2222
                } else {
2223
                    $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'report_err_notfound', array($importReportId)));
2224
                }
2225
            } else {
2226
                // Import all personal and project reports from the given project.
2227
                $srcReportFactory->copy($groupId, $mdMap, $user, $forceScope, $itemMapping);
2228
                $this->_controler->feedback->log('info', $GLOBALS['Language']->getText('plugin_docman', 'report_clone_success'));
2229
            }
2230
        } else {
2231
            $this->_controler->feedback->log('error', $GLOBALS['Language']->getText('plugin_docman', 'error_perms_generic'));
2232
        }
2233
    }
2234
2235
    function action_lock_add() {
2236
        $item = $this->_controler->_actionParams['item'];
2237
        if ($this->_controler->userCanWrite($item->getId())) {
2238
            $user = $this->_controler->getUser();
2239
            $lockFactory = new Docman_LockFactory();
2240
            $dIF = $this->_getItemFactory();
2241
            $canLock = true;
2242
2243
            // Cannot lock a wiki with a page already locked
2244
            if($dIF->getItemTypeForItem($item) == PLUGIN_DOCMAN_ITEM_TYPE_WIKI) {
2245
                $pagename = $item->getPagename();
2246
                $group_id = $item->getGroupId();
2247
                $referencers = $dIF->getWikiPageReferencers($pagename, $group_id);
2248
                foreach($referencers as $referencer) {
2249
                    if($lockFactory->itemIsLockedByItemId($referencer->getId())) {
2250
                        $canLock = false;
2251
                        break;
2252
                        // wiki page is locked by another item.
2253
                    }
2254
                }
2255
            }
2256
2257
            // Cannot lock a folder
2258
            if($dIF->getItemTypeForItem($item) == PLUGIN_DOCMAN_ITEM_TYPE_FOLDER) {
2259
                $canLock = false;
2260
            }
2261
2262
            if($canLock) {
2263
                if ($lockFactory->lock($item, $user)) {
2264
                    $this->_raiseLockEvent($item, $user);
2265
                }
2266
            }
2267
        }
2268
    }
2269
2270
    function action_lock_del() {
2271
        $item = $this->_controler->_actionParams['item'];
2272
        $user = $this->_controler->getUser();
2273
        $lockFactory = new Docman_LockFactory();
2274
        if ($this->_controler->userCanWrite($item->getId())) {
2275
            $lockFactory->unlock($item);
2276
            $this->_raiseUnlockEvent($item, $user);
2277
        }
2278
    }
2279
}
2280
2281
?>
2282