UserAccount::get_user_group_roles()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 6

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 13
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * The PHP Skeleton App
4
 *
5
 * @author      Goran Halusa <[email protected]>
6
 * @copyright   2015 Goran Halusa
7
 * @link        https://github.com/ghalusa/PHP-Skeleton-App
8
 * @license     https://github.com/ghalusa/PHP-Skeleton-App/wiki/License
9
 * @version     0.1.1
10
 * @package     PHP Skeleton App
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
16
/**
17
 * User Account
18
 *
19
 * Class for the User Account module, providing methods for browsing and managing users.
20
 *
21
 * @author      Goran Halusa <[email protected]>
22
 * @since       0.1.0
23
 */
24
25
namespace PHPSkeleton;
26
use PDO;
27
28
class UserAccount
29
{
30
  /**
31
   * @var string|bool  $session_key    The session key
32
   */
33
  private $session_key = false;
34
35
  /**
36
   * @var object  $db   The database connection object
37
   */
38
  public $db;
39
40
  /**
41
   * Constructor
42
   * @param object   $db_connection   The database connection object
43
   * @param string   $session_key     The session key
44
   */
45 View Code Duplication
  public function __construct($db_connection = false, $session_key = false)
46
  {
47
      if ($db_connection && is_object($db_connection)) {
48
          $this->db = $db_connection;
49
      }
50
      $this->session_key = $session_key;
51
  }
52
53
  /**
54
   * Browse User Accounts
55
   *
56
   * Run a query to retreive all users in the database.
57
   *
58
   * @param   string  $sort_field     The data value
59
   * @param   string  $sort_order     The data value
60
   * @param   int  $start_record      The data value
61
   * @param   int  $stop_record       The data value
62
   * @param   string  $search         The data value
63
   * @param   int  $user_account_id   The data value
64
   * @return  array|bool              The query result
65
   */
66
  public function browse_user_accounts(
67
    $sort_field = false
68
    ,$sort_order = 'DESC'
69
    ,$start_record = 0
70
    ,$stop_record = 20
71
    ,$search = false
72
    ,$user_account_id = false)
73
  {
74
      $sort = "";
75
      $search_sql = "";
76
      $pdo_params = array();
77
      $data = array();
78
79
      $limit_sql = " LIMIT {$start_record}, {$stop_record} ";
80
81 View Code Duplication
      if ($sort_field) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $sort_field of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
82
          switch ($sort_field) {
83
          case 'last_modified':
84
              $sort = " ORDER BY user_account_groups.last_modified {$sort_order} ";
85
          break;
86
          default:
87
              $sort = " ORDER BY {$sort_field} {$sort_order} ";
88
        }
89
      }
90
91
      $and_user_account_id = $user_account_id ? " AND user_account.user_account_id = {$user_account_id} " : "";
92
93
      if ($search) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $search of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
94
          $pdo_params[] = '%'.$search.'%';
95
          $pdo_params[] = '%'.$search.'%';
96
          $search_sql = "
97
              AND (
98
                user_account.last_name LIKE ?
99
                OR user_account.first_name LIKE ?
100
              ) ";
101
      }
102
103
      $statement = $this->db->prepare("SELECT SQL_CALC_FOUND_ROWS
104
              user_account_groups.user_account_id AS manage
105
              ,user_account_groups.user_account_id
106
              ,CONCAT(user_account.first_name, ' ', user_account.last_name) AS name
107
              ,user_account.active
108
              ,GROUP_CONCAT(DISTINCT group.name SEPARATOR ', ') AS groups
109
              ,user_account_groups.user_account_id AS DT_RowId
110
          FROM user_account_groups
111
          LEFT JOIN user_account ON user_account.user_account_id = user_account_groups.user_account_id
112
          LEFT JOIN `group` ON `group`.group_id = user_account_groups.group_id
113
          WHERE 1 = 1
114
          {$and_user_account_id}
115
          {$search_sql}
116
          GROUP BY user_account_groups.user_account_id
117
          HAVING 1 = 1
118
          {$sort}
119
          {$limit_sql}");
120
      $statement->execute($pdo_params);
121
      $data["aaData"] = $statement->fetchAll(PDO::FETCH_ASSOC);
122
123
      $statement = $this->db->prepare("SELECT FOUND_ROWS()");
124
      $statement->execute();
125
      $count = $statement->fetch(PDO::FETCH_ASSOC);
126
      $data["iTotalRecords"] = $count["FOUND_ROWS()"];
127
      $data["iTotalDisplayRecords"] = $count["FOUND_ROWS()"];
128
      return $data;
129
  }
130
131
  /**
132
   * Get Universal Administrator Emails
133
   *
134
   * Run a query to retrieve all administrator emails from the database.
135
   *
136
   * @return      array|bool     The query result
137
   */
138
  public function get_universal_administrator_emails()
139
  {
140
      $statement = $this->db->prepare("SELECT user_account.user_account_email
141
          FROM user_account
142
          LEFT JOIN user_account_groups ON user_account_groups.user_account_id = user_account.user_account_id
143
          WHERE role_id = 6");
144
      $statement->execute();
145
      return $statement->fetchAll(PDO::FETCH_ASSOC);
146
  }
147
148
  /**
149
   * Get User Account Groups
150
   *
151
   * Run a query to retrieve all of a user's groups from the database. Used by get_user_group_roles_map().
152
   *
153
   * @param       int $user_account_id    The data value
154
   * @return      array|bool              The query result
155
   */
156 View Code Duplication
  public function get_user_account_groups($user_account_id)
157
  {
158
      $statement = $this->db->prepare("SELECT `group`.group_id
159
          ,`group`.name AS group_name
160
          FROM user_account_groups
161
          LEFT JOIN `group` ON `group`.group_id = user_account_groups.group_id
162
          WHERE user_account_groups.user_account_id = :user_account_id
163
          GROUP BY `group`.group_id");
164
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
165
      $statement->execute();
166
      return $statement->fetchAll(PDO::FETCH_ASSOC);
167
  }
168
169
  /**
170
   * Get User Group Roles
171
   *
172
   * Run a query to retrieve all of a user's group roles from the database. Used by get_user_group_roles_map().
173
   *
174
   * @param       int $user_account_id    The data value
175
   * @param       int $group_id           The data value
176
   * @return      array|bool              The query result
177
   */
178 View Code Duplication
  public function get_user_group_roles($user_account_id, $group_id)
179
  {
180
      $statement = $this->db->prepare("SELECT user_account_roles.role_id
181
          ,user_account_roles.label AS role_label
182
          FROM user_account_groups
183
          LEFT JOIN user_account_roles ON user_account_roles.role_id = user_account_groups.role_id
184
          WHERE user_account_groups.user_account_id = :user_account_id
185
          AND user_account_groups.group_id = :group_id");
186
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
187
      $statement->bindValue(":group_id", $group_id, PDO::PARAM_INT);
188
      $statement->execute();
189
      return $statement->fetchAll(PDO::FETCH_ASSOC);
190
  }
191
192
  /**
193
   * Get Roles
194
   *
195
   * Run a query to retrieve all roles from the database.
196
   *
197
   * @param       array $exclude_ids      The array
198
   * @return      array|bool              The query result
199
   */
200
  public function get_roles($exclude_ids = array())
201
  {
202
      $exclude_id_sql = "";
203
204
      if (!empty($exclude_ids)) {
205
          $exclude_id_sql = " AND user_account_roles.role_id NOT IN (" . implode(",", $exclude_ids) . ") ";
206
      }
207
208
      $statement = $this->db->prepare("SELECT *
209
          FROM user_account_roles
210
          WHERE 1=1
211
          {$exclude_id_sql}");
212
      $statement->execute();
213
      return $statement->fetchAll(PDO::FETCH_ASSOC);
214
  }
215
216
  /**
217
   * Get User Account Info
218
   *
219
   * Run a query to retrieve one user's account from the database.
220
   *
221
   * @param       int $user_account_id    The data value
222
   * @return      array|bool              The query result
223
   */
224 View Code Duplication
  public function get_user_account_info($user_account_id = false)
225
  {
226
      $statement = $this->db->prepare("SELECT user_account_email
227
          ,first_name
228
          ,last_name
229
          ,user_account_id
230
          FROM user_account
231
          WHERE user_account_id = :user_account_id");
232
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
233
      $statement->execute();
234
      return $statement->fetch(PDO::FETCH_ASSOC);
235
  }
236
237
  /**
238
   * Get Addresses
239
   *
240
   * Run a query to retrieve one user's addresses from the database.
241
   *
242
   * @param       int $user_account_id    The data value
243
   * @return      array|bool              The query result
244
   */
245 View Code Duplication
  public function get_addresses($user_account_id = false)
246
  {
247
      $statement = $this->db->prepare("SELECT *
248
          FROM user_account_addresses
249
          WHERE user_account_id = :user_account_id");
250
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
251
      $statement->execute();
252
      return $statement->fetchAll(PDO::FETCH_ASSOC);
253
  }
254
255
  /**
256
   * Insert Addresses
257
   *
258
   * Run a query to insert addresses into the database.
259
   *
260
   * @param       array $data                    The array
261
   * @param       int $user_account_id           The data value
262
   * @param       int $editor_user_account_id    The data value
263
   * @return      void
264
   */
265
  public function insert_addresses($data, $user_account_id, $editor_user_account_id)
266
  {
267
      $address_data = array();
268
      $address_fields = array(
269
          "label"
270
          ,"address_1"
271
          ,"address_2"
272
          ,"city"
273
          ,"state"
274
          ,"zip"
275
      );
276
277
      if (isset($data["address_count"])) {
278
          // First, delete all user's addresses.
279
          $statement = $this->db->prepare("
280
              DELETE FROM user_account_addresses
281
              WHERE user_account_id = :user_account_id");
282
          $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
283
          $statement->execute();
284
285
          for ($i=1; $i <= $data["address_count"]; $i++) {
286
              foreach ($address_fields as $field) {
287
                  $address_data[$field] = $data[$field][$i];
288
              }
289
290
              $statement = $this->db->prepare("
291
              INSERT INTO user_account_addresses
292
                  (user_account_id
293
                  ,address_label
294
                  ,address_1
295
                  ,address_2
296
                  ,city
297
                  ,state
298
                  ,zip
299
                  ,date_created
300
                  ,created_by_user_account_id
301
                  ,last_modified_user_account_id)
302
              VALUES
303
                  (:user_account_id
304
                  ,:address_label
305
                  ,:address_1
306
                  ,:address_2
307
                  ,:city
308
                  ,:state
309
                  ,:zip
310
                  ,NOW()
311
                  ,:editor_user_account_id
312
                  ,:editor_user_account_id)");
313
              $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
314
              $statement->bindValue(":address_label", $address_data["label"], PDO::PARAM_STR);
315
              $statement->bindValue(":address_1", $address_data["address_1"], PDO::PARAM_STR);
316
              $statement->bindValue(":address_2", $address_data["address_2"], PDO::PARAM_STR);
317
              $statement->bindValue(":city", $address_data["city"], PDO::PARAM_STR);
318
              $statement->bindValue(":state", $address_data["state"], PDO::PARAM_STR);
319
              $statement->bindValue(":zip", $address_data["zip"], PDO::PARAM_STR);
320
              $statement->bindValue(":editor_user_account_id", $editor_user_account_id, PDO::PARAM_INT);
321
              $statement->execute();
322
          }
323
      }
324
  }
325
326
  /**
327
   * Insert/Update User Account
328
   *
329
   * Run queries to insert and update user accounts in the database.
330
   *
331
   * @uses        UaserAccount::$this->delete_user_groups
332
   * @param       array $data                                   The array
333
   * @param       int $user_account_id                          The data value
334
   * @param       bool $update_groups                           True/False
335
   * @param       int $proxy_role_id                            The data value
336
   * @param       bool $role_perm_manage_all_accounts_access    The data value
337
   * @return      void
338
   */
339
  public function insert_update_user_account(
340
      $data
341
      ,$user_account_id
342
      ,$update_groups = true
343
      ,$proxy_role_id = false
344
      ,$role_perm_manage_all_accounts_access = false
345
  ) {
346
      // Update
347
      $statement = $this->db->prepare("
348
          UPDATE user_account
349
          SET user_account_email = :user_account_email
350
          ,first_name = :first_name
351
          ,last_name = :last_name
352
          ,modified_date = NOW()
353
          WHERE user_account_id = :user_account_id"
354
      );
355
      $statement->bindValue(":user_account_email", $data["user_account_email"], PDO::PARAM_STR);
356
      $statement->bindValue(":first_name", $data["first_name"], PDO::PARAM_STR);
357
      $statement->bindValue(":last_name", $data["last_name"], PDO::PARAM_STR);
358
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
359
      $statement->execute();
360
      // Update the password if user has entered one.
361
      if (!empty($data["user_account_password"])) {
362
          $statement = $this->db->prepare("
363
              UPDATE user_account
364
              SET user_account_password = :user_account_password
365
              ,modified_date = NOW()
366
              WHERE user_account_id = :user_account_id"
367
          );
368
          $statement->bindValue(":user_account_password", $data["user_account_password"], PDO::PARAM_STR);
369
          $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
370
          $statement->execute();
371
      }
372
373
      if ($update_groups && $role_perm_manage_all_accounts_access) {
374
375
          // Remove all groups/roles because we are going to add them all back in.
376
          $this->delete_user_groups($user_account_id);
377
378
          if (isset($data["group_data"]) && $data["group_data"]) {
379
              $group_array = array_filter(json_decode($data["group_data"], true));
380
              foreach ($group_array as $single_group_data) {
381
                  if (!empty($single_group_data) && !empty($single_group_data["roles"])) {
382
                      foreach ($single_group_data["roles"] as $single_role) {
383
                          $statement = $this->db->prepare("
384
                              INSERT INTO user_account_groups
385
                              (role_id
386
                              ,user_account_id
387
                              ,group_id)
388
                              VALUES
389
                              (:role_id
390
                              ,:user_account_id
391
                              ,:group_id)");
392
                          $statement->bindValue(":role_id", $single_role, PDO::PARAM_INT);
393
                          $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
394
                          $statement->bindValue(":group_id", $single_group_data["group_id"], PDO::PARAM_INT);
395
                          $statement->execute();
396
397
                          if ($single_role == $proxy_role_id) {
398
                              if (!empty($single_group_data["proxy_users"])) {
399
                                  $user_account_groups_id = $this->db->lastInsertId();
400
                                  foreach ($single_group_data["proxy_users"] as $single_proxy_user) {
401
                                      $statement = $this->db->prepare("
402
                                          INSERT INTO user_account_proxy
403
                                          (user_account_groups_id
404
                                          ,proxy_user_account_id)
405
                                          VALUES
406
                                          (:user_account_groups_id
407
                                          ,:proxy_user_account_id)");
408
                                      $statement->bindValue(":user_account_groups_id", $user_account_groups_id, PDO::PARAM_INT);
409
                                      $statement->bindValue(":proxy_user_account_id", $single_proxy_user["user_account_id"], PDO::PARAM_INT);
410
                                      $statement->execute();
411
                                  }
412
                              }
413
                          }
414
                      }
415
                  }
416
              }
417
          }
418
      }
419
  }
420
421
  /**
422
   * Find User Account
423
   *
424
   * Run a query to search the database for user accounts.
425
   *
426
   * @param       string $search                 The data value
427
   * @return      array|bool                     The query result
428
   */
429 View Code Duplication
  public function find_user_account( $search )
430
  {
431
      $statement = $this->db->prepare("
432
          SELECT CONCAT(first_name, ' ', last_name) AS displayname
433
              ,first_name
434
              ,last_name
435
              ,user_account_id
436
          FROM user_account
437
          WHERE first_name LIKE :search
438
          OR last_name LIKE :search
439
          LIMIT 20");
440
      $statement->bindValue(":search", "%".$search ."%", PDO::PARAM_STR);
441
      $statement->execute();
442
      return $statement->fetchAll(PDO::FETCH_ASSOC);
443
  }
444
445
  /**
446
   * Delete User Account
447
   *
448
   * Run a query to delete a user account, and groups, from the database.
449
   *
450
   * @param       int $user_account_id           The data value
451
   * @return      void
452
   */
453 View Code Duplication
  public function delete_user_account( $user_account_id )
454
  {
455
      // Delete the user from the user_account table.
456
      $statement = $this->db->prepare("DELETE FROM user_account
457
          WHERE user_account_id = :user_account_id");
458
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
459
      $statement->execute();
460
461
      // Delete the user from the user_account_groups table.
462
      $this->delete_user_groups( $user_account_id );
463
  }
464
465
  /**
466
   * Delete User Groups
467
   *
468
   * Run a query to delete a user account's groups from the database.
469
   *
470
   * @param       int $user_account_id           The data value
471
   * @return      void
472
   */
473
  public function delete_user_groups( $user_account_id )
474
  {
475
      $statement = $this->db->prepare("DELETE FROM user_account_groups
476
          WHERE user_account_id = :user_account_id");
477
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
478
      $statement->execute();
479
  }
480
481
  /**
482
   * Get User Roles List
483
   *
484
   * Run a query to retrieve a user account's roles.
485
   *
486
   * @param       int $user_account_id           The data value
487
   * @return      array|bool                     The query result
488
   */
489 View Code Duplication
  public function get_user_roles_list( $user_account_id )
490
  {
491
      $statement = $this->db->prepare("SELECT DISTINCT role_id
492
          FROM user_account_groups
493
          WHERE user_account_id = :user_account_id");
494
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
495
      $statement->execute();
496
      return $statement->fetchAll(PDO::FETCH_ASSOC);
497
  }
498
499
  /**
500
   * Update Acceptable Use Policy
501
   *
502
   * Run a query to update a user account's acceptable use policy.
503
   *
504
   * @param       int $user_account_id    The data value
505
   * @param       int $value              The data value
506
   * @return      void
507
   */
508
  public function update_acceptable_use_policy( $user_account_id, $value )
509
  {
510
      $statement = $this->db->prepare("UPDATE user_account
511
          SET acceptable_use_policy = :acceptable_use_policy
512
          WHERE user_account_id = :user_account_id");
513
      $statement->bindValue(":acceptable_use_policy", $value, PDO::PARAM_INT);
514
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
515
      $statement->execute();
516
  }
517
518
  /**
519
   * Get User's Proxies For Groups
520
   *
521
   * Run a query to retrieve all the proxies that the user is associated with for a specific group.
522
   *
523
   * @param       int $user_account_id    The data value
524
   * @param       int $group_id           The data value
525
   * @return      array|bool              The query result
526
   */
527 View Code Duplication
  public function get_users_proxies_for_group( $user_account_id, $group_id )
528
  {
529
      $statement = $this->db->prepare("SELECT 
530
              CONCAT(user_account.first_name, ' ', user_account.last_name) AS displayname
531
              ,user_account.user_account_id
532
          FROM user_account_groups
533
          RIGHT JOIN user_account_proxy ON user_account_proxy.user_account_groups_id = user_account_groups.user_account_groups_id
534
          LEFT JOIN user_account ON user_account.user_account_id = user_account_proxy.proxy_user_account_id
535
          WHERE user_account_groups.user_account_id = :user_account_id
536
          AND user_account_groups.group_id = :group_id");
537
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
538
      $statement->bindValue(":group_id", $group_id, PDO::PARAM_INT);
539
      $statement->execute();
540
      return $statement->fetchAll(PDO::FETCH_ASSOC);
541
  }
542
543
  /**
544
   * Get User Group Roles Map
545
   *
546
   * Run queries to retrieve a user's current group values.
547
   *
548
   * @uses        UserAccount::$this->get_user_account_groups
549
   * @uses        UserAccount::$this->get_user_group_roles
550
   * @uses        UserAccount::$this->get_users_proxies_for_group
551
   * @param       int $user_account_id    The data value
552
   * @param       int $proxy_id           The data value
553
   * @return      array|bool              The query result
554
   */
555
  public function get_user_group_roles_map( $user_account_id, $proxy_id = false )
556
  {
557
      $current_group_values = $this->get_user_account_groups($user_account_id);
558
559
      if(is_array($current_group_values) && !empty($current_group_values)) {
560
          foreach ($current_group_values as $index => $single_group) {
561
              $roles_array = array();
562
              $selected_roles = $this->get_user_group_roles($user_account_id, $single_group["group_id"]);
563
              $proxy_users = array();
564
              if(is_array($selected_roles) && !empty($selected_roles)) {
565
                  foreach ($selected_roles as $single_role) {
566
                      $roles_array[] = $single_role["role_id"];
567
                      if (!empty($proxy_id) && $single_role["role_id"] == $proxy_id) {
568
                          $proxy_users = $this->get_users_proxies_for_group($user_account_id, $single_group["group_id"]);
569
                      }
570
                  }
571
              }
572
              $current_group_values[$index]["roles"] = $roles_array;
573
              $current_group_values[$index]["proxy_users"] = $proxy_users;
574
          }
575
      }
576
      return $current_group_values;
577
  }
578
579
  /**
580
   * Has Role
581
   *
582
   * Run a query to determine if a user has a role.
583
   * If assigned a role for a group, that role applies to all of that group's decendants.
584
   *
585
   * @param       int $user_account_id    The data value
586
   * @param       array $roles            The data value
587
   * @param       int $group_id           The data value
588
   * @return      array|bool              The query result
589
   */
590
  public function has_role( $user_account_id, $roles = array(), $group_id = false )
591
  {
592
      $statement = $this->db->prepare("SELECT ancestor
593
          FROM group_closure_table
594
          LEFT JOIN user_account_groups ON user_account_groups.group_id = group_closure_table.ancestor
595
          WHERE descendant = :group_id
596
          AND user_account_groups.role_id IN (" . implode(",", $roles) . ")
597
          AND user_account_groups.user_account_id = :user_account_id");
598
      $statement->bindValue(":group_id", $group_id, PDO::PARAM_INT);
599
      $statement->bindValue(":user_account_id", $user_account_id, PDO::PARAM_INT);
600
      $statement->execute();
601
      return $statement->fetchAll(PDO::FETCH_ASSOC);
602
  }
603
  
604
}
605