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.

Admin::deleteUser()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 9
nc 3
nop 2
1
<?php
2
3
 /**
4
  * Admin Class
5
  * Admin Class inherits from User.
6
  *
7
  * @license    http://opensource.org/licenses/MIT The MIT License (MIT)
8
  * @author     Omar El Gabry <[email protected]>
9
  */
10
11
class Admin extends User{
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
13
    /**
14
     * get all users in the database
15
     *
16
     * @access public
17
     * @param  string  $name
18
     * @param  string  $email
19
     * @param  string  $role
20
     * @param  integer $pageNum
21
     * @return array
22
     *
23
     */
24
    public function getUsers($name = null, $email = null, $role = null, $pageNum = 1){
25
26
        // validate user inputs
27
        $validation = new Validation();
28 View Code Duplication
        if(!$validation->validate([
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
29
            'User Name' => [$name,  'alphaNumWithSpaces|maxLen(30)'],
30
            'Email'     => [$email, 'email|maxLen(50)'],
31
            'Role'      => [$role,  'inArray(admin, user)']])){
32
            $this->errors  = $validation->errors();
33
            return false;
34
        }
35
36
        // in $options array, add all possible values from user, and their name parameters
37
        // then applyOptions() method will see if value is not empty, then add it to our query
38
        $options = [
39
            $name      => "name LIKE :name ",
40
            $email     => "email = :email ",
41
            $role      => "role = :role "
42
        ];
43
44
        // get options query
45
        $options = $this->applyOptions($options, "AND ");
46
        $options = empty($options)? "": "WHERE " . $options;
47
48
        $values = [];
49
        if (!empty($name))  $values[":name"]  = "%". $name ."%";
50
        if (!empty($email)) $values[":email"] = $email;
51
        if (!empty($role))  $values[":role"]  = $role;
52
53
        // get pagination object so that we can add offset and limit in our query
54
        $pagination = Pagination::pagination("users", $options, $values, $pageNum);
55
        $offset     = $pagination->getOffset();
56
        $limit      = $pagination->perPage;
57
58
        $database   = Database::openConnection();
59
        $query   = "SELECT id, name, email, role, is_email_activated FROM users ";
60
        $query  .= $options;
61
        $query  .= "LIMIT $limit OFFSET $offset";
62
63
        $database->prepare($query);
64
        $database->execute($values);
65
        $users = $database->fetchAllAssociative();
66
67
        return array("users" => $users, "pagination" => $pagination);
68
     }
69
70
    /**
71
     *  Update info of a passed user id
72
     *
73
     * @access public
74
     * @param  integer $userId
75
     * @param  integer $adminId
76
     * @param  string  $name
77
     * @param  string  $password
78
     * @param  string  $role
79
     * @return bool
80
     * @throws Exception If password couldn't be updated
81
     *
82
     */
83
    public function updateUserInfo($userId, $adminId, $name, $password, $role){
84
85
         $user = $this->getProfileInfo($userId);
86
87
         $name = (!empty($name) && $name !== $user["name"])? $name: null;
88
         $role = (!empty($role) && $role !== $user["role"])? $role: null;
89
90
         // current admin can't change his role,
91
         // changing the role requires to logout or reset session,
92
         // because role is stored in the session
93
         if(!empty($role) && $adminId === $user["id"]){
94
             $this->errors[] = "You can't change your role";
95
             return false;
96
         }
97
98
        $validation = new Validation();
99 View Code Duplication
        if(!$validation->validate([
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
100
             "Name" => [$name, "alphaNumWithSpaces|minLen(4)|maxLen(30)"],
101
             "Password" => [$password, "minLen(6)|password"],
102
             'Role' => [$role, "inArray(admin, user)"]])){
103
             $this->errors = $validation->errors();
104
             return false;
105
         }
106
107
         if($password || $name || $role) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null 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...
Bug Best Practice introduced by
The expression $role of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null 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...
108
109
             $options = [
110
                 $name     => "name = :name ",
111
                 $password => "hashed_password = :hashed_password ",
112
                 $role     => "role = :role "
113
             ];
114
115
             $database = Database::openConnection();
116
             $query   = "UPDATE users SET ";
117
             $query  .= $this->applyOptions($options, ", ");
118
             $query  .= "WHERE id = :id LIMIT 1 ";
119
             $database->prepare($query);
120
121
             if($name) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null 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...
122
                 $database->bindValue(':name', $name);
123
             }
124 View Code Duplication
             if($password) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
125
                 $database->bindValue(':hashed_password', password_hash($password, PASSWORD_DEFAULT, array('cost' => Config::get('HASH_COST_FACTOR'))));
126
             }
127
             if($role){
0 ignored issues
show
Bug Best Practice introduced by
The expression $role of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null 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...
128
                 $database->bindValue(':role', $role);
129
             }
130
131
             $database->bindValue(':id', $userId);
132
             $result = $database->execute();
133
134
             if(!$result){
135
                 throw new Exception("Couldn't update profile");
136
             }
137
         }
138
139
         return true;
140
     }
141
142
    /**
143
     * Delete a user.
144
     *
145
     * @param  string  $adminId
146
     * @param  integer $userId
147
     * @throws Exception
148
     */
149
    public function deleteUser($adminId, $userId){
150
151
        // current admin can't delete himself
152
        $validation = new Validation();
153
        if(!$validation->validate([ 'User ID' => [$userId, "notEqual(".$adminId.")"]])) {
154
            $this->errors  = $validation->errors();
155
            return false;
156
        }
157
158
        $database = Database::openConnection();
159
        $database->deleteById("users", $userId);
160
161
        if ($database->countRows() !== 1) {
162
            throw new Exception ("Couldn't delete user");
163
        }
164
    }
165
166
     /**
167
      * Counting the number of users in the database.
168
      *
169
      * @access public
170
      * @static static  method
171
      * @return integer number of users
172
      *
173
      */
174
     public function countUsers(){
175
         return $this->countAll("users");
0 ignored issues
show
Unused Code introduced by
The call to Admin::countAll() has too many arguments starting with 'users'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
176
     }
177
178
     /**
179
      * Get the backup file from the backup directory in file system
180
      *
181
      * @access public
182
      * @return array
183
      */
184
     public function getBackups() {
185
186
         $files = scandir(APP . "backups/");
187
         $basename = $filename = $unixTimestamp = null;
188
189
         foreach ($files as $file) {
190
             if ($file != "." && $file != "..") {
191
192
                 $filename_array = explode('-', pathinfo($file, PATHINFO_FILENAME));
193
                 if(count($filename_array) !== 2){
194
                     continue;
195
                 }
196
197
                 // backup file has name with something like this: backup-1435788336
198
                 list($filename, $unixTimestamp) = $filename_array;
199
                 $basename = $file;
200
                 break;
201
             }
202
         }
203
204
         $data = array("basename" => $basename, "filename" => $filename, "date" => "On " . date("F j, Y", $unixTimestamp));
205
         return $data;
206
     }
207
208
    /**
209
     * Update the backup file from the backup directory in file system
210
     * The user of the database MUST be assigned privilege of ADMINISTRATION -> LOCK TABLES.
211
     *
212
     * @access public
213
     * @return bool
214
     */
215
    public function updateBackup(){
216
217
         $dir = APP . "backups/";
218
         $files = scandir($dir);
219
220
         // delete and clean all current files in backup directory
221
         foreach ($files as $file) {
222
             if ($file != "." && $file != "..") {
223
                 if (is_file("$dir/$file")) {
224
                     Uploader::deleteFile("$dir/$file");
225
                 }
226
             }
227
         }
228
229
         // you can use another username and password only for this function, while the main user has limited privileges
230
         $windows = true;
231
         if($windows){
232
             exec('C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump --user=' . escapeshellcmd(Config::get('DB_USER')) . ' --password=' . escapeshellcmd(Config::get('DB_PASS')) . ' ' . escapeshellcmd(Config::get('DB_NAME')) . ' > '. APP.'backups\backup-' . time() . '.sql');
233 View Code Duplication
         }else{
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
234
             exec('mysqldump --user=' . escapeshellcmd(Config::get('DB_USER')) . ' --password=' .escapeshellcmd(Config::get('DB_PASS')). ' '. escapeshellcmd(Config::get('DB_NAME')) .' > '. APP . 'backups/backup-' . time() . '.sql');
235
         }
236
237
         return true;
238
     }
239
240
    /**
241
     * Restore the backup file
242
     * The user of the database MUST assigned all privileges of SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP, LOCK TABLES, & TRIGGER.
243
     *
244
     * @access public
245
     * @return bool
246
     *
247
     */
248
    public function restoreBackup(){
249
250
         $basename = $this->getBackups()["basename"];
251
252
         $validation = new Validation();
253
         $validation->addRuleMessage("required", "Please update backups first!");
254
255
         if(!$validation->validate(["Backup" => [$basename, "required"]])) {
256
             $this->errors = $validation->errors();
257
             return false;
258
         }
259
260
         $windows = true;
261
         if($windows){
262
             exec('C:\wamp\bin\mysql\mysql5.6.17\bin\mysql --user=' . escapeshellcmd(Config::get('DB_USER')) . ' --password=' . escapeshellcmd(Config::get('DB_PASS')) . ' ' . escapeshellcmd(Config::get('DB_NAME')) . ' < '.APP.'\backups\\' . $basename);
263 View Code Duplication
         }else{
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
264
             exec('mysql --user='.escapeshellcmd(Config::get('DB_USER')).' --password='.escapeshellcmd(Config::get('DB_PASS')).' '.escapeshellcmd(Config::get('DB_NAME')).' < '. APP . 'backups/' . $basename);
265
         }
266
267
         return true;
268
     }
269
270
    /**
271
     * get users data.
272
     * Use this method to download users info in database as csv file.
273
     *
274
     * @access public
275
     * @return array
276
     */
277
    public function getUsersData(){
278
279
        $database = Database::openConnection();
280
281
        $database->prepare("SELECT name, role, email, is_email_activated FROM users");
282
        $database->execute();
283
284
        $users = $database->fetchAllAssociative();
285
        $cols  = array("User Name", "Role", "Email", "is Email Activated?");
286
287
        return ["rows" => $users, "cols" => $cols, "filename" => "users"];
288
    }
289
290
 }
291