Index: branches/uploadwizard/phase3/includes/upload/SessionStash.php |
— | — | @@ -11,7 +11,6 @@ |
12 | 12 | * the session, even the uploading user. See SpecialSessionStash, which implements a web interface to some files stored this way. |
13 | 13 | * |
14 | 14 | */ |
15 | | - |
16 | 15 | class SessionStash { |
17 | 16 | // repository that this uses to store temp files |
18 | 17 | protected $repo; |
— | — | @@ -27,9 +26,9 @@ |
28 | 27 | // const SESSION_KEYNAME = 'wsUploadData'; |
29 | 28 | |
30 | 29 | /** |
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. |
34 | 33 | */ |
35 | 34 | public function __construct( $repo = null ) { |
36 | 35 | |
— | — | @@ -47,7 +46,7 @@ |
48 | 47 | throw new MWException( 'session not available' ); |
49 | 48 | } |
50 | 49 | |
51 | | - if ( ! array_key_exists( UploadBase::SESSION_KEYNAME, $_SESSION ) ) { |
| 50 | + if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME] ) ) { |
52 | 51 | $_SESSION[UploadBase::SESSION_KEYNAME] = array(); |
53 | 52 | } |
54 | 53 | |
— | — | @@ -65,31 +64,25 @@ |
66 | 65 | /** |
67 | 66 | * Get a file from the stash. |
68 | 67 | * May throw exception if session data cannot be parsed due to schema change. |
69 | | - * @param {Integer} key |
| 68 | + * @param {Integer} $key: key |
70 | 69 | * @return {null|SessionStashItem} null if no such item or item out of date, or the item |
71 | 70 | */ |
72 | 71 | public function getFile( $key ) { |
73 | 72 | if ( !isset( $this->files[$key] ) ) { |
74 | 73 | if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME][$key] ) ) { |
75 | | - throw new SessionStashFileNotFoundException(); |
| 74 | + return $this->files[$key] = null; |
76 | 75 | } |
77 | 76 | |
78 | 77 | $stashData = $_SESSION[UploadBase::SESSION_KEYNAME][$key]; |
79 | 78 | |
80 | 79 | // guards against PHP class changing while session data doesn't |
81 | 80 | if ($stashData['version'] !== UploadBase::SESSION_VERSION ) { |
82 | | - throw new MWException( 'outdated session version' ); |
| 81 | + return $this->files[$key] = null; |
83 | 82 | } |
84 | 83 | |
85 | 84 | // 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 ) ); |
94 | 87 | |
95 | 88 | $file = new SessionStashFile( $this, $this->repo, $path, $key, $data ); |
96 | 89 | $this->files[$key] = $file; |
— | — | @@ -100,20 +93,22 @@ |
101 | 94 | |
102 | 95 | /** |
103 | 96 | * 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 |
108 | 101 | */ |
109 | 102 | public function stashFile( $key, $path, $data = array() ) { |
110 | 103 | 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? |
111 | 106 | $key = mt_rand( 0, 0x7fffffff ); |
112 | 107 | } |
113 | 108 | |
114 | 109 | // if not already in a temporary area, put it there |
115 | 110 | $status = $this->repo->storeTemp( basename($path), $path ); |
116 | 111 | if( !$status->isOK() ) { |
117 | | - return false; |
| 112 | + return null; |
118 | 113 | } |
119 | 114 | $stashPath = $status->value; |
120 | 115 | |
— | — | @@ -134,13 +129,8 @@ |
135 | 130 | |
136 | 131 | // put extended info into the session (this changes from application to application). |
137 | 132 | // 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; |
145 | 135 | |
146 | 136 | return $this->getFile( $key ); |
147 | 137 | } |
— | — | @@ -155,10 +145,12 @@ |
156 | 146 | /** |
157 | 147 | * A LocalFile wrapper around a file that has been temporarily stashed, so we can do things like create thumbnails for it |
158 | 148 | * 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 |
161 | 153 | */ |
162 | | - public function __construct( $stash, $repo, $path, $key, $data ) { |
| 154 | + public function __construct( $stash, $repo, $path, $key, $data ) { // FIXME: document $stash, $key, $data --RK |
163 | 155 | $this->sessionStash = $stash; |
164 | 156 | $this->sessionKey = $key; |
165 | 157 | $this->sessionData = $data; |
— | — | @@ -168,9 +160,9 @@ |
169 | 161 | $path = $repo->resolveVirtualUrl( $path ); |
170 | 162 | } |
171 | 163 | |
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. |
173 | 165 | if ( ( ! $repo->validateFilename( $path ) ) || |
174 | | - ( strpos( $path, $repo->getZonePath( 'temp' ) ) !== 0 ) ) { |
| 166 | + ( strpos( $path, $repo->getZonePath( 'temp' ) ) !== 0 ) ) { |
175 | 167 | throw new SessionStashBadPathException(); |
176 | 168 | } |
177 | 169 | |
— | — | @@ -200,14 +192,15 @@ |
201 | 193 | /** |
202 | 194 | * Find or guess extension -- ensuring that our extension matches our mime type. |
203 | 195 | * 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. |
207 | 199 | * For obvious reasons this should be called as early as possible, as part of initialization |
208 | 200 | */ |
209 | 201 | public function setExtension() { |
210 | 202 | // Does this have an extension? |
211 | 203 | $n = strrpos( $this->path, '.' ); |
| 204 | + $extension = null; |
212 | 205 | if ( $n !== false ) { |
213 | 206 | $extension = $n ? substr( $this->path, $n + 1 ) : ''; |
214 | 207 | } else { |
— | — | @@ -235,7 +228,7 @@ |
236 | 229 | * The actual argument is the result of thumbName although we seem to have |
237 | 230 | * buggy code elsewhere that expects a boolean 'suffix' |
238 | 231 | * |
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 |
240 | 233 | * @return {String} path thumbnail should take on filesystem, or containing directory if thumbname is false |
241 | 234 | */ |
242 | 235 | public function getThumbPath( $thumbName = false ) { |
— | — | @@ -250,7 +243,7 @@ |
251 | 244 | * Return the file/url base name of a thumbnail with the specified parameters |
252 | 245 | * |
253 | 246 | * @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 |
255 | 248 | */ |
256 | 249 | function thumbName( $params ) { |
257 | 250 | if ( !$this->getHandler() ) { |
— | — | @@ -258,7 +251,7 @@ |
259 | 252 | } |
260 | 253 | $extension = $this->getExtension(); |
261 | 254 | 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(); |
263 | 256 | if ( $thumbExt != $extension ) { |
264 | 257 | $thumbName .= ".$thumbExt"; |
265 | 258 | } |
— | — | @@ -271,12 +264,12 @@ |
272 | 265 | * the thumbnail urls be predictable. However, in our model the URL is not based on the filename |
273 | 266 | * (that's hidden in the session) |
274 | 267 | * |
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 |
276 | 269 | * @return {String} URL to access thumbnail, or URL with partial path |
277 | 270 | */ |
278 | 271 | public function getThumbUrl( $thumbName = false ) { |
279 | 272 | $path = $this->sessionStash->getBaseUrl(); |
280 | | - $extension = $this->getExtension(); |
| 273 | + $extension = $this->getExtension(); // Unused. Should this be appended to $path ? --RK |
281 | 274 | if ( $thumbName !== false ) { |
282 | 275 | $path .= '/' . rawurlencode( $thumbName ); |
283 | 276 | } |
— | — | @@ -289,7 +282,7 @@ |
290 | 283 | * @param {Array} optional transformation parameters |
291 | 284 | * @return {String} base url name, like '120px-123456.jpg' |
292 | 285 | */ |
293 | | - public function getUrlName() { |
| 286 | + public function getUrlName() { // FIXME: Docs say this has a parameter, but it doesn't --RK |
294 | 287 | if ( ! $this->urlName ) { |
295 | 288 | $this->urlName = $this->sessionKey . '.' . $this->getExtension(); |
296 | 289 | } |
— | — | @@ -326,8 +319,8 @@ |
327 | 320 | * Here we override transform() to stash the thumbnail file, and then |
328 | 321 | * provide a way to get at the stashed thumbnail file to extract properties such as its URL |
329 | 322 | * |
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() |
332 | 325 | * @return {ThumbnailImage} with additional File thumbnailFile property |
333 | 326 | */ |
334 | 327 | public function transform( $params, $flags = 0 ) { |