InstantCommons
[lhc/web/wiklou.git] / includes / filerepo / ForeignAPIFile.php
1 <?php
2 /**
3 * Foreign file accessible through api.php requests.
4 *
5 * @file
6 * @ingroup FileRepo
7 */
8
9 /**
10 * Foreign file accessible through api.php requests.
11 * Very hacky and inefficient, do not use :D
12 *
13 * @ingroup FileRepo
14 */
15 class ForeignAPIFile extends File {
16
17 private $mExists;
18
19 function __construct( $title, $repo, $info, $exists = false ) {
20 parent::__construct( $title, $repo );
21 $this->mInfo = $info;
22 $this->mExists = $exists;
23 }
24
25 static function newFromTitle( $title, $repo ) {
26 $data = $repo->fetchImageQuery( array(
27 'titles' => 'File:' . $title->getDBKey(),
28 'iiprop' => self::getProps(),
29 'prop' => 'imageinfo' ) );
30
31 $info = $repo->getImageInfo( $data );
32
33 if( $data && $info) {
34 if( isset( $data['query']['redirects'][0] ) ) {
35 $newtitle = Title::newFromText( $data['query']['redirects'][0]['to']);
36 $img = new ForeignAPIFile( $newtitle, $repo, $info, true );
37 if( $img ) $img->redirectedFrom( $title->getDBkey() );
38 } else {
39 $img = new ForeignAPIFile( $title, $repo, $info, true );
40 }
41 return $img;
42 } else {
43 return null;
44 }
45 }
46
47 /**
48 * Get the property string for iiprop and aiprop
49 */
50 static function getProps() {
51 return 'timestamp|user|comment|url|size|sha1|metadata|mime';
52 }
53
54 // Dummy functions...
55 public function exists() {
56 return $this->mExists;
57 }
58
59 public function getPath() {
60 return false;
61 }
62
63 function transform( $params, $flags = 0 ) {
64 if( !$this->canRender() ) {
65 // show icon
66 return parent::transform( $params, $flags );
67 }
68 $thumbUrl = $this->repo->getThumbUrlFromCache(
69 $this->getName(),
70 isset( $params['width'] ) ? $params['width'] : -1,
71 isset( $params['height'] ) ? $params['height'] : -1 );
72 return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
73 }
74
75 // Info we can get from API...
76 public function getWidth( $page = 1 ) {
77 return intval( @$this->mInfo['width'] );
78 }
79
80 public function getHeight( $page = 1 ) {
81 return intval( @$this->mInfo['height'] );
82 }
83
84 public function getMetadata() {
85 if ( isset( $this->mInfo['metadata'] ) ) {
86 return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
87 }
88 return null;
89 }
90
91 public static function parseMetadata( $metadata ) {
92 if( !is_array( $metadata ) ) {
93 return $metadata;
94 }
95 $ret = array();
96 foreach( $metadata as $meta ) {
97 $ret[ $meta['name'] ] = self::parseMetadata( $meta['value'] );
98 }
99 return $ret;
100 }
101
102 public function getSize() {
103 return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
104 }
105
106 public function getUrl() {
107 return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
108 }
109
110 public function getUser( $method='text' ) {
111 return isset( $this->mInfo['user'] ) ? strval( $this->mInfo['user'] ) : null;
112 }
113
114 public function getDescription() {
115 return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
116 }
117
118 function getSha1() {
119 return isset( $this->mInfo['sha1'] ) ?
120 wfBaseConvert( strval( $this->mInfo['sha1'] ), 16, 36, 31 ) :
121 null;
122 }
123
124 function getTimestamp() {
125 return wfTimestamp( TS_MW,
126 isset( $this->mInfo['timestamp'] ) ?
127 strval( $this->mInfo['timestamp'] ) :
128 null
129 );
130 }
131
132 function getMimeType() {
133 if( !isset( $this->mInfo['mime'] ) ) {
134 $magic = MimeMagic::singleton();
135 $this->mInfo['mime'] = $magic->guessTypesForExtension( $this->getExtension() );
136 }
137 return $this->mInfo['mime'];
138 }
139
140 /// @todo Fixme: may guess wrong on file types that can be eg audio or video
141 function getMediaType() {
142 $magic = MimeMagic::singleton();
143 return $magic->getMediaType( null, $this->getMimeType() );
144 }
145
146 function getDescriptionUrl() {
147 return isset( $this->mInfo['descriptionurl'] )
148 ? $this->mInfo['descriptionurl']
149 : false;
150 }
151
152 /**
153 * Only useful if we're locally caching thumbs anyway...
154 */
155 function getThumbPath( $suffix = '' ) {
156 if ( $this->repo->canCacheThumbs() ) {
157 global $wgUploadDirectory;
158 $path = $this->repo->getZonePath('thumb') . '/' . $this->getHashPath( $this->getName() );
159 if ( $suffix ) {
160 $path = $path . $suffix . '/';
161 }
162 return $path;
163 }
164 else {
165 return null;
166 }
167 }
168
169 function getThumbnails() {
170 $files = array();
171 $dir = $this->getThumbPath( $this->getName() );
172 if ( is_dir( $dir ) ) {
173 $handle = opendir( $dir );
174 if ( $handle ) {
175 while ( false !== ( $file = readdir($handle) ) ) {
176 if ( $file{0} != '.' ) {
177 $files[] = $file;
178 }
179 }
180 closedir( $handle );
181 }
182 }
183 return $files;
184 }
185
186 function purgeCache() {
187 $this->purgeThumbnails();
188 $this->purgeDescriptionPage();
189 }
190
191 function purgeDescriptionPage() {
192 global $wgMemc, $wgContLang;
193 $url = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgContLang->getCode() );
194 $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5($url) );
195 $wgMemc->delete( $key );
196 }
197
198 function purgeThumbnails() {
199 global $wgMemc;
200 $key = $this->repo->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $this->getName() );
201 $wgMemc->delete( $key );
202 $files = $this->getThumbnails();
203 $dir = $this->getThumbPath( $this->getName() );
204 foreach ( $files as $file ) {
205 unlink( $dir . $file );
206 }
207 if ( is_dir( $dir ) ) {
208 rmdir( $dir ); // Might have already gone away, spews errors if we don't.
209 }
210 }
211 }