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 |
||
56 | class ShareController extends Controller { |
||
57 | |||
58 | /** @var \OC\User\Session */ |
||
59 | protected $userSession; |
||
60 | /** @var \OC\AppConfig */ |
||
61 | protected $appConfig; |
||
62 | /** @var \OCP\IConfig */ |
||
63 | protected $config; |
||
64 | /** @var \OC\URLGenerator */ |
||
65 | protected $urlGenerator; |
||
66 | /** @var \OC\User\Manager */ |
||
67 | protected $userManager; |
||
68 | /** @var \OCP\ILogger */ |
||
69 | protected $logger; |
||
70 | /** @var OCP\Activity\IManager */ |
||
71 | protected $activityManager; |
||
72 | |||
73 | /** |
||
74 | * @param string $appName |
||
75 | * @param IRequest $request |
||
76 | * @param OC\User\Session $userSession |
||
77 | * @param AppConfig $appConfig |
||
78 | * @param OCP\IConfig $config |
||
79 | * @param URLGenerator $urlGenerator |
||
80 | * @param OCP\IUserManager $userManager |
||
81 | * @param ILogger $logger |
||
82 | * @param OCP\Activity\IManager $activityManager |
||
83 | */ |
||
84 | 7 | public function __construct($appName, |
|
103 | |||
104 | /** |
||
105 | * @PublicPage |
||
106 | * @NoCSRFRequired |
||
107 | * |
||
108 | * @param string $token |
||
109 | * @return TemplateResponse|RedirectResponse |
||
110 | */ |
||
111 | 1 | public function showAuthenticate($token) { |
|
120 | |||
121 | /** |
||
122 | * @PublicPage |
||
123 | * @UseSession |
||
124 | * |
||
125 | * Authenticates against password-protected shares |
||
126 | * @param $token |
||
127 | * @param string $password |
||
128 | * @return RedirectResponse|TemplateResponse |
||
129 | */ |
||
130 | 1 | public function authenticate($token, $password = '') { |
|
144 | |||
145 | /** |
||
146 | * @PublicPage |
||
147 | * @NoCSRFRequired |
||
148 | * |
||
149 | * @param string $token |
||
150 | * @param string $path |
||
151 | * @return TemplateResponse|RedirectResponse |
||
152 | * @throws NotFoundException |
||
153 | */ |
||
154 | 3 | public function showShare($token, $path = '') { |
|
229 | |||
230 | /** |
||
231 | * @PublicPage |
||
232 | * @NoCSRFRequired |
||
233 | * |
||
234 | * @param string $token |
||
235 | * @param string $files |
||
236 | * @param string $path |
||
237 | * @param string $downloadStartSecret |
||
238 | * @return void|RedirectResponse |
||
239 | */ |
||
240 | 2 | public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') { |
|
241 | 2 | \OC_User::setIncognitoMode(true); |
|
242 | |||
243 | 2 | $linkItem = OCP\Share::getShareByToken($token, false); |
|
244 | |||
245 | // Share is password protected - check whether the user is permitted to access the share |
||
246 | 2 | View Code Duplication | if (isset($linkItem['share_with'])) { |
247 | 2 | if(!Helper::authenticate($linkItem)) { |
|
248 | 1 | return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate', |
|
249 | 1 | array('token' => $token))); |
|
250 | } |
||
251 | 1 | } |
|
252 | |||
253 | 1 | $files_list = null; |
|
254 | 1 | if (!is_null($files)) { // download selected files |
|
255 | $files_list = json_decode($files); |
||
256 | // in case we get only a single file |
||
257 | if ($files_list === null) { |
||
258 | $files_list = array($files); |
||
259 | } |
||
260 | } |
||
261 | |||
262 | 1 | $originalSharePath = self::getPath($token); |
|
263 | |||
264 | // Create the activities |
||
265 | if (isset($originalSharePath) && Filesystem::isReadable($originalSharePath . $path)) { |
||
266 | $originalSharePath = Filesystem::normalizePath($originalSharePath . $path); |
||
267 | $isDir = \OC\Files\Filesystem::is_dir($originalSharePath); |
||
268 | |||
269 | $activities = []; |
||
270 | if (!$isDir) { |
||
271 | // Single file public share |
||
272 | $activities[$originalSharePath] = Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; |
||
273 | } else if (!empty($files_list)) { |
||
274 | // Only some files are downloaded |
||
275 | foreach ($files_list as $file) { |
||
276 | $filePath = Filesystem::normalizePath($originalSharePath . '/' . $file); |
||
277 | $isDir = \OC\Files\Filesystem::is_dir($filePath); |
||
278 | $activities[$filePath] = ($isDir) ? Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED : Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; |
||
279 | } |
||
280 | } else { |
||
281 | // The folder is downloaded |
||
282 | $activities[$originalSharePath] = Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED; |
||
283 | } |
||
284 | |||
285 | foreach ($activities as $filePath => $subject) { |
||
286 | $this->activityManager->publishActivity( |
||
287 | 'files_sharing', $subject, array($filePath), '', array(), |
||
288 | $filePath, '', $linkItem['uid_owner'], Activity::TYPE_PUBLIC_LINKS, Activity::PRIORITY_MEDIUM |
||
289 | ); |
||
290 | } |
||
291 | } |
||
292 | |||
293 | /** |
||
294 | * this sets a cookie to be able to recognize the start of the download |
||
295 | * the content must not be longer than 32 characters and must only contain |
||
296 | * alphanumeric characters |
||
297 | */ |
||
298 | if (!empty($downloadStartSecret) |
||
299 | && !isset($downloadStartSecret[32]) |
||
300 | && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) { |
||
301 | |||
302 | // FIXME: set on the response once we use an actual app framework response |
||
303 | setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/'); |
||
304 | } |
||
305 | |||
306 | // download selected files |
||
307 | if (!is_null($files) && $files !== '') { |
||
308 | // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well |
||
309 | // after dispatching the request which results in a "Cannot modify header information" notice. |
||
310 | OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); |
||
311 | exit(); |
||
312 | } else { |
||
313 | // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well |
||
314 | // after dispatching the request which results in a "Cannot modify header information" notice. |
||
315 | OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $_SERVER['REQUEST_METHOD'] == 'HEAD'); |
||
316 | exit(); |
||
317 | } |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @param string $token |
||
322 | * @return string Resolved file path of the token |
||
323 | * @throws NotFoundException In case share could not get properly resolved |
||
324 | */ |
||
325 | 4 | private function getPath($token) { |
|
346 | } |
||
347 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.