ImageGallery.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. if ( ! defined( 'MEDIAWIKI' ) )
  3. die( 1 );
  4. /**
  5. * Image gallery
  6. *
  7. * Add images to the gallery using add(), then render that list to HTML using toHTML().
  8. *
  9. * @ingroup Media
  10. */
  11. class ImageGallery
  12. {
  13. var $mImages, $mShowBytes, $mShowFilename;
  14. var $mCaption = false;
  15. var $mSkin = false;
  16. var $mRevisionId = 0;
  17. /**
  18. * Hide blacklisted images?
  19. */
  20. var $mHideBadImages;
  21. /**
  22. * Registered parser object for output callbacks
  23. */
  24. var $mParser;
  25. /**
  26. * Contextual title, used when images are being screened
  27. * against the bad image list
  28. */
  29. private $contextTitle = false;
  30. private $mPerRow = 4; // How many images wide should the gallery be?
  31. private $mWidths = 120, $mHeights = 120; // How wide/tall each thumbnail should be
  32. private $mAttribs = array();
  33. /**
  34. * Create a new image gallery object.
  35. */
  36. function __construct( ) {
  37. $this->mImages = array();
  38. $this->mShowBytes = true;
  39. $this->mShowFilename = true;
  40. $this->mParser = false;
  41. $this->mHideBadImages = false;
  42. }
  43. /**
  44. * Register a parser object
  45. */
  46. function setParser( $parser ) {
  47. $this->mParser = $parser;
  48. }
  49. /**
  50. * Set bad image flag
  51. */
  52. function setHideBadImages( $flag = true ) {
  53. $this->mHideBadImages = $flag;
  54. }
  55. /**
  56. * Set the caption (as plain text)
  57. *
  58. * @param $caption Caption
  59. */
  60. function setCaption( $caption ) {
  61. $this->mCaption = htmlspecialchars( $caption );
  62. }
  63. /**
  64. * Set the caption (as HTML)
  65. *
  66. * @param $caption Caption
  67. */
  68. public function setCaptionHtml( $caption ) {
  69. $this->mCaption = $caption;
  70. }
  71. /**
  72. * Set how many images will be displayed per row.
  73. *
  74. * @param int $num > 0; invalid numbers will be rejected
  75. */
  76. public function setPerRow( $num ) {
  77. if ($num > 0) {
  78. $this->mPerRow = (int)$num;
  79. }
  80. }
  81. /**
  82. * Set how wide each image will be, in pixels.
  83. *
  84. * @param int $num > 0; invalid numbers will be ignored
  85. */
  86. public function setWidths( $num ) {
  87. if ($num > 0) {
  88. $this->mWidths = (int)$num;
  89. }
  90. }
  91. /**
  92. * Set how high each image will be, in pixels.
  93. *
  94. * @param int $num > 0; invalid numbers will be ignored
  95. */
  96. public function setHeights( $num ) {
  97. if ($num > 0) {
  98. $this->mHeights = (int)$num;
  99. }
  100. }
  101. /**
  102. * Instruct the class to use a specific skin for rendering
  103. *
  104. * @param $skin Skin object
  105. */
  106. function useSkin( $skin ) {
  107. $this->mSkin = $skin;
  108. }
  109. /**
  110. * Return the skin that should be used
  111. *
  112. * @return Skin object
  113. */
  114. function getSkin() {
  115. if( !$this->mSkin ) {
  116. global $wgUser;
  117. $skin = $wgUser->getSkin();
  118. } else {
  119. $skin = $this->mSkin;
  120. }
  121. return $skin;
  122. }
  123. /**
  124. * Add an image to the gallery.
  125. *
  126. * @param $title Title object of the image that is added to the gallery
  127. * @param $html String: additional HTML text to be shown. The name and size of the image are always shown.
  128. */
  129. function add( $title, $html='' ) {
  130. if ( $title instanceof File ) {
  131. // Old calling convention
  132. $title = $title->getTitle();
  133. }
  134. $this->mImages[] = array( $title, $html );
  135. wfDebug( "ImageGallery::add " . $title->getText() . "\n" );
  136. }
  137. /**
  138. * Add an image at the beginning of the gallery.
  139. *
  140. * @param $title Title object of the image that is added to the gallery
  141. * @param $html String: Additional HTML text to be shown. The name and size of the image are always shown.
  142. */
  143. function insert( $title, $html='' ) {
  144. if ( $title instanceof File ) {
  145. // Old calling convention
  146. $title = $title->getTitle();
  147. }
  148. array_unshift( $this->mImages, array( &$title, $html ) );
  149. }
  150. /**
  151. * isEmpty() returns true if the gallery contains no images
  152. */
  153. function isEmpty() {
  154. return empty( $this->mImages );
  155. }
  156. /**
  157. * Enable/Disable showing of the file size of an image in the gallery.
  158. * Enabled by default.
  159. *
  160. * @param $f Boolean: set to false to disable.
  161. */
  162. function setShowBytes( $f ) {
  163. $this->mShowBytes = ( $f == true);
  164. }
  165. /**
  166. * Enable/Disable showing of the filename of an image in the gallery.
  167. * Enabled by default.
  168. *
  169. * @param $f Boolean: set to false to disable.
  170. */
  171. function setShowFilename( $f ) {
  172. $this->mShowFilename = ( $f == true);
  173. }
  174. /**
  175. * Set arbitrary attributes to go on the HTML gallery output element.
  176. * Should be suitable for a &lt;table&gt; element.
  177. *
  178. * Note -- if taking from user input, you should probably run through
  179. * Sanitizer::validateAttributes() first.
  180. *
  181. * @param array of HTML attribute pairs
  182. */
  183. function setAttributes( $attribs ) {
  184. $this->mAttribs = $attribs;
  185. }
  186. /**
  187. * Return a HTML representation of the image gallery
  188. *
  189. * For each image in the gallery, display
  190. * - a thumbnail
  191. * - the image name
  192. * - the additional text provided when adding the image
  193. * - the size of the image
  194. *
  195. */
  196. function toHTML() {
  197. global $wgLang;
  198. $sk = $this->getSkin();
  199. $attribs = Sanitizer::mergeAttributes(
  200. array(
  201. 'class' => 'gallery',
  202. 'cellspacing' => '0',
  203. 'cellpadding' => '0' ),
  204. $this->mAttribs );
  205. $s = Xml::openElement( 'table', $attribs );
  206. if( $this->mCaption )
  207. $s .= "\n\t<caption>{$this->mCaption}</caption>";
  208. $params = array( 'width' => $this->mWidths, 'height' => $this->mHeights );
  209. $i = 0;
  210. foreach ( $this->mImages as $pair ) {
  211. $nt = $pair[0];
  212. $text = $pair[1];
  213. # Give extensions a chance to select the file revision for us
  214. $time = $descQuery = false;
  215. wfRunHooks( 'BeforeGalleryFindFile', array( &$this, &$nt, &$time, &$descQuery ) );
  216. $img = wfFindFile( $nt, $time );
  217. if( $nt->getNamespace() != NS_FILE || !$img ) {
  218. # We're dealing with a non-image, spit out the name and be done with it.
  219. $thumbhtml = "\n\t\t\t".'<div style="height: '.($this->mHeights*1.25+2).'px;">'
  220. . htmlspecialchars( $nt->getText() ) . '</div>';
  221. } elseif( $this->mHideBadImages && wfIsBadImage( $nt->getDBkey(), $this->getContextTitle() ) ) {
  222. # The image is blacklisted, just show it as a text link.
  223. $thumbhtml = "\n\t\t\t".'<div style="height: '.($this->mHeights*1.25+2).'px;">'
  224. . $sk->makeKnownLinkObj( $nt, htmlspecialchars( $nt->getText() ) ) . '</div>';
  225. } elseif( !( $thumb = $img->transform( $params ) ) ) {
  226. # Error generating thumbnail.
  227. $thumbhtml = "\n\t\t\t".'<div style="height: '.($this->mHeights*1.25+2).'px;">'
  228. . htmlspecialchars( $img->getLastError() ) . '</div>';
  229. } else {
  230. $vpad = floor( ( 1.25*$this->mHeights - $thumb->height ) /2 ) - 2;
  231. $thumbhtml = "\n\t\t\t".
  232. '<div class="thumb" style="padding: ' . $vpad . 'px 0; width: ' .($this->mWidths+30).'px;">'
  233. # Auto-margin centering for block-level elements. Needed now that we have video
  234. # handlers since they may emit block-level elements as opposed to simple <img> tags.
  235. # ref http://css-discuss.incutio.com/?page=CenteringBlockElement
  236. . '<div style="margin-left: auto; margin-right: auto; width: ' .$this->mWidths.'px;">'
  237. . $thumb->toHtml( array( 'desc-link' => true, 'desc-query' => $descQuery ) ) . '</div></div>';
  238. // Call parser transform hook
  239. if ( $this->mParser && $img->getHandler() ) {
  240. $img->getHandler()->parserTransformHook( $this->mParser, $img );
  241. }
  242. }
  243. //TODO
  244. //$ul = $sk->makeLink( $wgContLang->getNsText( MWNamespace::getUser() ) . ":{$ut}", $ut );
  245. if( $this->mShowBytes ) {
  246. if( $img ) {
  247. $nb = wfMsgExt( 'nbytes', array( 'parsemag', 'escape'),
  248. $wgLang->formatNum( $img->getSize() ) );
  249. } else {
  250. $nb = wfMsgHtml( 'filemissing' );
  251. }
  252. $nb = "$nb<br />\n";
  253. } else {
  254. $nb = '';
  255. }
  256. $textlink = $this->mShowFilename ?
  257. $sk->makeKnownLinkObj( $nt, htmlspecialchars( $wgLang->truncate( $nt->getText(), 20 ) ) ) . "<br />\n" :
  258. '' ;
  259. # ATTENTION: The newline after <div class="gallerytext"> is needed to accommodate htmltidy which
  260. # in version 4.8.6 generated crackpot html in its absence, see:
  261. # http://bugzilla.wikimedia.org/show_bug.cgi?id=1765 -Ævar
  262. if ( $i % $this->mPerRow == 0 ) {
  263. $s .= "\n\t<tr>";
  264. }
  265. $s .=
  266. "\n\t\t" . '<td><div class="gallerybox" style="width: '.($this->mWidths+35).'px;">'
  267. . $thumbhtml
  268. . "\n\t\t\t" . '<div class="gallerytext">' . "\n"
  269. . $textlink . $text . $nb
  270. . "\n\t\t\t</div>"
  271. . "\n\t\t</div></td>";
  272. if ( $i % $this->mPerRow == $this->mPerRow - 1 ) {
  273. $s .= "\n\t</tr>";
  274. }
  275. ++$i;
  276. }
  277. if( $i % $this->mPerRow != 0 ) {
  278. $s .= "\n\t</tr>";
  279. }
  280. $s .= "\n</table>";
  281. return $s;
  282. }
  283. /**
  284. * @return int Number of images in the gallery
  285. */
  286. public function count() {
  287. return count( $this->mImages );
  288. }
  289. /**
  290. * Set the contextual title
  291. *
  292. * @param Title $title Contextual title
  293. */
  294. public function setContextTitle( $title ) {
  295. $this->contextTitle = $title;
  296. }
  297. /**
  298. * Get the contextual title, if applicable
  299. *
  300. * @return mixed Title or false
  301. */
  302. public function getContextTitle() {
  303. return is_object( $this->contextTitle ) && $this->contextTitle instanceof Title
  304. ? $this->contextTitle
  305. : false;
  306. }
  307. } //class