/** * Get a file and its metadata from the stash. * * @param $key String: key under which file information is stored * @param $noAuth Boolean (optional) Don't check authentication. Used by maintenance scripts. * @throws UploadStashFileNotFoundException * @throws UploadStashNotLoggedInException * @throws UploadStashWrongOwnerException * @throws UploadStashBadPathException * @return UploadStashFile */ public function getFile($key, $noAuth = false) { if (!preg_match(self::KEY_FORMAT_REGEX, $key)) { throw new UploadStashBadPathException("key '{$key}' is not in a proper format"); } if (!$noAuth) { if (!$this->isLoggedIn) { throw new UploadStashNotLoggedInException(__METHOD__ . ' No user is logged in, files must belong to users'); } } $dbr = $this->repo->getSlaveDb(); if (!isset($this->fileMetadata[$key])) { // try this first. if it fails to find the row, check for lag, wait, try again. if its still missing, throw an exception. // this more complex solution keeps things moving for page loads with many requests // (ie. validating image ownership) when replag is high if (!$this->fetchFileMetadata($key)) { $lag = $dbr->getLag(); if ($lag > 0 && $lag <= self::MAX_LAG) { // if there's not too much replication lag, just wait for the slave to catch up to our last insert. sleep(ceil($lag)); } elseif ($lag > self::MAX_LAG) { // that's a lot of lag to introduce into the middle of the UI. throw new UploadStashMaxLagExceededException('Couldn\'t load stashed file metadata, and replication lag is above threshold: (MAX_LAG=' . self::MAX_LAG . ')'); } // now that the waiting has happened, try again $this->fetchFileMetadata($key); } if (!isset($this->fileMetadata[$key])) { throw new UploadStashFileNotFoundException("key '{$key}' not found in stash"); } // create $this->files[$key] $this->initFile($key); // fetch fileprops $path = $this->fileMetadata[$key]['us_path']; if ($this->repo->isVirtualUrl($path)) { $path = $this->repo->resolveVirtualUrl($path); } $this->fileProps[$key] = File::getPropsFromPath($path); } if (!$this->files[$key]->exists()) { wfDebug(__METHOD__ . " tried to get file at {$key}, but it doesn't exist\n"); throw new UploadStashBadPathException("path doesn't exist"); } if (!$noAuth) { if ($this->fileMetadata[$key]['us_user'] != $this->userId) { throw new UploadStashWrongOwnerException("This file ({$key}) doesn't belong to the current user."); } } return $this->files[$key]; }
/** * Get a file and its metadata from the stash. * The noAuth param is a bit janky but is required for automated scripts which clean out the stash. * * @param $key String: key under which file information is stored * @param $noAuth Boolean (optional) Don't check authentication. Used by maintenance scripts. * @throws UploadStashFileNotFoundException * @throws UploadStashNotLoggedInException * @throws UploadStashWrongOwnerException * @throws UploadStashBadPathException * @return UploadStashFile */ public function getFile($key, $noAuth = false) { if (!preg_match(self::KEY_FORMAT_REGEX, $key)) { throw new UploadStashBadPathException("key '{$key}' is not in a proper format"); } if (!$noAuth) { if (!$this->isLoggedIn) { throw new UploadStashNotLoggedInException(__METHOD__ . ' No user is logged in, files must belong to users'); } } if (!isset($this->fileMetadata[$key])) { if (!$this->fetchFileMetadata($key)) { // If nothing was received, it's likely due to replication lag. Check the master to see if the record is there. $this->fetchFileMetadata($key, DB_MASTER); } if (!isset($this->fileMetadata[$key])) { throw new UploadStashFileNotFoundException("key '{$key}' not found in stash"); } // create $this->files[$key] $this->initFile($key); // fetch fileprops $path = $this->fileMetadata[$key]['us_path']; if ($this->repo->isVirtualUrl($path)) { $path = $this->repo->resolveVirtualUrl($path); } $this->fileProps[$key] = File::getPropsFromPath($path); } if (!$this->files[$key]->exists()) { wfDebug(__METHOD__ . " tried to get file at {$key}, but it doesn't exist\n"); throw new UploadStashBadPathException("path doesn't exist"); } if (!$noAuth) { if ($this->fileMetadata[$key]['us_user'] != $this->userId) { throw new UploadStashWrongOwnerException("This file ({$key}) doesn't belong to the current user."); } } return $this->files[$key]; }