2 rcs_id('$Id: PhotoAlbum.php,v 1.11 2004-12-06 19:50:05 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 * Display an album of a set of photos with optional descriptions.
26 * @author: Ted Vinke <teddy@jouwfeestje.com>
27 * Reini Urban (local fs)
31 * src="http://server/textfile" or localfile or localdir
38 * "src": textfile of images or directory of images (local or remote)
39 * Local or remote e.g. http://myserver/images/MyPhotos.txt or http://myserver/images/
40 * Possible content of a valid textfile:
41 * photo-01.jpg; Me and my girlfriend
43 * christmas.gif; Merry Christmas!
45 * Inside textfile, filenames and optional descriptions are seperated by
46 * semi-colon on each line. Listed files must be in same directory as textfile
47 * itself, so don't use relative paths inside textfile.
49 * "url": defines the the webpath to the srcdir directory (formerly called weblocation)
54 * - implement WinXP style 'slide' mode, javascript tricks
55 * - specify picture(s) as parameter(s)
56 * - limit amount of pictures on one page
57 * - use PHP to really resize or greyscale images (only where GD library supports it)
60 * - reading height and width from images with spaces in their names fails.
62 * Fixed album location idea by Philip J. Hollenback. Thanks!
65 class WikiPlugin_PhotoAlbum
69 return _("PhotoAlbum");
72 function getDescription () {
73 return _("Displays a set of photos listed in a text file with optional descriptions");
76 function getVersion() {
77 return preg_replace("/[Revision: $]/", '',
78 "\$Revision: 1.11 $");
81 // Avoid nameclash, so it's disabled. We allow any url.
82 // define('allow_album_location', true);
83 // define('album_location', 'http://kw.jouwfeestje.com/foto/redactie');
84 // define('album_default_extension', '.jpg');
85 // define('desc_separator', ';');
87 function getDefaultArguments() {
88 return array('src' => '', // textfile of image list, or local dir.
89 'url' => '', // if src=localfs, url prefix (webroot for the links)
90 'mode' => 'normal', // normal|thumbs|tiles|list
91 // "normal" - Normal table which shows photos full-size
92 // "thumbs" - WinXP thumbnail style
93 // "tiles" - WinXP tiles style
94 // "list" - WinXP list style
95 // "slide" - Not yet implemented
96 'numcols' => 3, // photos per row, columns
97 'showdesc' => 'both', // none|name|desc|both
98 // "none" - No descriptions next to photos
99 // "name" - Only filename shown
100 // "desc" - Only description (from textfile) shown
101 // "both" - If no description found, then filename will be used
102 'link' => true, // show link to original sized photo
103 // If true, each image will be hyperlinked to a page where the single
104 // photo will be shown full-size. Only works when mode != 'normal'
105 'attrib' => '', // 'sort, nowrap, alt'
106 // attrib arg allows multiple attributes: attrib=sort,nowrap,alt
107 // 'sort' sorts alphabetically, 'nowrap' for cells, 'alt' to use
108 // descs instead of filenames in image ALT-tags
109 'bgcolor' => '#eae8e8', // cell bgcolor (lightgrey)
110 'hlcolor' => '#c0c0ff', // highlight color (lightblue)
111 'align' => 'center', // alignment of table
112 'height' => 'auto', // image height (auto|75|100%)
113 'width' => 'auto', // image width (auto|75|100%)
114 // Size of shown photos. Either absolute value (e.g. "50") or
115 // HTML style percentage (e.g. "75%") or "auto" for no special
117 'cellwidth'=> 'image', // cell (auto|equal|image|75|100%)
118 // Width of cells in table. Either absolute value in pixels, HTML
119 // style percentage, "auto" (no special action), "equal" (where
120 // all columns are equally sized) or "image" (take height and
121 // width of the photo in that cell).
122 'tablewidth'=> false, // table (75|100%)
123 'p' => false, // "displaythissinglephoto.jpg"
124 'h' => false, // "highlightcolorofthisphoto.jpg"
127 // descriptions (instead of filenames) for image alt-tags
129 function run($dbi, $argstr, &$request, $basepage) {
130 extract($this->getArgs($argstr, $request));
132 $attributes = $attrib ? explode(",", $attrib) : array();
136 // check all parameters
137 // what type do we have?
140 $src = $request->getArg('pagename');
141 $error = $this->fromLocation($src, $photos);
143 $error = $this->fromFile($src, $photos, $url);
146 return $this->error($error);
149 if ($numcols < 1) $numcols = 1;
150 if ($align != 'left' && $align != 'center' && $align != 'right') {
153 if (count($photos) == 0) return;
155 if (in_array("sort", $attributes))
162 // set some fixed properties for each $mode
163 if ($mode == 'thumbs' || $mode == 'tiles') {
164 $attributes = array_merge($attributes, "alt");
165 $attributes = array_merge($attributes, "nowrap");
166 $cellwidth = 'auto'; // else cell won't nowrap
169 } elseif ($mode == 'list') {
172 if ($showdesc != "none") {
178 while (list($key, $value) = each($photos)) {
179 if ($p && basename($value["name"]) != "$p") {
182 if ($h && basename($value["name"]) == "$h") {
183 $color = $hlcolor ? $hlcolor : $bgcolor;
187 // $params will be used for each <img > tag
188 $params = array('src' => $value["name"],
190 'alt' => ($value["desc"] != "" and in_array("alt", $attributes))
192 : basename($value["name"]));
199 $value["desc"] = basename($value["name"]);
204 if (!$value["desc"]) $value["desc"] = basename($value["name"]);
208 // FIXME: get getimagesize to work with names with spaces in it.
209 // convert $value["name"] from webpath to local path
210 $size = @getimagesize($value["name"]); // try " " => "\\ "
211 if (!$size and !empty($value["src"])) {
212 $size = @getimagesize($value["src"]);
214 trigger_error("Unable to getimagesize(".$value["name"].")",
219 $newwidth = $this->newSize($size[0], $width);
220 $newheight = $this->newSize($size[1], $height);
222 if ($width != 'auto' && $newwidth > 0) {
223 $params = array_merge($params, array("width" => $newwidth));
225 if ($height != 'auto' && $newheight > 0) {
226 $params = array_merge($params, array("height" => $newheight));
230 $cell = array('align' => "center",
232 'bgcolor' => "$color");
233 if ($cellwidth != 'auto') {
234 if ($cellwidth == 'equal') {
235 $newcellwidth = round(100/$numcols)."%";
236 } else if ($cellwidth == 'image') {
237 $newcellwidth = $newwidth;
239 $newcellwidth = $cellwidth;
241 $cell = array_merge($cell, array("width" => $newcellwidth));
243 if (in_array("nowrap", $attributes)) {
244 $cell = array_merge($cell, array("nowrap" => "nowrap"));
246 //create url to display single larger version of image on page
247 $url = WikiURL($request->getPage(),
248 array("p" => basename($value["name"])));
249 $b_url = WikiURL($request->getPage(),
250 array("h" => basename($value["name"]))).
252 basename($value["name"]);
253 $url_text = $link ? HTML::a(array("href" => "$url"),
254 basename($value["name"])) :
255 basename($value["name"]);
257 $url_image = $link ? HTML::a(array("href" => "$url"),
258 HTML::img($params)) :
261 $url_image = $link ? HTML::a(array("href" => "$b_url"),
262 HTML::img($params)) :
265 $url_text = HTML::a(array("name" => basename($value["name"])),
267 // here we use different modes
268 if ($mode == 'tiles') {
269 $row->pushContent(HTML::td($cell,
270 HTML::table(array("cellpadding" => 1, "border" => 0),
272 HTML::td(array("valign" => "top", "rowspan" => 2),
274 HTML::td(array("valign" => "top", "nowrap" => 0),
275 HTML::small(HTML::strong($url_text)),
277 HTML::small($size[0].
282 } elseif ($mode == 'list') {
283 $desc = ($showdesc != 'none') ? $value["desc"] : '';
285 HTML::td(array("valign" => "top",
287 "bgcolor" => $color),
288 HTML::small(HTML::strong($url_text))));
290 HTML::td(array("valign" => "top",
292 "bgcolor" => $color),
293 HTML::small($size[0].
299 $row->pushContent(HTML::td(array("valign" => "top",
301 "bgcolor" => $color),
302 HTML::small($desc)));
304 } elseif ($mode == 'thumbs') {
305 $desc = ($showdesc != 'none') ?
306 HTML::p(HTML::a(array("href" => "$url"),
312 // FIXME: no HtmlElement for fontsizes?
313 // rurban: use ->setAttr("style","font-size:small;")
314 // but better use a css class
315 HTML::span(array('class'=>'gensmall'),$desc)
317 } elseif ($mode == 'normal') {
318 $desc = ($showdesc != 'none') ? HTML::p($value["desc"]) : '';
322 // FIXME: no HtmlElement for fontsizes?
323 HTML::span(array('class'=>'gensmall'),$desc)
325 //} elseif ($mode == 'slide') {
328 return $this->error(fmt("Invalid argument: %s=%s", 'mode', $mode));
331 // no more images in one row as defined by $numcols
332 if ( ($key + 1) % $numcols == 0 ||
333 ($key + 1) == count($photos) ||
335 $html->pushcontent(HTML::tr($row));
336 $row->setContent('');
341 $html = HTML::table(array("border" => 0,
344 "width" => $tablewidth),
347 return HTML::div(array("align" => $align), $html);
351 * Calculate the new size in pixels when the original size
352 * with a value is given.
354 * @param integer $oldSize Absolute no. of pixels
355 * @param mixed $value Either absolute no. or HTML percentage e.g. '50%'
356 * @return integer New size in pixels
358 function newSize($oldSize, $value) {
359 if (trim(substr($value,strlen($value)-1)) != "%") {
362 $value = str_replace("%", "", $value);
363 return round(($oldSize*$value)/100);
367 * fromLocation - read only one picture from fixed album_location
368 * and return it in array $photos
370 * @param string $src Name of page
371 * @param array $photos
372 * @return string Error if fixed location is not allowed
374 function fromLocation($src, &$photos) {
375 /*if (!allow_album_location) {
376 return $this->error(_("Fixed album location is not allowed. Please specify parameter src."));
379 if (! IsSafeURL($src)) {
380 return $this->error(_("Bad url in src: remove all of <, >, \""));
382 $photos[] = array ("name" => $src, //album_location."/$src".album_default_extension,
387 * fromFile - read pictures & descriptions (separated by ;)
388 * from $src and return it in array $photos
390 * @param string $src path to dir or textfile (local or remote)
391 * @param array $photos
392 * @return string Error when bad url or file couldn't be opened
394 function fromFile($src, &$photos, $webpath='') {
396 if (! IsSafeURL($src)) {
397 return $this->error(_("Bad url in src: remove all of <, >, \""));
399 if (preg_match('/^(http|ftp|https):\/\//i', $src)) {
400 $src = url_get_contents($src);
402 if (!file_exists($src) and file_exists(PHPWIKI_DIR . "/$src")) {
403 $src = PHPWIKI_DIR . "/$src";
405 // check if src is a directory
406 if (file_exists($src) and filetype($src) == 'dir') {
409 foreach (array('jpeg','jpg','png','gif') as $ext) {
410 $fileset = new fileSet($src, "*.$ext");
411 $list = array_merge($list, $fileset->getFiles());
413 // convert dirname($src) (local fs path) to web path
416 // assume relative src. default: "themes/Hawaiian/images/pictures"
417 $webpath = DATA_PATH . '/' . $src_bak;
419 foreach ($list as $file) {
420 // convert local path to webpath
421 $photos[] = array ("name" => $webpath . "/$file",
422 "src" => $src . "/$file",
428 @$fp = fopen ($src, "r");
430 return $this->error(fmt("Unable to read src='%s'", $src));
432 while ($data = fgetcsv ($fp, 1024, ';')) {
433 if (count($data) == 0 || empty($data[0]))
435 if (empty($data[1])) $data[1] = '';
436 $photos[] = array ("name" => dirname($src)."/".trim($data[0]),
437 "desc" => trim($data[1]));
443 // $Log: not supported by cvs2svn $
444 // Revision 1.10 2004/12/01 19:34:13 rurban
445 // Cleanup of CONSTANT pollution.
446 // renamed weblocation to url.
448 // use fixed ";" CSV seperator
449 // fix substr_replace usage bug.
451 // Revision 1.9 2004/07/08 20:30:07 rurban
452 // plugin->run consistency: request as reference, added basepage.
453 // encountered strange bug in AllPages (and the test) which destroys ->_dbi
455 // Revision 1.8 2004/06/01 15:28:01 rurban
456 // AdminUser only ADMIN_USER not member of Administrators
457 // some RateIt improvements by dfrankow
458 // edit_toolbar buttons
460 // Revision 1.7 2004/05/03 20:44:55 rurban
461 // fixed gettext strings
462 // new SqlResult plugin
463 // _WikiTranslation: fixed init_locale
465 // Revision 1.6 2004/04/18 00:19:30 rurban
466 // better default example with local src, don't require weblocation for
467 // the default setup, better docs, fixed ini_get => get_cfg_var("allow_url_fopen"),
468 // no HttpClient lib yet.
470 // Revision 1.5 2004/03/09 12:10:23 rurban
471 // fixed getimagesize problem with local dir.
473 // Revision 1.4 2004/02/28 21:14:08 rurban
474 // generally more PHPDOC docs
475 // see http://xarch.tu-graz.ac.at/home/rurban/phpwiki/xref/
476 // fxied WikiUserNew pref handling: empty theme not stored, save only
477 // changed prefs, sql prefs improved, fixed password update,
478 // removed REPLACE sql (dangerous)
479 // moved gettext init after the locale was guessed
480 // + some minor changes
482 // Revision 1.3 2004/02/27 08:03:35 rurban
483 // Update from version 1.2 by Ted Vinke
484 // implemented the localdir support
486 // Revision 1.2 2004/02/17 12:11:36 rurban
487 // 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, ...)
489 // Revision 1.1 2003/01/05 04:21:06 carstenklapp
490 // New plugin by Ted Vinke (sf tracker patch #661189)
498 // c-hanging-comment-ender-p: nil
499 // indent-tabs-mode: nil