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 |
||
| 49 | class AvatarController extends Controller { |
||
| 50 | |||
| 51 | /** @var IAvatarManager */ |
||
| 52 | protected $avatarManager; |
||
| 53 | |||
| 54 | /** @var \OC\Cache\File */ |
||
| 55 | protected $cache; |
||
| 56 | |||
| 57 | /** @var IL10N */ |
||
| 58 | protected $l; |
||
| 59 | |||
| 60 | /** @var IUserManager */ |
||
| 61 | protected $userManager; |
||
| 62 | |||
| 63 | /** @var IUserSession */ |
||
| 64 | protected $userSession; |
||
| 65 | |||
| 66 | /** @var Folder */ |
||
| 67 | protected $userFolder; |
||
| 68 | |||
| 69 | /** @var ILogger */ |
||
| 70 | protected $logger; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @param string $appName |
||
| 74 | * @param IRequest $request |
||
| 75 | * @param IAvatarManager $avatarManager |
||
| 76 | * @param \OC\Cache\File $cache |
||
| 77 | * @param IL10N $l10n |
||
| 78 | * @param IUserManager $userManager |
||
| 79 | * @param IUserSession $userSession |
||
| 80 | * @param Folder $userFolder |
||
| 81 | * @param ILogger $logger |
||
| 82 | */ |
||
| 83 | View Code Duplication | public function __construct($appName, |
|
|
|
|||
| 84 | IRequest $request, |
||
| 85 | IAvatarManager $avatarManager, |
||
| 86 | \OC\Cache\File $cache, |
||
| 87 | IL10N $l10n, |
||
| 88 | IUserManager $userManager, |
||
| 89 | IUserSession $userSession, |
||
| 90 | Folder $userFolder = null, |
||
| 91 | ILogger $logger) { |
||
| 92 | parent::__construct($appName, $request); |
||
| 93 | |||
| 94 | $this->avatarManager = $avatarManager; |
||
| 95 | $this->cache = $cache; |
||
| 96 | $this->l = $l10n; |
||
| 97 | $this->userManager = $userManager; |
||
| 98 | $this->userSession = $userSession; |
||
| 99 | $this->userFolder = $userFolder; |
||
| 100 | $this->logger = $logger; |
||
| 101 | } |
||
| 102 | |||
| 103 | /** |
||
| 104 | * @NoAdminRequired |
||
| 105 | * @NoCSRFRequired |
||
| 106 | * @PublicPage |
||
| 107 | * |
||
| 108 | * @param string $userId |
||
| 109 | * @param int $size |
||
| 110 | * @return DataResponse|DataDisplayResponse |
||
| 111 | */ |
||
| 112 | public function getAvatar($userId, $size) { |
||
| 113 | if ($size > 2048) { |
||
| 114 | $size = 2048; |
||
| 115 | } elseif ($size <= 0) { |
||
| 116 | $size = 64; |
||
| 117 | } |
||
| 118 | |||
| 119 | try { |
||
| 120 | $avatar = $this->avatarManager->getAvatar($userId)->getFile($size); |
||
| 121 | $resp = new DataDisplayResponse($avatar->getContent(), |
||
| 122 | Http::STATUS_OK, |
||
| 123 | ['Content-Type' => $avatar->getMimeType()]); |
||
| 124 | $resp->setETag($avatar->getEtag()); |
||
| 125 | } catch (NotFoundException $e) { |
||
| 126 | $user = $this->userManager->get($userId); |
||
| 127 | $resp = new DataResponse([ |
||
| 128 | 'data' => [ |
||
| 129 | 'displayname' => $user->getDisplayName(), |
||
| 130 | ], |
||
| 131 | ]); |
||
| 132 | } catch (\Exception $e) { |
||
| 133 | $resp = new DataResponse([ |
||
| 134 | 'data' => [ |
||
| 135 | 'displayname' => '', |
||
| 136 | ], |
||
| 137 | ]); |
||
| 138 | } |
||
| 139 | |||
| 140 | $resp->addHeader('Pragma', 'public'); |
||
| 141 | $resp->cacheFor(0); |
||
| 142 | $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT'))); |
||
| 143 | |||
| 144 | return $resp; |
||
| 145 | } |
||
| 146 | |||
| 147 | /** |
||
| 148 | * @NoAdminRequired |
||
| 149 | * |
||
| 150 | * @param string $path |
||
| 151 | * @return DataResponse|JSONResponse |
||
| 152 | */ |
||
| 153 | public function postAvatar($path) { |
||
| 154 | $userId = $this->userSession->getUser()->getUID(); |
||
| 155 | $files = $this->request->getUploadedFile('files'); |
||
| 156 | |||
| 157 | $headers = []; |
||
| 158 | if ($this->request->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE_8])) { |
||
| 159 | // due to upload iframe workaround, need to set content-type to text/plain |
||
| 160 | $headers['Content-Type'] = 'text/plain'; |
||
| 161 | } |
||
| 162 | |||
| 163 | if (isset($path)) { |
||
| 164 | $path = stripslashes($path); |
||
| 165 | $node = $this->userFolder->get($path); |
||
| 166 | if (!($node instanceof \OCP\Files\File)) { |
||
| 167 | return new DataResponse(['data' => ['message' => $this->l->t('Please select a file.')]], Http::STATUS_OK, $headers); |
||
| 168 | } |
||
| 169 | View Code Duplication | if ($node->getSize() > 20*1024*1024) { |
|
| 170 | return new DataResponse( |
||
| 171 | ['data' => ['message' => $this->l->t('File is too big')]], |
||
| 172 | Http::STATUS_BAD_REQUEST, |
||
| 173 | $headers |
||
| 174 | ); |
||
| 175 | } |
||
| 176 | |||
| 177 | View Code Duplication | if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') { |
|
| 178 | return new JSONResponse( |
||
| 179 | ['data' => ['message' => $this->l->t('The selected file is not an image.')]], |
||
| 180 | Http::STATUS_BAD_REQUEST |
||
| 181 | ); |
||
| 182 | } |
||
| 183 | |||
| 184 | try { |
||
| 185 | $content = $node->getContent(); |
||
| 186 | } catch (\OCP\Files\NotPermittedException $e) { |
||
| 187 | return new JSONResponse( |
||
| 188 | ['data' => ['message' => $this->l->t('The selected file cannot be read.')]], |
||
| 189 | Http::STATUS_BAD_REQUEST |
||
| 190 | ); |
||
| 191 | } |
||
| 192 | } elseif (!is_null($files)) { |
||
| 193 | if ( |
||
| 194 | $files['error'][0] === 0 && |
||
| 195 | is_uploaded_file($files['tmp_name'][0]) && |
||
| 196 | !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0]) |
||
| 197 | ) { |
||
| 198 | View Code Duplication | if ($files['size'][0] > 20*1024*1024) { |
|
| 199 | return new DataResponse( |
||
| 200 | ['data' => ['message' => $this->l->t('File is too big')]], |
||
| 201 | Http::STATUS_BAD_REQUEST, |
||
| 202 | $headers |
||
| 203 | ); |
||
| 204 | } |
||
| 205 | $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200); |
||
| 206 | $content = $this->cache->get('avatar_upload'); |
||
| 207 | unlink($files['tmp_name'][0]); |
||
| 208 | View Code Duplication | } else { |
|
| 209 | return new DataResponse( |
||
| 210 | ['data' => ['message' => $this->l->t('Invalid file provided')]], |
||
| 211 | Http::STATUS_BAD_REQUEST, |
||
| 212 | $headers |
||
| 213 | ); |
||
| 214 | } |
||
| 215 | View Code Duplication | } else { |
|
| 216 | //Add imgfile |
||
| 217 | return new DataResponse( |
||
| 218 | ['data' => ['message' => $this->l->t('No image or file provided')]], |
||
| 219 | Http::STATUS_BAD_REQUEST, |
||
| 220 | $headers |
||
| 221 | ); |
||
| 222 | } |
||
| 223 | |||
| 224 | try { |
||
| 225 | $image = new \OC_Image(); |
||
| 226 | $image->loadFromData($content); |
||
| 227 | $image->fixOrientation(); |
||
| 228 | |||
| 229 | if ($image->valid()) { |
||
| 230 | $mimeType = $image->mimeType(); |
||
| 231 | View Code Duplication | if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') { |
|
| 232 | return new DataResponse( |
||
| 233 | ['data' => ['message' => $this->l->t('Unknown filetype')]], |
||
| 234 | Http::STATUS_OK, |
||
| 235 | $headers |
||
| 236 | ); |
||
| 237 | } |
||
| 238 | |||
| 239 | $this->cache->set('tmpAvatar', $image->data(), 7200); |
||
| 240 | return new DataResponse( |
||
| 241 | ['data' => 'notsquare'], |
||
| 242 | Http::STATUS_OK, |
||
| 243 | $headers |
||
| 244 | ); |
||
| 245 | View Code Duplication | } else { |
|
| 246 | return new DataResponse( |
||
| 247 | ['data' => ['message' => $this->l->t('Invalid image')]], |
||
| 248 | Http::STATUS_OK, |
||
| 249 | $headers |
||
| 250 | ); |
||
| 251 | } |
||
| 252 | } catch (\Exception $e) { |
||
| 253 | $this->logger->logException($e, ['app' => 'core']); |
||
| 254 | return new DataResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK, $headers); |
||
| 255 | } |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * @NoAdminRequired |
||
| 260 | * |
||
| 261 | * @return DataResponse |
||
| 262 | */ |
||
| 263 | public function deleteAvatar() { |
||
| 264 | $userId = $this->userSession->getUser()->getUID(); |
||
| 265 | |||
| 266 | try { |
||
| 267 | $avatar = $this->avatarManager->getAvatar($userId); |
||
| 268 | $avatar->remove(); |
||
| 269 | return new DataResponse(); |
||
| 270 | } catch (\Exception $e) { |
||
| 271 | $this->logger->logException($e, ['app' => 'core']); |
||
| 272 | return new DataResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST); |
||
| 273 | } |
||
| 274 | } |
||
| 275 | |||
| 276 | /** |
||
| 277 | * @NoAdminRequired |
||
| 278 | * |
||
| 279 | * @return DataResponse|DataDisplayResponse |
||
| 280 | */ |
||
| 281 | public function getTmpAvatar() { |
||
| 301 | |||
| 302 | /** |
||
| 303 | * @NoAdminRequired |
||
| 304 | * |
||
| 305 | * @param array $crop |
||
| 306 | * @return DataResponse |
||
| 307 | */ |
||
| 308 | public function postCroppedAvatar($crop) { |
||
| 345 | } |
||
| 346 |
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.