Index: trunk/phase3/includes/filerepo/LocalFile.php |
— | — | @@ -58,6 +58,8 @@ |
59 | 59 | |
60 | 60 | /**#@-*/ |
61 | 61 | |
| 62 | + protected $repoClass = 'LocalRepo'; |
| 63 | + |
62 | 64 | /** |
63 | 65 | * Create a LocalFile from a title |
64 | 66 | * Do not call this except from inside a repo class. |
— | — | @@ -144,16 +146,15 @@ |
145 | 147 | * Do not call this except from inside a repo class. |
146 | 148 | */ |
147 | 149 | function __construct( $title, $repo ) { |
148 | | - if ( !is_object( $title ) ) { // LocalFile requires a title object |
149 | | - throw new MWException( __CLASS__ . ' constructor given bogus title.' ); |
150 | | - } |
151 | | - |
152 | 150 | parent::__construct( $title, $repo ); |
153 | 151 | |
154 | 152 | $this->metadata = ''; |
155 | 153 | $this->historyLine = 0; |
156 | 154 | $this->historyRes = null; |
157 | 155 | $this->dataLoaded = false; |
| 156 | + |
| 157 | + $this->assertRepoDefined(); |
| 158 | + $this->assertTitleDefined(); |
158 | 159 | } |
159 | 160 | |
160 | 161 | /** |
Index: trunk/phase3/includes/filerepo/File.php |
— | — | @@ -61,7 +61,7 @@ |
62 | 62 | */ |
63 | 63 | |
64 | 64 | /** |
65 | | - * @var FileRepo |
| 65 | + * @var FileRepo|false |
66 | 66 | */ |
67 | 67 | var $repo; |
68 | 68 | |
— | — | @@ -85,13 +85,22 @@ |
86 | 86 | protected $canRender, $isSafeFile; |
87 | 87 | |
88 | 88 | /** |
89 | | - * Call this constructor from child classes |
| 89 | + * @var string Required Repository class type |
| 90 | + */ |
| 91 | + protected $repoClass = 'FileRepo'; |
| 92 | + |
| 93 | + /** |
| 94 | + * Call this constructor from child classes. |
| 95 | + * |
| 96 | + * Both $title and $repo are optional, though some functions |
| 97 | + * may return false or throw exceptions if they are not set. |
| 98 | + * Most subclasses will want to call assertRepoDefined() here. |
90 | 99 | * |
91 | | - * @param $title Title|false |
| 100 | + * @param $title Title|string|false |
92 | 101 | * @param $repo FileRepo|false |
93 | 102 | */ |
94 | 103 | function __construct( $title, $repo ) { |
95 | | - if ( $title !== false ) { // account for UnregisteredLocalFile et all |
| 104 | + if ( $title !== false ) { // subclasses may not use MW titles |
96 | 105 | $title = self::normalizeTitle( $title, 'exception' ); |
97 | 106 | } |
98 | 107 | $this->title = $title; |
— | — | @@ -205,6 +214,7 @@ |
206 | 215 | */ |
207 | 216 | public function getName() { |
208 | 217 | if ( !isset( $this->name ) ) { |
| 218 | + $this->assertRepoDefined(); |
209 | 219 | $this->name = $this->repo->getNameFromTitle( $this->title ); |
210 | 220 | } |
211 | 221 | return $this->name; |
— | — | @@ -226,7 +236,7 @@ |
227 | 237 | |
228 | 238 | /** |
229 | 239 | * Return the associated title object |
230 | | - * @return Title |
| 240 | + * @return Title|false |
231 | 241 | */ |
232 | 242 | public function getTitle() { return $this->title; } |
233 | 243 | |
— | — | @@ -249,6 +259,7 @@ |
250 | 260 | */ |
251 | 261 | public function getUrl() { |
252 | 262 | if ( !isset( $this->url ) ) { |
| 263 | + $this->assertRepoDefined(); |
253 | 264 | $this->url = $this->repo->getZoneUrl( 'public' ) . '/' . $this->getUrlRel(); |
254 | 265 | } |
255 | 266 | return $this->url; |
— | — | @@ -303,7 +314,8 @@ |
304 | 315 | */ |
305 | 316 | public function getPath() { |
306 | 317 | if ( !isset( $this->path ) ) { |
307 | | - $this->path = $this->repo->getZonePath('public') . '/' . $this->getRel(); |
| 318 | + $this->assertRepoDefined(); |
| 319 | + $this->path = $this->repo->getZonePath( 'public' ) . '/' . $this->getRel(); |
308 | 320 | } |
309 | 321 | return $this->path; |
310 | 322 | } |
— | — | @@ -928,6 +940,7 @@ |
929 | 941 | */ |
930 | 942 | function getHashPath() { |
931 | 943 | if ( !isset( $this->hashPath ) ) { |
| 944 | + $this->assertRepoDefined(); |
932 | 945 | $this->hashPath = $this->repo->getHashPath( $this->getName() ); |
933 | 946 | } |
934 | 947 | return $this->hashPath; |
— | — | @@ -995,6 +1008,7 @@ |
996 | 1009 | * @return string |
997 | 1010 | */ |
998 | 1011 | function getArchivePath( $suffix = false ) { |
| 1012 | + $this->assertRepoDefined(); |
999 | 1013 | return $this->repo->getZonePath( 'public' ) . '/' . $this->getArchiveRel( $suffix ); |
1000 | 1014 | } |
1001 | 1015 | |
— | — | @@ -1007,7 +1021,9 @@ |
1008 | 1022 | * @return string |
1009 | 1023 | */ |
1010 | 1024 | function getArchiveThumbPath( $archiveName, $suffix = false ) { |
1011 | | - return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getArchiveThumbRel( $archiveName, $suffix ); |
| 1025 | + $this->assertRepoDefined(); |
| 1026 | + return $this->repo->getZonePath( 'thumb' ) . '/' . |
| 1027 | + $this->getArchiveThumbRel( $archiveName, $suffix ); |
1012 | 1028 | } |
1013 | 1029 | |
1014 | 1030 | /** |
— | — | @@ -1018,6 +1034,7 @@ |
1019 | 1035 | * @return string |
1020 | 1036 | */ |
1021 | 1037 | function getThumbPath( $suffix = false ) { |
| 1038 | + $this->assertRepoDefined(); |
1022 | 1039 | $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getRel(); |
1023 | 1040 | if ( $suffix !== false ) { |
1024 | 1041 | $path .= '/' . $suffix; |
— | — | @@ -1033,7 +1050,8 @@ |
1034 | 1051 | * @return string |
1035 | 1052 | */ |
1036 | 1053 | function getArchiveUrl( $suffix = false ) { |
1037 | | - $path = $this->repo->getZoneUrl('public') . '/archive/' . $this->getHashPath(); |
| 1054 | + $this->assertRepoDefined(); |
| 1055 | + $path = $this->repo->getZoneUrl( 'public' ) . '/archive/' . $this->getHashPath(); |
1038 | 1056 | if ( $suffix === false ) { |
1039 | 1057 | $path = substr( $path, 0, -1 ); |
1040 | 1058 | } else { |
— | — | @@ -1051,7 +1069,9 @@ |
1052 | 1070 | * @return string |
1053 | 1071 | */ |
1054 | 1072 | function getArchiveThumbUrl( $archiveName, $suffix = false ) { |
1055 | | - $path = $this->repo->getZoneUrl('thumb') . '/archive/' . $this->getHashPath() . rawurlencode( $archiveName ) . "/"; |
| 1073 | + $this->assertRepoDefined(); |
| 1074 | + $path = $this->repo->getZoneUrl( 'thumb' ) . '/archive/' . |
| 1075 | + $this->getHashPath() . rawurlencode( $archiveName ) . "/"; |
1056 | 1076 | if ( $suffix === false ) { |
1057 | 1077 | $path = substr( $path, 0, -1 ); |
1058 | 1078 | } else { |
— | — | @@ -1068,6 +1088,7 @@ |
1069 | 1089 | * @return path |
1070 | 1090 | */ |
1071 | 1091 | function getThumbUrl( $suffix = false ) { |
| 1092 | + $this->assertRepoDefined(); |
1072 | 1093 | $path = $this->repo->getZoneUrl('thumb') . '/' . $this->getUrlRel(); |
1073 | 1094 | if ( $suffix !== false ) { |
1074 | 1095 | $path .= '/' . rawurlencode( $suffix ); |
— | — | @@ -1083,6 +1104,7 @@ |
1084 | 1105 | * @return string |
1085 | 1106 | */ |
1086 | 1107 | function getArchiveVirtualUrl( $suffix = false ) { |
| 1108 | + $this->assertRepoDefined(); |
1087 | 1109 | $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath(); |
1088 | 1110 | if ( $suffix === false ) { |
1089 | 1111 | $path = substr( $path, 0, -1 ); |
— | — | @@ -1100,6 +1122,7 @@ |
1101 | 1123 | * @return string |
1102 | 1124 | */ |
1103 | 1125 | function getThumbVirtualUrl( $suffix = false ) { |
| 1126 | + $this->assertRepoDefined(); |
1104 | 1127 | $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel(); |
1105 | 1128 | if ( $suffix !== false ) { |
1106 | 1129 | $path .= '/' . rawurlencode( $suffix ); |
— | — | @@ -1115,6 +1138,7 @@ |
1116 | 1139 | * @return string |
1117 | 1140 | */ |
1118 | 1141 | function getVirtualUrl( $suffix = false ) { |
| 1142 | + $this->assertRepoDefined(); |
1119 | 1143 | $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel(); |
1120 | 1144 | if ( $suffix !== false ) { |
1121 | 1145 | $path .= '/' . rawurlencode( $suffix ); |
— | — | @@ -1126,6 +1150,7 @@ |
1127 | 1151 | * @return bool |
1128 | 1152 | */ |
1129 | 1153 | function isHashed() { |
| 1154 | + $this->assertRepoDefined(); |
1130 | 1155 | return $this->repo->isHashed(); |
1131 | 1156 | } |
1132 | 1157 | |
— | — | @@ -1205,7 +1230,7 @@ |
1206 | 1231 | /** |
1207 | 1232 | * Returns the repository |
1208 | 1233 | * |
1209 | | - * @return FileRepo |
| 1234 | + * @return FileRepo|false |
1210 | 1235 | */ |
1211 | 1236 | function getRepo() { |
1212 | 1237 | return $this->repo; |
— | — | @@ -1384,7 +1409,7 @@ |
1385 | 1410 | */ |
1386 | 1411 | function getDescriptionText() { |
1387 | 1412 | global $wgMemc, $wgLang; |
1388 | | - if ( !$this->repo->fetchDescription ) { |
| 1413 | + if ( !$this->repo || !$this->repo->fetchDescription ) { |
1389 | 1414 | return false; |
1390 | 1415 | } |
1391 | 1416 | $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgLang->getCode() ); |
— | — | @@ -1635,6 +1660,26 @@ |
1636 | 1661 | function isMissing() { |
1637 | 1662 | return false; |
1638 | 1663 | } |
| 1664 | + |
| 1665 | + /** |
| 1666 | + * Assert that $this->repo is set to a valid FileRepo instance |
| 1667 | + * @throws MWException |
| 1668 | + */ |
| 1669 | + protected function assertRepoDefined() { |
| 1670 | + if ( !( $this->repo instanceof $this->repoClass ) ) { |
| 1671 | + throw new MWException( "A {$this->repoClass} object is not set for this File.\n" ); |
| 1672 | + } |
| 1673 | + } |
| 1674 | + |
| 1675 | + /** |
| 1676 | + * Assert that $this->title is set to a Title |
| 1677 | + * @throws MWException |
| 1678 | + */ |
| 1679 | + protected function assertTitleDefined() { |
| 1680 | + if ( !( $this->title instanceof Title ) ) { |
| 1681 | + throw new MWException( "A Title object is not set for this File.\n" ); |
| 1682 | + } |
| 1683 | + } |
1639 | 1684 | } |
1640 | 1685 | /** |
1641 | 1686 | * Aliases for backwards compatibility with 1.6 |
Index: trunk/phase3/includes/filerepo/ForeignAPIFile.php |
— | — | @@ -16,6 +16,8 @@ |
17 | 17 | |
18 | 18 | private $mExists; |
19 | 19 | |
| 20 | + protected $repoClass = 'ForeignApiRepo'; |
| 21 | + |
20 | 22 | /** |
21 | 23 | * @param $title |
22 | 24 | * @param $repo ForeignApiRepo |
— | — | @@ -24,8 +26,11 @@ |
25 | 27 | */ |
26 | 28 | function __construct( $title, $repo, $info, $exists = false ) { |
27 | 29 | parent::__construct( $title, $repo ); |
| 30 | + |
28 | 31 | $this->mInfo = $info; |
29 | 32 | $this->mExists = $exists; |
| 33 | + |
| 34 | + $this->assertRepoDefined(); |
30 | 35 | } |
31 | 36 | |
32 | 37 | /** |