| Conditions | 9 |
| Paths | 41 |
| Total Lines | 154 |
| Code Lines | 73 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 84 | public function resultAction(Request $request, $project, $start = null, $end = null) |
||
| 85 | { |
||
| 86 | // Load the database information for the tool. |
||
| 87 | // $projectData will be a redirect if the project is invalid. |
||
| 88 | $projectData = $this->validateProject($project); |
||
| 89 | if ($projectData instanceof RedirectResponse) { |
||
| 90 | return $projectData; |
||
| 91 | } |
||
| 92 | |||
| 93 | list($start, $end) = $this->getUTCFromDateParams($start, $end); |
||
| 94 | |||
| 95 | // Initialize variables - prevents variable undefined errors |
||
| 96 | $adminIdArr = []; |
||
| 97 | $adminsWithoutAction = 0; |
||
| 98 | $adminsWithoutActionPct = 0; |
||
| 99 | |||
| 100 | // Pull the API helper and database. Then check if we can use this tool |
||
| 101 | $api = $this->get('app.api_helper'); |
||
| 102 | $conn = $this->get('doctrine')->getManager('replicas')->getConnection(); |
||
| 103 | |||
| 104 | // Generate a diff for the dates - this is the number of days we're spanning. |
||
| 105 | $days = ($end - $start) / 60 / 60 / 24; |
||
| 106 | |||
| 107 | // Get admin ID's, used to account for inactive admins |
||
| 108 | $userGroupsTable = $projectData->getTableName('user_groups'); |
||
| 109 | $ufgTable = $projectData->getTableName('user_former_groups'); |
||
| 110 | $query = " |
||
| 111 | SELECT ug_user AS user_id |
||
| 112 | FROM $userGroupsTable |
||
| 113 | WHERE ug_group = 'sysop' |
||
| 114 | UNION |
||
| 115 | SELECT ufg_user AS user_id |
||
| 116 | FROM $ufgTable |
||
| 117 | WHERE ufg_group = 'sysop' |
||
| 118 | "; |
||
| 119 | |||
| 120 | $res = $conn->prepare($query); |
||
| 121 | $res->execute(); |
||
| 122 | |||
| 123 | // Iterate over query results, loading each user id into the array |
||
| 124 | while ($row = $res->fetch()) { |
||
| 125 | $adminIdArr[] = $row['user_id'] ; |
||
| 126 | } |
||
| 127 | |||
| 128 | // Set the query results to be useful in a sql statement. |
||
| 129 | $adminIds = implode(',', $adminIdArr); |
||
| 130 | |||
| 131 | // Load up the tables we need and run the mega query. |
||
| 132 | // This query provides all of the statistics |
||
| 133 | $userTable = $projectData->getTableName('user'); |
||
| 134 | $loggingTable = $projectData->getTableName('logging', 'userindex'); |
||
| 135 | |||
| 136 | $startDb = date('Ymd000000', $start); |
||
| 137 | $endDb = date('Ymd235959', $end); |
||
| 138 | |||
| 139 | // TODO: Fix this - inactive admins aren't getting shown |
||
| 140 | $query = " |
||
| 141 | SELECT user_name, user_id, |
||
| 142 | SUM(IF( (log_type = 'delete' AND log_action != 'restore'),1,0)) AS mdelete, |
||
| 143 | SUM(IF( (log_type = 'delete' AND log_action = 'restore'),1,0)) AS mrestore, |
||
| 144 | SUM(IF( (log_type = 'block' AND log_action != 'unblock'),1,0)) AS mblock, |
||
| 145 | SUM(IF( (log_type = 'block' AND log_action = 'unblock'),1,0)) AS munblock, |
||
| 146 | SUM(IF( (log_type = 'protect' AND log_action != 'unprotect'),1,0)) AS mprotect, |
||
| 147 | SUM(IF( (log_type = 'protect' AND log_action = 'unprotect'),1,0)) AS munprotect, |
||
| 148 | SUM(IF( log_type = 'rights',1,0)) AS mrights, |
||
| 149 | SUM(IF( log_type = 'import',1,0)) AS mimport, |
||
| 150 | SUM(IF(log_type != '',1,0)) AS mtotal |
||
| 151 | FROM $loggingTable |
||
| 152 | JOIN $userTable ON user_id = log_user |
||
| 153 | WHERE log_timestamp > '$startDb' AND log_timestamp <= '$endDb' |
||
| 154 | AND log_type IS NOT NULL |
||
| 155 | AND log_action IS NOT NULL |
||
| 156 | AND log_type IN ('block', 'delete', 'protect', 'import', 'rights') |
||
| 157 | GROUP BY user_name |
||
| 158 | HAVING mdelete > 0 OR user_id IN ($adminIds) |
||
| 159 | ORDER BY mtotal DESC"; |
||
| 160 | |||
| 161 | $res = $conn->prepare($query); |
||
| 162 | $res->execute(); |
||
| 163 | |||
| 164 | // Fetch all the information out. Because of pre-processing done |
||
| 165 | // in the query, we can use this practically raw. |
||
| 166 | $users = $res->fetchAll(); |
||
| 167 | |||
| 168 | // Pull the admins from the API, for merging. |
||
| 169 | $admins = $api->getAdmins($project); |
||
| 170 | |||
| 171 | // Get the total number of admins, the number of admins without |
||
| 172 | // action, and then later we'll run percentage calculations |
||
| 173 | $adminCount = count($admins); |
||
| 174 | |||
| 175 | // Combine the two arrays. We can't use array_merge here because |
||
| 176 | // the arrays contain fundamentally different data. Instead, it's |
||
| 177 | // done by hand. Only two values are needed, edit count and groups. |
||
| 178 | foreach ($users as $key => $value) { |
||
| 179 | $username = $value['user_name']; |
||
| 180 | |||
| 181 | if (empty($admins[$username])) { |
||
| 182 | $admins[$username] = [ |
||
| 183 | 'groups' => '', |
||
| 184 | ]; |
||
| 185 | } |
||
| 186 | $users[$key]['groups'] = $admins[$username]['groups']; |
||
| 187 | |||
| 188 | if ($users[$key]['mtotal'] === 0) { |
||
| 189 | $adminsWithoutAction++; |
||
| 190 | } |
||
| 191 | |||
| 192 | unset($admins[$username]); |
||
| 193 | } |
||
| 194 | |||
| 195 | // push any inactive admins back to $users with zero values |
||
| 196 | if (count($admins)) { |
||
| 197 | foreach ($admins as $username => $stats) { |
||
| 198 | $users[] = [ |
||
| 199 | 'user_name' => $username, |
||
| 200 | 'mdelete' => 0, |
||
| 201 | 'mrestore' => 0, |
||
| 202 | 'mblock' => 0, |
||
| 203 | 'munblock' => 0, |
||
| 204 | 'mprotect' => 0, |
||
| 205 | 'munprotect' => 0, |
||
| 206 | 'mrights' => 0, |
||
| 207 | 'mimport' => 0, |
||
| 208 | 'mtotal' => 0, |
||
| 209 | 'groups' => $stats['groups'], |
||
| 210 | ]; |
||
| 211 | $adminsWithoutAction++; |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | if ($adminCount > 0) { |
||
| 216 | $adminsWithoutActionPct = ($adminsWithoutAction / $adminCount) * 100; |
||
| 217 | } |
||
| 218 | |||
| 219 | // Render the result! |
||
| 220 | return $this->render('adminStats/result.html.twig', [ |
||
| 221 | 'xtPage' => 'adminstats', |
||
| 222 | 'xtTitle' => $project, |
||
| 223 | |||
| 224 | 'project' => $projectData, |
||
| 225 | |||
| 226 | 'start_date' => date('Y-m-d', $start), |
||
| 227 | 'end_date' => date('Y-m-d', $end), |
||
| 228 | 'days' => $days, |
||
| 229 | |||
| 230 | 'adminsWithoutAction' => $adminsWithoutAction, |
||
| 231 | 'admins_without_action_pct' => $adminsWithoutActionPct, |
||
| 232 | 'adminCount' => $adminCount, |
||
| 233 | |||
| 234 | 'users' => $users, |
||
| 235 | 'usersCount' => count($users), |
||
| 236 | ]); |
||
| 237 | } |
||
| 238 | } |
||
| 239 |
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.