r74263 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r74262‎ | r74263 | r74264 >
Date:17:16, 4 October 2010
Author:catrope
Status:deferred (Comments)
Tags:
Comment:
UploadWizard branch: Some fixes and comments for SessionStash.php. Stylize run will follow
* Add some FIXME comments
* Fix @param lines in doc comments to clarify which parameter they refer to
* Fix some language in SessionStash::__construct() doc comment
* Use isset() rather than array_key_exists()
* Have SessionStash::getFile() return null (and cache that!) on error like the doc comment claims it does
* Use array_diff_key() to strip 'mTempPath' out rather than DIY method
* Correct doc comment for stashFile()
* Return null instead of false from stashFile() to be consistent with getFile()
* Use the + operator to merge $stashData and $data rather than DIY method
* Document which exceptions SessionStashFile::__construct() can throw
* Use () when referring to function names in doc comments, so Doxygen will pick up on them and linkify them magically
* Explicitly set $extension to null in setExtension() rather than relying on the implicit assumption that an undefined variable is null
* Document null return in thumbName()
* Use getHandler() consistently, rather than using ->handler in one case and getHandler() in another
Modified paths:
  • /branches/uploadwizard/phase3/includes/upload/SessionStash.php (modified) (history)

Diff [purge]

Index: branches/uploadwizard/phase3/includes/upload/SessionStash.php
@@ -11,7 +11,6 @@
1212 * the session, even the uploading user. See SpecialSessionStash, which implements a web interface to some files stored this way.
1313 *
1414 */
15 -
1615 class SessionStash {
1716 // repository that this uses to store temp files
1817 protected $repo;
@@ -27,9 +26,9 @@
2827 // const SESSION_KEYNAME = 'wsUploadData';
2928
3029 /**
31 - * Represents the session which contain temporarily stored files.
32 - * Designed to be compatible with the session stashing code in UploadBase (should replace eventually)
33 - * @param {FileRepo} optional -- repo in which to store files. Will choose LocalRepo if not supplied.
 30+ * Represents the session which contains temporarily stored files.
 31+ * Designed to be compatible with the session stashing code in UploadBase (should replace it eventually)
 32+ * @param {FileRepo} $repo: optional -- repo in which to store files. Will choose LocalRepo if not supplied.
3433 */
3534 public function __construct( $repo = null ) {
3635
@@ -47,7 +46,7 @@
4847 throw new MWException( 'session not available' );
4948 }
5049
51 - if ( ! array_key_exists( UploadBase::SESSION_KEYNAME, $_SESSION ) ) {
 50+ if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME] ) ) {
5251 $_SESSION[UploadBase::SESSION_KEYNAME] = array();
5352 }
5453
@@ -65,31 +64,25 @@
6665 /**
6766 * Get a file from the stash.
6867 * May throw exception if session data cannot be parsed due to schema change.
69 - * @param {Integer} key
 68+ * @param {Integer} $key: key
7069 * @return {null|SessionStashItem} null if no such item or item out of date, or the item
7170 */
7271 public function getFile( $key ) {
7372 if ( !isset( $this->files[$key] ) ) {
7473 if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME][$key] ) ) {
75 - throw new SessionStashFileNotFoundException();
 74+ return $this->files[$key] = null;
7675 }
7776
7877 $stashData = $_SESSION[UploadBase::SESSION_KEYNAME][$key];
7978
8079 // guards against PHP class changing while session data doesn't
8180 if ($stashData['version'] !== UploadBase::SESSION_VERSION ) {
82 - throw new MWException( 'outdated session version' );
 81+ return $this->files[$key] = null;
8382 }
8483
8584 // The path is flattened in with the other random props so we have to dig it out.
86 - $data = array();
87 - foreach( $stashData as $stashKey => $stashVal ) {
88 - if ( $stashKey === 'mTempPath' ) {
89 - $path = $stashVal;
90 - } else {
91 - $data[ $stashKey ] = $stashVal;
92 - }
93 - }
 85+ $path = $stashData['mTempPath'];
 86+ $data = array_diff_key( $data, array( 'mTempPath' => true ) );
9487
9588 $file = new SessionStashFile( $this, $this->repo, $path, $key, $data );
9689 $this->files[$key] = $file;
@@ -100,20 +93,22 @@
10194
10295 /**
10396 * Stash a file in a temp directory and record that we did this in the session, along with other parameters.
104 - * @param {String} name - this is used for directory hashing when storing. Otherwise not important
105 - * @param {String} path - path to file you want stashed
106 - * @param {Array} data - other data you want added to the session. Do not use 'mTempPath', 'mFileProps', 'mFileSize', or version as keys here
107 - * @return {SessionStashFile} file
 97+ * @param {Integer} $key: unique key. Used for directory hashing when storing, otherwise not important
 98+ * @param {String} $path: path to file you want stashed
 99+ * @param {Array} $data: other data you want added to the session. Do not use 'mTempPath', 'mFileProps', 'mFileSize', or 'version' as keys here
 100+ * @return {null|SessionStashFile} file, or null on failure
108101 */
109102 public function stashFile( $key, $path, $data = array() ) {
110103 if ( !$key ) {
 104+ // FIXME: Doesn't sound like a good idea if $key is to be unique
 105+ // Also, why is this an integer rather than a string?
111106 $key = mt_rand( 0, 0x7fffffff );
112107 }
113108
114109 // if not already in a temporary area, put it there
115110 $status = $this->repo->storeTemp( basename($path), $path );
116111 if( !$status->isOK() ) {
117 - return false;
 112+ return null;
118113 }
119114 $stashPath = $status->value;
120115
@@ -134,13 +129,8 @@
135130
136131 // put extended info into the session (this changes from application to application).
137132 // UploadWizard wants different things than say FirefoggChunkedUpload.
138 - foreach ($data as $stashKey => $stashValue) {
139 - if ( !array_key_exists( $stashKey, $data ) ) {
140 - $stashData[$stashKey] = $stashValue;
141 - }
142 - }
143 -
144 - $_SESSION[UploadBase::SESSION_KEYNAME][$key] = $stashData;
 133+ // Order is relevant: in case of a key collision, the value from $stashData wins
 134+ $_SESSION[UploadBase::SESSION_KEYNAME][$key] = $data + $stashData;
145135
146136 return $this->getFile( $key );
147137 }
@@ -155,10 +145,12 @@
156146 /**
157147 * A LocalFile wrapper around a file that has been temporarily stashed, so we can do things like create thumbnails for it
158148 * Arguably UnregisteredLocalFile should be handling its own file repo but that class is a bit retarded currently
159 - * @param {FileRepo} repository where we should find the path
160 - * @param {String} path to file
 149+ * @param {FileRepo} $repo: repository where we should find the path
 150+ * @param {String} $path: path to file
 151+ * @throws SessionStashBadPathException
 152+ * @throws SessionStashFileNotFoundException
161153 */
162 - public function __construct( $stash, $repo, $path, $key, $data ) {
 154+ public function __construct( $stash, $repo, $path, $key, $data ) { // FIXME: document $stash, $key, $data --RK
163155 $this->sessionStash = $stash;
164156 $this->sessionKey = $key;
165157 $this->sessionData = $data;
@@ -168,9 +160,9 @@
169161 $path = $repo->resolveVirtualUrl( $path );
170162 }
171163
172 - // check if path appears to be sane, no parent traverals, and is in this repo's temp zone.
 164+ // check if path appears to be sane, no parent traversals, and is in this repo's temp zone.
173165 if ( ( ! $repo->validateFilename( $path ) ) ||
174 - ( strpos( $path, $repo->getZonePath( 'temp' ) ) !== 0 ) ) {
 166+ ( strpos( $path, $repo->getZonePath( 'temp' ) ) !== 0 ) ) {
175167 throw new SessionStashBadPathException();
176168 }
177169
@@ -200,14 +192,15 @@
201193 /**
202194 * Find or guess extension -- ensuring that our extension matches our mime type.
203195 * Since these files are constructed from php tempnames they may not start off
204 - * with an extension
205 - * This does not override getExtension because things like getMimeType already call getExtension,
206 - * and that results in infinite recursion. So, we preemptively *set* the extension so getExtension can find it.
 196+ * with an extension.
 197+ * This does not override getExtension() because things like getMimeType() already call getExtension(),
 198+ * and that results in infinite recursion. So, we preemptively *set* the extension so getExtension() can find it.
207199 * For obvious reasons this should be called as early as possible, as part of initialization
208200 */
209201 public function setExtension() {
210202 // Does this have an extension?
211203 $n = strrpos( $this->path, '.' );
 204+ $extension = null;
212205 if ( $n !== false ) {
213206 $extension = $n ? substr( $this->path, $n + 1 ) : '';
214207 } else {
@@ -235,7 +228,7 @@
236229 * The actual argument is the result of thumbName although we seem to have
237230 * buggy code elsewhere that expects a boolean 'suffix'
238231 *
239 - * @param {String|false} name of thumbnail (e.g. "120px-123456.jpg" ), or false to just get the path
 232+ * @param {String|false} $thumbName: name of thumbnail (e.g. "120px-123456.jpg" ), or false to just get the path
240233 * @return {String} path thumbnail should take on filesystem, or containing directory if thumbname is false
241234 */
242235 public function getThumbPath( $thumbName = false ) {
@@ -250,7 +243,7 @@
251244 * Return the file/url base name of a thumbnail with the specified parameters
252245 *
253246 * @param {Array} $params: handler-specific parameters
254 - * @return {String} base name for URL, like '120px-12345.jpg'
 247+ * @return {String|null} base name for URL, like '120px-12345.jpg', or null if there is no handler
255248 */
256249 function thumbName( $params ) {
257250 if ( !$this->getHandler() ) {
@@ -258,7 +251,7 @@
259252 }
260253 $extension = $this->getExtension();
261254 list( $thumbExt, $thumbMime ) = $this->handler->getThumbType( $extension, $this->getMimeType(), $params );
262 - $thumbName = $this->handler->makeParamString( $params ) . '-' . $this->getUrlName();
 255+ $thumbName = $this->getHandler()->makeParamString( $params ) . '-' . $this->getUrlName();
263256 if ( $thumbExt != $extension ) {
264257 $thumbName .= ".$thumbExt";
265258 }
@@ -271,12 +264,12 @@
272265 * the thumbnail urls be predictable. However, in our model the URL is not based on the filename
273266 * (that's hidden in the session)
274267 *
275 - * @param {String} basename of thumbnail file -- however, we don't want to use the file exactly
 268+ * @param {String} $thumbName: basename of thumbnail file -- however, we don't want to use the file exactly
276269 * @return {String} URL to access thumbnail, or URL with partial path
277270 */
278271 public function getThumbUrl( $thumbName = false ) {
279272 $path = $this->sessionStash->getBaseUrl();
280 - $extension = $this->getExtension();
 273+ $extension = $this->getExtension(); // Unused. Should this be appended to $path ? --RK
281274 if ( $thumbName !== false ) {
282275 $path .= '/' . rawurlencode( $thumbName );
283276 }
@@ -289,7 +282,7 @@
290283 * @param {Array} optional transformation parameters
291284 * @return {String} base url name, like '120px-123456.jpg'
292285 */
293 - public function getUrlName() {
 286+ public function getUrlName() { // FIXME: Docs say this has a parameter, but it doesn't --RK
294287 if ( ! $this->urlName ) {
295288 $this->urlName = $this->sessionKey . '.' . $this->getExtension();
296289 }
@@ -326,8 +319,8 @@
327320 * Here we override transform() to stash the thumbnail file, and then
328321 * provide a way to get at the stashed thumbnail file to extract properties such as its URL
329322 *
330 - * @param {Array} parameters suitable for File::transform()
331 - * @param {Bitmask} flags suitable for File::transform()
 323+ * @param {Array} $params: parameters suitable for File::transform()
 324+ * @param {Bitmask} $flags: flags suitable for File::transform()
332325 * @return {ThumbnailImage} with additional File thumbnailFile property
333326 */
334327 public function transform( $params, $flags = 0 ) {

Follow-up revisions

RevisionCommit summaryAuthorDate
r74280multiple issues fixed relating to comment/followup revision r74262, r74263neilk22:02, 4 October 2010

Comments

#Comment by NeilK (talk | contribs)   22:07, 4 October 2010

Responded to this change in r74280.

- Comments more in sync with code, formatting - File keys no longer random ints, now using sha1 content hash (or user-supplied key). - Changed argument order of stashFile to make key potentially empty. - reverted removals of exceptions thrown in getFile() - simplified stashData array merge (not even necessary) - double check for existence of path. Also check if is_uploaded_file if stashing an uploaded file. - made session* members private in SessionStashFile. No need for accessors. - removed unnecessary calls to getExtension() in getThumbUrl. - removed unnecessary parameter in getUrlName().


#Comment by NeilK (talk | contribs)   22:08, 4 October 2010

Ugh, for better formatting:

Responded to this change in r74280.

- Comments more in sync with code, formatting

- File keys no longer random ints, now using sha1 content hash (or user-supplied key).

- Changed argument order of stashFile to make key potentially empty.

- reverted removals of exceptions thrown in getFile()

- simplified stashData array merge (not even necessary)

- double check for existence of path. Also check if is_uploaded_file if stashing an uploaded file.

- made session* members private in SessionStashFile. No need for accessors.

- removed unnecessary calls to getExtension() in getThumbUrl.

- removed unnecessary parameter in getUrlName().

Status & tagging log