Completed
Push — master ( ae7e79...4a5483 )
by Patrick
03:04
created

class.LDAPAuthenticator.php ➔ sort_array()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 7
eloc 15
c 1
b 1
f 1
nc 7
nop 2
dl 0
loc 27
rs 6.7272
1
<?php
2
/**
3
 * LDAPAuthenticator class
4
 *
5
 * This file describes the LDAPAuthenticator class
6
 *
7
 * PHP version 5 and 7
8
 *
9
 * @author Patrick Boyd / [email protected]
10
 * @copyright Copyright (c) 2015, Austin Artistic Reconstruction
11
 * @license http://www.apache.org/licenses/ Apache 2.0 License
12
 */
13
14
namespace Auth;
15
16
/** We need the FlipsideSettings class to determine how to connect to the LDAP server */
17
if(isset($GLOBALS['FLIPSIDE_SETTINGS_LOC']))
18
{
19
    require_once($GLOBALS['FLIPSIDE_SETTINGS_LOC'].'/class.FlipsideSettings.php');
20
}
21
else
22
{
23
    require_once('/var/www/secure_settings/class.FlipsideSettings.php');
24
}
25
26
/** 
27
 * Sort the provided array by the keys in $orderby 
28
 *
29
 * @param array $array The array to sort
30
 * @param array $orderby An array of keys to sort the array by
31
 */
32
function sort_array(&$array, $orderby)
33
{
34
    $count = count($array);
35
    $keys  = array_keys($orderby);
36
    for($i = 0; $i < $count; $i++)
37
    {
38
        for($j = $i; $j < $count; $j++)
39
        {
40
            $d = strcasecmp($array[$i][$keys[0]][0], $array[$j][$keys[0]][0]);
41
            switch($orderby[$keys[0]])
42
            {
43
                case 1:
44
                    if($d > 0)
45
                    {
46
                        swap($array, $i, $j);
47
                    }
48
                    break;
49
                case 0:
50
                    if($d < 0)
51
                    {
52
                        swap($array, $i, $j);
53
                    }
54
                    break;
55
            }
56
        }
57
    }
58
}
59
60
/**
61
 * Swap two elements of the provided array
62
 *
63
 * @param array $array The array to swap values in
64
 * @param mixed $i The key of the first element to swap
65
 * @param mixed $j The key of the second element to swap
66
 */
67
function swap(&$array, $i, $j)
68
{
69
    $tmp = $array[$i];
70
    $array[$i] = $array[$j];
71
    $array[$j] = $tmp;
72
}
73
74
/**
75
 * An Authenticator class which uses LDAP as its backend storage mechanism
76
 */
77
class LDAPAuthenticator extends Authenticator
78
{
79
    /** The URL for the LDAP host */
80
    private $host;
81
    /** The base DN for all users in the LDAP server */
82
    public  $user_base;
83
    /** The base DN for all groups in the LDAP server */
84
    public  $group_base;
85
    /** The DN to use to bind if not binding as the user */
86
    private $bind_dn;
87
    /** The password to use to bind if not binding as the user */
88
    private $bind_pass;
89
90
    /**
91
     * Create an LDAP Authenticator
92
     *
93
     * @param array $params Parementers needed to initialize the authenticator
94
     */
95
    public function __construct($params)
96
    {
97
        parent::__construct($params);
98
        $this->host       = $this->getHostParam($params);
99
        $this->user_base  = $this->getParam($params, 'user_base');
100
        $this->group_base = $this->getParam($params, 'group_base');
101
        $this->bind_dn    = $this->getParam($params, 'bind_dn', '$ldap_auth', 'read_write_pass');
102
        $this->bind_pass  = $this->getParam($params, 'bind_pass', '$ldap_auth', 'read_write_user');
103
    }
104
105
    /**
106
     * Return the host string for this authenticator
107
     *
108
     * @param array $params The initial parameters of the authenticator
109
     *
110
     * @return string The host string
111
     *
112
     * @SuppressWarnings("StaticAccess")
113
     */
114
    private function getHostParam($params)
115
    {
116
        if(isset($params['host']))
117
        {
118
            return $params['host'];
119
        }
120
        if(isset(\FlipsideSettings::$ldap['proto']))
121
        {
122
            return \FlipsideSettings::$ldap['proto'].'://'.\FlipsideSettings::$ldap['host'];
123
        }
124
        return \FlipsideSettings::$ldap['host'];
125
    }
126
127
    /**
128
     * Return the required paramter for this authenticator
129
     *
130
     * @param array  $params The initial parameters of the authenticator
131
     * @param string $paramName The name of the parameter in the $paramsArray
132
     * @param string $settingsLocation The location in the FlipsideSettings class
133
     * @param string $settingsName The name in the FlipsideSettings class
134
     *
135
     * @return mixed The paramter value
136
     *
137
     * @SuppressWarnings("StaticAccess")
138
     */
139
    private function getParam($params, $paramName, $settingsLocation = '$ldap', $settingsName = false)
140
    {
141
        if($settingsName === false)
142
        {
143
            $settingsName = $paramName;
144
        }
145
        if(isset($params[$paramName]))
146
        {
147
            return $params[$paramName];
148
        }
149
        if($settingsLocation === '$ldap')
150
        {
151
            return \FlipsideSettings::$ldap[$settingsName];
152
        }
153
        return \FlipsideSettings::$ldap_auth[$settingsName];
154
    }
155
156
    /**
157
     * Return an instance to the \LDAP\LDAPServer object instance
158
     *
159
     * @param boolean $bind_write Should we be able to write to the server?
160
     *
161
     * @return \LDAP\LDAPServer|false The server instance if the binding was successful, otherwise false
162
     *
163
     * @SuppressWarnings("StaticAccess")
164
     */
165
    public function get_and_bind_server($bind_write = false)
166
    {
167
        $server = \LDAP\LDAPServer::getInstance();
168
        $server->user_base = $this->user_base;
169
        $server->group_base = $this->group_base;
170
        $server->connect($this->host);
171
        if($bind_write === false)
172
        {
173
            $ret = $server->bind();
174
        }
175
        else
176
        {
177
            $ret = $server->bind($this->bind_dn, $this->bind_pass);
178
        }
179
        if($ret === false)
180
        {
181
            return false;
182
        }
183
        return $server;
184
    }
185
186
    /**
187
     * Log the user in provided the credetials
188
     *
189
     * @param string $username The UID or email address for the user
190
     * @param string $password The password for the user
191
     *
192
     * @return mixed False if the login failed and array otherwise
193
     */
194
    public function login($username, $password)
195
    {
196
        $server = $this->get_and_bind_server();
197
        if($server === false)
198
        {
199
            return false;
200
        }
201
        $filter = new \Data\Filter("uid eq $username or mail eq $username");
202
        $user = $server->read($this->user_base, $filter);
0 ignored issues
show
Documentation introduced by
$filter is of type object<Data\Filter>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
203
        if($user === false || count($user) === 0)
204
        {
205
            return false;
206
        }
207
        $user = $user[0];
208
        $server->unbind();
209
        $ret = $server->bind($user->dn, $password);
210
        if($ret !== false)
211
        {
212
            return array('res'=>true, 'extended'=>$user); 
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array('res' => true, 'extended' => $user); (array) is incompatible with the return type of the parent method Auth\Authenticator::login of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
213
        }
214
        return false;
215
    }
216
217
    /**
218
     * Does this array represent a successful login?
219
     *
220
     * @param array $data The array data stored in the session after a login call
221
     *
222
     * @return boolean True if the user is logged in, false otherwise
223
     */
224
    public function isLoggedIn($data)
225
    {
226
        if(isset($data['res']))
227
        {
228
            return $data['res'];
229
        }
230
        return false;
231
    }
232
233
    /**
234
     * Obtain the currently logged in user from the session data
235
     *
236
     * @param \stdClass	$data The AuthData from the session
237
     *
238
     * @return \Auth\LDAPUser The LDAPUser represented by this data
239
     */
240
    public function getUser($data)
241
    {
242
        return new LDAPUser($data);
0 ignored issues
show
Documentation introduced by
$data is of type object<stdClass>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The return type of return new \Auth\LDAPUser($data); (Auth\LDAPUser) is incompatible with the return type of the parent method Auth\Authenticator::getUser of type Auth\Auth\User|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
243
    }
244
245
    public function getGroupByName($name)
246
    {
247
        $server = $this->get_and_bind_server();
248
        if($server === false)
249
        {
250
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method Auth\Authenticator::getGroupByName of type Auth\Auth\Group|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
251
        }
252
        return LDAPGroup::from_name($name, $server);
0 ignored issues
show
Documentation introduced by
$server is of type object<LDAP\LDAPServer>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The return type of return \Auth\LDAPGroup::from_name($name, $server); (false|Auth\LDAPGroup) is incompatible with the return type of the parent method Auth\Authenticator::getGroupByName of type Auth\Auth\Group|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
253
    }
254
255
    public function getGroupsByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false)
256
    {
257
        $server = $this->get_and_bind_server();
258
        if($server === false)
259
        {
260
            return false;
261
        }
262
        if($filter === false)
263
        {
264
            $filter = new \Data\Filter('cn eq *');
265
        }
266
        $groups = $server->read($this->group_base, $filter);
267
        if($groups === false)
268
        {
269
            return false;
270
        }
271
        $this->processFilteringParams($groups, $select, $top, $skip, $orderby);
272
        $count = count($groups);
273
        for($i = 0; $i < $count; $i++)
274
        {
275
            $groups[$i] = new LDAPGroup($groups[$i]);
276
            if($select !== false)
277
            {
278
                $groups[$i] = json_decode(json_encode($groups[$i]), true);
279
                $groups[$i] = array_intersect_key($groups[$i], array_flip($select));
280
            }
281
        }
282
        return $groups;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $groups; (array) is incompatible with the return type of the parent method Auth\Authenticator::getGroupsByFilter of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
283
    }
284
285
    public function getActiveUserCount()
286
    {
287
        $server = $this->get_and_bind_server();
288
        if($server === false)
289
        {
290
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method Auth\Authenticator::getActiveUserCount of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
291
        }
292
        return $server->count($this->user_base);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $server->count($this->user_base); of type false|integer adds false to the return on line 292 which is incompatible with the return type of the parent method Auth\Authenticator::getActiveUserCount of type integer. It seems like you forgot to handle an error condition.
Loading history...
293
    }
294
295
    /**
296
     * @param array           $data The array data to filter and sort
297
     * @param boolean|array   $select The fields to return
298
     * @param boolean|integer $top The number of records to return
299
     * @param boolean|integer $skip The number of records to skip
300
     * @param boolean|array   $orderby The fields to sort by
301
     */
302
    private function processFilteringParams(&$data, &$select, $top, $skip, $orderby)
303
    {
304
        if($orderby !== false)
305
        {
306
            sort_array($data, $orderby);
307
        }
308
        if($select !== false)
309
        {
310
            $select = array_flip($select);
311
        }
312
        if($skip !== false && $top !== false)
313
        {
314
            $data = array_slice($data, $skip, $top);
315
        }
316
        else if($top !== false)
317
        {
318
            $data = array_slice($data, 0, $top);
319
        }
320
        else if($skip !== false)
321
        {
322
            $data = array_slice($data, $skip);
323
        }
324
    }
325
326
    
327
    /**
328
     * @param boolean|\Data\Filter $filter The filter to user when reading users
329
     * @param boolean|array   $select The fields to return
330
     * @param boolean|integer $top The number of records to return
331
     * @param boolean|integer $skip The number of records to skip
332
     * @param boolean|array   $orderby The fields to sort by
333
     */
334
    public function getUsersByFilter($filter, $select = false, $top = false, $skip = false, $orderby = false)
335
    {
336
        $server = $this->get_and_bind_server();
337
        if($server === false)
338
        {
339
            return false;
340
        }
341
        if($filter === false)
342
        {
343
            $filter = new \Data\Filter('cn eq *');
344
        }
345
        $users = $server->read($this->user_base, $filter, false, $select);
0 ignored issues
show
Bug introduced by
It seems like $filter can also be of type object<Data\Filter>; however, LDAP\LDAPServer::read() does only seem to accept boolean, 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 $select defined by parameter $select on line 334 can also be of type array; however, LDAP\LDAPServer::read() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
346
        if($users === false)
347
        {
348
            return false;
349
        }
350
        $this->processFilteringParams($users, $select, $top, $skip, $orderby);
351
        $count = count($users);
352
        for($i = 0; $i < $count; $i++)
353
        {
354
            $tmp = new LDAPUser($users[$i]);
355
            if($select !== false)
356
            {
357
                $tmp = $tmp->jsonSerialize();
358
                $tmp = array_intersect_key($tmp, $select);
359
            }
360
            $users[$i] = $tmp;
361
        }
362
        return $users;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $users; (array) is incompatible with the return type of the parent method Auth\Authenticator::getUsersByFilter of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
363
    }
364
365
    public function activatePendingUser($user)
366
    {
367
        $this->get_and_bind_server(true);
368
        $new_user = new LDAPUser();
369
        $new_user->setUID($user->getUID());
370
        $email = $user->getEmail();
371
        $new_user->setEmail($email);
372
        $pass = $user->getPassword();
373
        if($pass !== false)
374
        {
375
            $new_user->setPass($pass);
376
        }
377
        $sn = $user->getLastName();
378
        if($sn !== false)
379
        {
380
            $new_user->setLastName($sn);
381
        }
382
        $givenName = $user->getGivenName();
383
        if($givenName !== false)
384
        {
385
            $new_user->setGivenName($givenName);
386
        }
387
        $hosts = $user->getLoginProviders();
388
        if($hosts !== false)
389
        {
390
            $count = count($hosts);
391
            for($i = 0; $i < $count; $i++)
392
            {
393
                $new_user->addLoginProvider($hosts[$i]);
394
            }
395
        }
396
        $ret = $new_user->flushUser();
397
        if($ret)
398
        {
399
            $user->delete();
400
        }
401
        $users = $this->getUsersByFilter(new \Data\Filter('mail eq '.$email));
402
        if($users === false || !isset($users[0]))
403
        {
404
            throw new \Exception('Error creating user!');
405
        }
406
        return $users[0];
407
    }
408
409
    public function getUserByResetHash($hash)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
410
    {
411
        $users = $this->getUsersByFilter(new \Data\Filter("uniqueIdentifier eq $hash"));
412
        if($users === false || !isset($users[0]))
413
        {
414
            return false;
415
        }
416
        return $users[0];
417
    }
418
}
419
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
420