Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php namespace BB\Http\Controllers; |
||
| 13 | class ACSController extends Controller |
||
| 14 | { |
||
| 15 | |||
| 16 | /** |
||
| 17 | * @var ACSNodeRepository |
||
| 18 | */ |
||
| 19 | private $deviceRepository; |
||
|
|
|||
| 20 | /** |
||
| 21 | * @var ACSValidator |
||
| 22 | */ |
||
| 23 | private $ACSValidator; |
||
| 24 | /** |
||
| 25 | * @var \BB\Services\KeyFobAccess |
||
| 26 | */ |
||
| 27 | private $keyFobAccess; |
||
| 28 | /** |
||
| 29 | * @var EquipmentLogRepository |
||
| 30 | */ |
||
| 31 | private $equipmentLogRepository; |
||
| 32 | |||
| 33 | function __construct(ACSNodeRepository $acsNodeRepository, ACSValidator $ACSValidator, \BB\Services\KeyFobAccess $keyFobAccess, EquipmentLogRepository $equipmentLogRepository) { |
||
| 34 | $this->acsNodeRepository = $acsNodeRepository; |
||
| 35 | $this->ACSValidator = $ACSValidator; |
||
| 36 | $this->keyFobAccess = $keyFobAccess; |
||
| 37 | $this->equipmentLogRepository = $equipmentLogRepository; |
||
| 38 | } |
||
| 39 | |||
| 40 | public function store() |
||
| 41 | { |
||
| 42 | $data = \Request::only('device', 'service', 'message', 'tag', 'time', 'payload', 'signature', 'nonce', 'session_id'); |
||
| 43 | |||
| 44 | //device = the node id from the acs table - unique to each acs |
||
| 45 | //service = what the request is for, entry, usage, consumable |
||
| 46 | //message = system message, heartbeat, boot |
||
| 47 | //tag = the keyfob id |
||
| 48 | //time = the time of the action |
||
| 49 | //payload = any extra data relavent to the request |
||
| 50 | //signature = an encoded value generated using a secret key - oauth style |
||
| 51 | //nonce = a unique value suitable to stop replay attacks |
||
| 52 | //session_id = the id of the current session the user is maintaining |
||
| 53 | |||
| 54 | $this->ACSValidator->validate($data); |
||
| 55 | |||
| 56 | |||
| 57 | //System messages |
||
| 58 | if (in_array($data['message'], ['boot', 'heartbeat'])) { |
||
| 59 | return $this->handleSystemCheckIn($data['message'], $data['device'], $data['service']); |
||
| 60 | } |
||
| 61 | |||
| 62 | |||
| 63 | switch ($data['service']) { |
||
| 64 | case 'entry': |
||
| 65 | return $this->handleDoor($data); |
||
| 66 | case 'usage': |
||
| 67 | return $this->handleDevice($data); |
||
| 68 | case 'consumable': |
||
| 69 | |||
| 70 | break; |
||
| 71 | case 'shop': |
||
| 72 | |||
| 73 | break; |
||
| 74 | case 'status': |
||
| 75 | return $this->handleStatus($data); |
||
| 76 | |||
| 77 | break; |
||
| 78 | default: |
||
| 79 | \Log::debug(json_encode($data)); |
||
| 80 | } |
||
| 81 | |||
| 82 | } |
||
| 83 | |||
| 84 | View Code Duplication | private function handleStatus($data) |
|
| 85 | { |
||
| 86 | try { |
||
| 87 | /** @var User $user */ |
||
| 88 | $user = $this->keyFobAccess->verifyForEntry($data['tag'], 'main-door', $data['time']); |
||
| 89 | } catch (\Exception $e) { |
||
| 90 | return $this->sendResponse(404, []); |
||
| 91 | } |
||
| 92 | |||
| 93 | return $this->sendResponse(200, ['member' => $user->given_name]); |
||
| 94 | } |
||
| 95 | |||
| 96 | View Code Duplication | private function handleDoor($data) |
|
| 97 | { |
||
| 98 | //Door entry is quite simple - this will just deal with lookups |
||
| 99 | |||
| 100 | try { |
||
| 101 | /** @var User $user */ |
||
| 102 | $user = $this->keyFobAccess->verifyForEntry($data['tag'], 'main-door', $data['time']); |
||
| 103 | $this->keyFobAccess->logSuccess(); |
||
| 104 | } catch (\Exception $e) { |
||
| 105 | return $this->sendResponse(404, []); |
||
| 106 | } |
||
| 107 | |||
| 108 | return $this->sendResponse(200, ['member' => $user->given_name]); |
||
| 109 | } |
||
| 110 | |||
| 111 | |||
| 112 | private function handleDevice($data) |
||
| 113 | { |
||
| 114 | $sessionId = null; |
||
| 115 | try { |
||
| 116 | $device = ACSNode::where('device_id', $data['device'])->firstOrFail(); |
||
| 117 | if ($device->entry_device) { |
||
| 118 | return $this->sendResponse(400, ['message' => 'This is an entry device only']); |
||
| 119 | } else { |
||
| 120 | $member = $this->keyFobAccess->verifyForDevice($data['tag'], $data['device'], $data['time']); |
||
| 121 | $keyFob = $this->keyFobAccess->getKeyFob(); |
||
| 122 | |||
| 123 | if ($data['message'] == 'start') { |
||
| 124 | $sessionId = $this->equipmentLogRepository->recordStartCloseExisting($keyFob->user->id, $keyFob->id, $data['device']); |
||
| 125 | event(new MemberActivity($keyFob, $data['device'])); |
||
| 126 | } elseif ($data['message'] == 'stop') { |
||
| 127 | if (empty($data['session_id'])) { |
||
| 128 | $data['session_id'] = $this->equipmentLogRepository->findActiveUserSession($keyFob->user->id, $data['device']); |
||
| 129 | } |
||
| 130 | if (empty($data['session_id'])) { |
||
| 131 | return $this->sendResponse(404, ['message' => 'No active session to close']); |
||
| 132 | } |
||
| 133 | $this->equipmentLogRepository->endSession($data['session_id']); |
||
| 134 | } |
||
| 135 | } |
||
| 136 | } catch (ValidationException $e) { |
||
| 137 | return $this->sendResponse(400, ['message' => $e->getMessage()]); |
||
| 138 | } |
||
| 139 | return $this->sendResponse(200, ['member' => $member->given_name, 'session_id' => $sessionId]); |
||
| 140 | } |
||
| 141 | |||
| 142 | /** |
||
| 143 | * System checkins are common across all devices |
||
| 144 | * Record the time and return pending status messages |
||
| 145 | * |
||
| 146 | * @param $message |
||
| 147 | * @param $device |
||
| 148 | * @return Response |
||
| 149 | */ |
||
| 150 | private function handleSystemCheckIn($message, $device, $service) |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Json encode the response data and return |
||
| 184 | * |
||
| 185 | * @param int $statusCode |
||
| 186 | * @param array $responseData |
||
| 187 | * |
||
| 188 | * @return \Response |
||
| 189 | */ |
||
| 190 | private function sendResponse($statusCode = 200, array $responseData) |
||
| 197 | |||
| 198 | } |
||
| 199 |
This check marks private properties in classes that are never used. Those properties can be removed.