2 rcs_id('$Id: PhotoAlbum.php,v 1.8 2004-06-01 15:28:01 rurban Exp $');
4 Copyright 2003, 2004 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * WikiPlugin which makes an 'album' of a set of photos with optional
27 * @author: Ted Vinke <teddy@jouwfeestje.com>
28 * local fs by Reini Urban
32 * src="http://server/textfile" or localfile or localdir or nothing
40 * (1) No src specified. Means [wikipagename].jpg from fixed albumlocation
41 * will be displayed e.g. "Sandbox.jpg".
43 * You can set the following constants:
46 define('allow_album_location', true);
47 define('album_location', 'http://kw.jouwfeestje.com/foto/redactie');
48 define('album_default_extension', '.jpg');
51 * (2) Textfile. Local or remote e.g. http://myserver/images/MyPhotos.txt
52 * E.g. possible content of a valid textfile:
54 * photo-01.jpg; Me and my girlfriend
56 * christmas.gif; Merry Christmas!
58 * Inside textfile, filenames and optional descriptions are seperated by
59 * constant 'desc_separator' (default is semi-colon) on each line. Listed
60 * files must be in same directory as textfile itself, so don't use
61 * relative paths inside textfile.
64 define('desc_separator', ';');
68 * Need weblocation="" the webpath to the srcdir
70 * Other parameters that need explaining:
73 * "mode" "normal" - Normal table which shows photos full-size
74 * "thumbs" - WinXP thumbnail style
75 * "tiles" - WinXP tiles style
76 * "list" - WinXP list style
77 * "slide" - Not yet implemented
79 * "numcols" Amount of columns per row in table
81 * "showdesc" "none" - No descriptions next to photos
82 * "name" - Only filename shown
83 * "desc" - Only description (from textfile) shown
84 * "both" - If no description found, then filename will be used
86 * "link" If true, each image will be hyperlink to page where only that
87 * photo will be shown full-size. Only works when mode != 'normal'
89 * "attrib" Array which can hold:
90 * "sort" - sort shown photos alphabetically
91 * "nowrap" - descriptions won't be wrapped
92 * "alt" - descs instead of filenames are used in image ALT-tags
95 * "hlcolor" Cell background and highlight color
97 * "align" Aligment of cell: "left", "center", "right"
100 * "width" Size of shown photos. Either absolute value (e.g. "50") or
101 * HTML style percentage (e.g. "75%") or "auto" for no special
104 * "cellwidth" Width of cells in table. Either absolute value in pixels, HTML
105 * style percentage, "auto" (no special action), "equal" (where
106 * all columns are equally sized) or "image" (take height and
107 * width of the photo in that cell).
109 * "tablewidth" Guess what.
112 define('default_mode', 'normal'); // normal|thumbs|tiles|list
113 define('default_numcols', 3); // photos per row
114 define('default_showdesc', 'both'); // none|name|desc|both
115 define('default_link', true); // show link to original sized photo
116 define('default_attrib', ''); // 'sort, nowrap, alt'
117 define('default_bgcolor', '#eae8e8'); // cell bgcolor (lightgrey)
118 define('default_hlcolor', '#c0c0ff'); // highlight color (lightblue)
119 define('default_align', 'center'); // alignment of all
120 define('default_height', 'auto'); // image height (auto|75|100%)
121 define('default_width', 'auto'); // image width (auto|75|100%)
122 define('default_cellwidth', 'image'); // cell (auto|equal|image|75|100%)
123 define('default_tablewidth', 1); // table (75|100%)
128 * - parse any local directory for pictures
129 * - implement WinXP style 'slide' mode
130 * - specify picture(s) as parameter(s)
131 * - limit amount of pictures on one page
132 * - use PHP to really resize or greyscale images (only where GD library
137 * - reading height and width, from images with spaces in their names, fails
139 * Fixed album location idea by Philip J. Hollenback. Thanks!
142 class WikiPlugin_PhotoAlbum
145 function getName () {
146 return _("PhotoAlbum");
149 function getDescription () {
150 return _("Displays a set of photos listed in a text file with optional descriptions");
153 function getVersion() {
154 return preg_replace("/[Revision: $]/", '',
155 "\$Revision: 1.8 $");
158 function getDefaultArguments() {
159 return array('src' => '', // textfile
160 'mode' => default_mode,
161 'numcols' => default_numcols,
162 'showdesc' => default_showdesc,
163 'link' => default_link,
164 'attrib' => default_attrib,
165 'bgcolor' => default_bgcolor,
166 'hlcolor' => default_hlcolor,
167 'align' => default_align,
168 'height' => default_height,
169 'width' => default_width,
170 'cellwidth'=> default_cellwidth,
171 'tablewidth'=> default_tablewidth,
172 'p' => false, // "displaythissinglephoto.jpg"
173 'h' => false, // "highlightcolorofthisphoto.jpg"
174 'weblocation' => false, // if src = localfs the web location
177 // attrib arg allows multiple attributes attrib=sort,nowrap,alt
178 // 'sort' sorts alphabetically, 'nowrap' for cells, 'alt' to use
179 // descriptions (instead of filenames) for image alt-tags
181 function run($dbi, $argstr, $request) {
182 extract($this->getArgs($argstr, $request));
184 $attributes = $attrib ? explode(",", $attrib) : array();
189 // check all parameters
191 // what type do we have?
194 $src = $request->getArg('pagename');
195 $error = $this->fromLocation($src, $photos);
197 $error = $this->fromFile($src, $photos, $weblocation);
200 return $this->error($error);
203 if ($numcols < 1) $numcols = 1;
204 if ($align != 'left' && $align != 'center' && $align != 'right') {
205 $align = default_align;
208 if (count($photos) == 0) return;
210 if (in_array("sort", $attributes))
217 // set some fixed properties for each $mode
218 if ($mode == 'thumbs' || $mode == 'tiles') {
219 $attributes = array_merge($attributes, "alt");
220 $attributes = array_merge($attributes, "nowrap");
221 $cellwidth = 'auto'; // else cell won't nowrap
224 } elseif ($mode == 'list') {
227 if ($showdesc != "none") {
233 while (list($key, $value) = each($photos)) {
234 if ($p && basename($value["name"]) != "$p") {
237 if ($h && basename($value["name"]) == "$h") {
238 $color = $hlcolor ? $hlcolor : $bgcolor;
242 // $params will be used for each <img > tag
243 $params = array('src' => $value["name"],
245 'alt' => ($value["desc"] != "" &&
246 in_array("alt", $attributes)) ?
248 basename($value["name"])
257 $value["desc"] = basename($value["name"]);
262 $value["desc"] = ($value["desc"] != "") ?
264 basename($value["name"]);
268 // FIXME: get getimagesize to work with names with spaces in it.
269 // convert $value["name"] from webpath to local path
270 $size = @getimagesize($value["name"]); // try " " => "\\ "
271 if (!$size and !empty($value["src"])) {
272 $size = @getimagesize($value["src"]);
274 trigger_error("Unable to getimagesize(".$value["name"].")",E_USER_NOTICE);
278 $newwidth = $this->newSize($size[0], $width);
279 $newheight = $this->newSize($size[1], $height);
281 if ($width != 'auto' && $newwidth > 0) {
282 $params = array_merge($params, array("width" => $newwidth));
284 if ($height != 'auto' && $newheight > 0) {
285 $params = array_merge($params, array("height" => $newheight));
289 $cell = array('align' => "center",
291 'bgcolor' => "$color",
293 if ($cellwidth != 'auto') {
294 if ($cellwidth == 'equal') {
295 $newcellwidth = round(100/$numcols)."%";
296 } else if ($cellwidth == 'image') {
297 $newcellwidth = $newwidth;
299 $newcellwidth = $cellwidth;
301 $cell = array_merge($cell, array("width" => $newcellwidth));
303 if (in_array("nowrap", $attributes)) {
304 $cell = array_merge($cell, array("nowrap" => ""));
306 //create url to display single larger version of image on page
307 $url = WikiURL($request->getPage(),
308 array("p" => basename($value["name"])));
309 $b_url = WikiURL($request->getPage(),
310 array("h" => basename($value["name"]))).
312 basename($value["name"]);
313 $url_text = $link ? HTML::a(array("href" => "$url"),
314 basename($value["name"])) :
315 basename($value["name"]);
317 $url_image = $link ? HTML::a(array("href" => "$url"),
318 HTML::img($params)) :
321 $url_image = $link ? HTML::a(array("href" => "$b_url"),
322 HTML::img($params)) :
325 $url_text = HTML::a(array("name" => basename($value["name"])),
327 // here we use different modes
328 if ($mode == 'tiles') {
329 $row->pushContent(HTML::td($cell,
330 HTML::table(array("cellpadding" => 1, "border" => 0),
332 HTML::td(array("valign" => "top", "rowspan" => 2),
334 HTML::td(array("valign" => "top", "nowrap" => 0),
335 HTML::small(HTML::strong($url_text)),
337 HTML::small($size[0].
342 } else if ($mode == 'list') {
343 $desc = ($showdesc != 'none') ? $value["desc"] : '';
345 HTML::td(array("valign" => "top",
347 "bgcolor" => $color),
348 HTML::small(HTML::strong($url_text))));
350 HTML::td(array("valign" => "top",
352 "bgcolor" => $color),
353 HTML::small($size[0].
359 $row->pushContent(HTML::td(array("valign" => "top",
361 "bgcolor" => $color),
362 HTML::small($desc)));
364 } else if ($mode == 'thumbs') {
365 $desc = ($showdesc != 'none') ?
366 HTML::p(HTML::a(array("href" => "$url"),
372 // FIXME: no HtmlElement for fontsizes?
373 // rurban: use ->setAttr("style","font-size:small;")
374 // but better use a css class
375 HTML::span(array('class'=>'gensmall'),$desc)
377 } else /* 'normal' mode */ {
378 $desc = ($showdesc != 'none') ? HTML::p($value["desc"]) : '';
382 // FIXME: no HtmlElement for fontsizes?
383 HTML::span(array('class'=>'gensmall'),$desc)
387 // no more images in one row as defined by $numcols
388 if ( ($key + 1) % $numcols == 0 ||
389 ($key + 1) == count($photos) ||
391 $html->pushcontent(HTML::tr($row));
392 $row->setContent('');
397 $html = HTML::table(array("border" => 0,
400 "width" => $tablewidth),
403 $html = HTML::div(array("align" => $align), $html);
408 * Calculate the new size in pixels when the original size
409 * with a value is given.
411 * @param integer $oldSize Absolute no. of pixels
412 * @param mixed $value Either absolute no. or HTML percentage e.g. '50%'
413 * @return integer New size in pixels
415 function newSize($oldSize, $value) {
416 if (substr($value, strlen($value) - 1) != "%") {
419 substr_replace($value, "%", "");
420 return round(($oldSize*$value)/100);
424 * fromLocation - read only one picture from fixed album_location
425 * and return it in array $photos
427 * @param string $src Name of page
428 * @param array $photos
429 * @return string Error if fixed location is not allowed
431 function fromLocation($src, &$photos) {
432 if (!allow_album_location) {
433 return $this->error(_("Fixed album location is not allowed. Please specify parameter src."));
435 $photos[count($photos)] =
436 array ("name" => album_location."/$src".album_default_extension,
442 * fromFile - read pictures & descriptions (separated by desc_sep)
443 * from file $src and return it in array $photos
445 * @param string $src Full path and filename of textfile
446 * @param array $photos
447 * @return string Error when bad url or file couldn't be opened
449 function fromFile($src, &$photos, $webpath = false) {
450 if (! IsSafeURL($src)) {
451 return $this->error(_("Bad url in src: remove all of <, >, \""));
453 if (!preg_match('/^(http|ftp|https):\/\//i',$src)) {
454 // check if src is a directory
455 if (file_exists($src) and filetype($src) == 'dir') {
458 foreach (array('jpeg','jpg','png','gif') as $ext) {
459 $fileset = new fileSet($src, "*.$ext");
460 $list = array_merge($list,$fileset->getFiles());
462 // convert dirname($src) (local fs path) to web path
465 // assume relative src. default: "themes/Hawaiian/images/pictures"
466 $webpath = DATA_PATH . '/' . $src;
468 foreach ($list as $file) {
469 // convert local path to webpath
470 $photos[] = array ("name" => $webpath . "/$file",
471 "src" => $src . "/$file",
478 // fixed: get current value, not stored value.
479 // todo: use lib/HttpClient.php (stdlib.php:url_get_contents())
480 if (! get_cfg_var('allow_url_fopen')) {
481 return $this->error(fmt("Wrong server setting: allow_url_fopen set to Off"));
484 @$fp = fopen ($src,"r");
486 return $this->error(fmt("Unable to read %s ", $src));
488 while ($data = fgetcsv ($fp, 1024, desc_separator)) {
489 if (count($data) == 0 || empty($data[0]))
491 // otherwise when empty 'undefined index 1' PHP warning appears
494 $photos[count($photos)] = array ("name" => dirname($src).
497 "desc" => trim("$data[1]"),
504 // $Log: not supported by cvs2svn $
505 // Revision 1.7 2004/05/03 20:44:55 rurban
506 // fixed gettext strings
507 // new SqlResult plugin
508 // _WikiTranslation: fixed init_locale
510 // Revision 1.6 2004/04/18 00:19:30 rurban
511 // better default example with local src, don't require weblocation for
512 // the default setup, better docs, fixed ini_get => get_cfg_var("allow_url_fopen"),
513 // no HttpClient lib yet.
515 // Revision 1.5 2004/03/09 12:10:23 rurban
516 // fixed getimagesize problem with local dir.
518 // Revision 1.4 2004/02/28 21:14:08 rurban
519 // generally more PHPDOC docs
520 // see http://xarch.tu-graz.ac.at/home/rurban/phpwiki/xref/
521 // fxied WikiUserNew pref handling: empty theme not stored, save only
522 // changed prefs, sql prefs improved, fixed password update,
523 // removed REPLACE sql (dangerous)
524 // moved gettext init after the locale was guessed
525 // + some minor changes
527 // Revision 1.3 2004/02/27 08:03:35 rurban
528 // Update from version 1.2 by Ted Vinke
529 // implemented the localdir support
531 // Revision 1.2 2004/02/17 12:11:36 rurban
532 // added missing 4th basepage arg at plugin->run() to almost all plugins. This caused no harm so far, because it was silently dropped on normal usage. However on plugin internal ->run invocations it failed. (InterWikiSearch, IncludeSiteMap, ...)
534 // Revision 1.1 2003/01/05 04:21:06 carstenklapp
535 // New plugin by Ted Vinke (sf tracker patch #661189)
543 // c-hanging-comment-ender-p: nil
544 // indent-tabs-mode: nil