From: Leandro Lucarella Date: Sat, 17 May 2003 04:37:08 +0000 (+0000) Subject: Draft 2. X-Git-Tag: svn_import~60 X-Git-Url: https://git.llucax.com/software/bife/bife-all.git/commitdiff_plain/338962ee423f5d2515b34af79829e9f6b854a52b Draft 2. Implemented a simple set of widgets and an album photo widget. All uses a template (PEAR's HTML_Template_Sigma) to draw itselfs. --- diff --git a/Album.php b/Album.php new file mode 100644 index 0000000..5cb8c8d --- /dev/null +++ b/Album.php @@ -0,0 +1,301 @@ + | +// | Groucho Marx | +// | Leandro Lucarella | +// +--------------------------------------------------------------------+ +// +// $Id$ +// + +require_once 'PEAR.php'; +require_once 'Util.php'; +require_once 'Image/Transform.php'; +require_once 'HTML/Template/Sigma.php'; + +/** + * Generates a photo album. + * + * This library generates a photo album dinamically. + * + * @package Hooks + * @subpackage Album + * @author Harpo Maxx + * @author Groucho Marx + * @author Leandro Lucarella + * @version $Rev$ + * @since rev 130 + * @access public + */ +class Hook_Album { + + var $root; + var $recursive; + var $thumbsdir; + var $thumbsformat; + var $exts; + + /** + * Constructor. + * + * @param string $root Root directory. + * same row. + * @param bool $recursive True if subdirectories must be + * proccessed. + * @param string $thumbsdir Directory where the thumbnails are (or + * will be generated). + * @param array $exts Comma separated extensions of photo files. + * + * @access public + */ + function Hook_Album($root = '.', $recursive = true, $thumbsformat = 'jpeg', $thumbsdir = '.thumbs', $exts = 'png,jpg,jpeg,gif') { + $this->root = $root ? $root : '.'; + $this->recursive = $recursive; + $this->thumbsdir = $thumbsdir; + $this->thumbsformat = $thumbsformat; + $this->exts = preg_split('/\s*,\s*/', $exts); + } + + /** + * Shows the photo album. + * + * Shows the photo album. + * + * @param string $photo Selected photo. + * @param int $max Maximum quantity of thumbnails to show. 0 for + * unlimited. + * @param int $cols How many thumbnails are shown in the + * + * @access public + * @todo Implement the 'max' feature! + * @todo Make the thumbs cache before showing the images so the + * browser can find the with having to refresh. + */ + function album(&$tpl, $photo = '', $max = 0, $cols = 4) { + $tpl->loadTemplateFile('bife_album.html'); + $tpl->addBlockFile('ITEMS', 'ITEM', 'bife_album_item.html'); + + $root = $this->root; + $list = $this->getList(); + $tot = count($list); + $rows = ceil($tot / $cols); + + for ($row = 0; $row < $rows; $row++) { + for ($col = 0; $col < $cols; $col++) { + $cur = $row*$cols+$col; + if ($photo = @$list[$cur]) { + $selected = ($photo['file'] === $photo); + if (is_null($photo['thumb'])) { + $photo['thumb'] = $this->makeThumb($photo['file']); + } + $tpl->setVariable( + array( + 'PHOTO' => $photo['file'], + 'DESC' => $photo['desc'], + 'THUMB' => $photo['thumb'], + ) + ); + $tpl->parse('ITEM'); + } else { + if (!@$empty) { + $tpl->replaceBlockFile('ITEM', + 'bife_album_emptyitem.html', true); + $empty = true; + } + $tpl->touchBlock('ITEM'); + $tpl->parse('ITEM'); + } + } + $tpl->parse('FILA'); + } + $tpl->setVariable('DESC', $this->getDescription()); + return $tpl->get(); + } + + /** + * Shows a photo. + * + * Shows a photo. + * + * @param string $photo Photo to show. + * + * @access public + * @since rev 131 + */ + function photo($photo) { + list($path, $name, $ext) = File_Util::splitFilename($photo); + $tpl =& new HTML_Template_Sigma('.'); + $tpl->loadTemplateFile('photo.html'); + $tpl->setVariable( + array( + 'DESC' => $name, + 'PHOTO' => $photo, + ) + ); + $tpl->show(); + } + + /** + * Makes a photo thumbnail. + * + * @param string $photo Source photo to create the thumbnail. + * @param int $size Maximum thumbnail size. + * + * @return bool True on success, false on failure. + * + * @access public + * @since rev 131 + */ + function makeThumb($photo, $size = 100) { + $format = $this->thumbsformat; + $thumb = $this->getThumbName($photo); + list($path, $name, $ext) = File_Util::splitFilename($thumb); + + $img =& Image_Transform::factory('GD'); + + $img->load($photo); + // If image is larger than the maximum size, we resize it. + if ($img->img_x > $size or $img->img_y > $size ) { + if (!is_dir($path) and !mkdir($path)) { + return false; + } + if (PEAR::isError($img)) { + return false; + } + if (!$img->scale($size)) { + return false; + } + } + $img->save("$path/$name.$format", $format); + $img->free(); + + return true; + } + + /** + * Gets a list of photos with their descriptions and thumbnails. + * + * Returns an array of associative arrays with this keys: + *
    + *
  • file: Photo filename.
  • + *
  • desc: Photo Description.
  • + *
  • thumb: Photo thumbnail filename.
  • + *
+ * + * @return array Array of associative arrays with file, desc and + * thumb. + * + * @access public + */ + function getList() { + $root = $this->root; + $exts = $this->exts; + $format = $this->thumbsformat; + $return = array(); + + $d = dir($root); + while (($file = $d->read()) !== false) { + list($path, $name, $ext) = File_Util::splitFilename("$root/$file"); + if (is_readable("$root/$file") and in_array($ext, $exts)) { + $thumb = $this->getThumbName("$root/$file"); + $return[] = array( + 'file' => "$root/$file", + 'desc' => $name, + 'thumb' => is_readable($thumb) ? $thumb : null, + ); + } + } + $d->close(); + + return $return; + } + + /** + * Gets a photo thumbnail name. + * + * @param string $photo Source photo to create the thumbnail. + * + * @return string Thumbnail name. + * + * @access public + * @since rev 131 + */ + function getThumbName($photo) { + $root = $this->root; + $format = $this->thumbsformat; + $thumbsdir = $this->thumbsdir; + + list($path, $name, $ext) = File_Util::splitFilename($photo); + + return "$root/$thumbsdir/$name.$format"; + } + + /** + * Creates album thumbnails. + * + * @since rev 147 + * @access public + */ + function createThumbs() { + foreach ($this->getList() as $photo) { + if (is_null($photo['thumb'])) { + $photo['thumb'] = $this->makeThumb($photo['file']); + } + } + } + + /** + * Sets the album description. + * + * @param string $desc New album description. + * + * @returns bool True on success, false on failure. + * + * @since rev 147 + * @access public + */ + function setDescription($desc) { + $root = $this->root; + $out = fopen("$root/.album", 'w'); + $ret = fputs($out, $desc); + fclose($out); + return $ret ? true : false; + } + + /** + * Gets the album description. + * + * @returns string Album description. + * + * @since rev 149 + * @access public + */ + function getDescription() { + $root = $this->root; + return file_get_contents("$root/.album"); + } + +} + +// $Id$ +?> diff --git a/Util.php b/Util.php new file mode 100644 index 0000000..7fee82a --- /dev/null +++ b/Util.php @@ -0,0 +1,128 @@ + | +// +--------------------------------------------------------------------+ +// +// $Id$ +// + +/** + * General file utilities functions. + * + * This is a group of static functions for getting file info and other + * stuff. + * + * @package Hooks + * @author Leandro Lucarella + * @version $Rev$ + * @since rev 122 + * @access public + */ +class File_Util { + + /** + * Splits a filename into path, filename and extension. + * + * @param string $file Filename to split. + * + * @return array Array where the first element (index 0) is the + * path, the second is the name and the third is the + * extension. + * + * @access public + * @since rev 122 + */ + function splitFilename($file) + { + $path = preg_split('|/|', $file); + $file = array_pop($path); + $ext = ''; + if (strstr($file, '.')) { + preg_match('|([^/]+?)(\.([^\.]*))?$|', $file, $m); + $file = @$m[1] . ((@$m[2] == '.' ) ? '.' : ''); + $ext = @$m[3]; + } + $dir = count($path) ? join('/', $path) : ''; + return array($dir, $file, $ext); + } + + /** + * Tells if a file is readable looking in the include path. + * + * @param string $file Name of the file to look for. + * + * @return bool True if file is readable, false if not. + * + * @access public + * @since rev 122 + */ + function isReadableInclude($file) + { + list($dir, $page, $ext) = File_Util::splitFilename($file); + if (is_readable($file)) { + return true; + } + $include_path = array_unique(preg_split('/:/', ini_get('include_path'))); + foreach ($include_path as $path) { + if (is_readable("$path/$file")) { + return true; + } + } + return false; + } + + /** + * Gets the last modification date/time for a file. + * + * @param string $file Name of the file to get the last modification + * date/time. + * @param string $format Format (see strftime). + * + * @return string Formated string with the last modification + * date/time. + * + * @see strftime() + * @access public + * @since rev 142 + */ + function lastModified($file, $format = '%c') + { + return strftime($format, filemtime($file)); + } + +} + +// This is a workarround to live until PHP 4.3 is out and we can use the +// native get_file_contents() function. We don't care about +// $use_include_file option. +function file_get_contents($file, $use_include_file = false) +{ + if (@is_readable($file)) { + $var = join('', file($file)); + } else { + $var = ''; + } + return $var; +} + +?> diff --git a/bife_album.html b/bife_album.html new file mode 100644 index 0000000..2510de9 --- /dev/null +++ b/bife_album.html @@ -0,0 +1,12 @@ +

{DESC}

+
+ + + + + {ITEMS} + + + +
+
diff --git a/bife_album_emptyitem.html b/bife_album_emptyitem.html new file mode 100644 index 0000000..ca79251 --- /dev/null +++ b/bife_album_emptyitem.html @@ -0,0 +1 @@ +VACIO diff --git a/bife_album_item.html b/bife_album_item.html new file mode 100644 index 0000000..1e828f9 --- /dev/null +++ b/bife_album_item.html @@ -0,0 +1,3 @@ + + {DESC} + diff --git a/bife_page.html b/bife_page.html new file mode 100644 index 0000000..ea824f4 --- /dev/null +++ b/bife_page.html @@ -0,0 +1,9 @@ + + + {TITLE} + + +

{TITLE}

+ {CONTENTS} + + diff --git a/bife_title.html b/bife_title.html new file mode 100644 index 0000000..3590da3 --- /dev/null +++ b/bife_title.html @@ -0,0 +1 @@ +

{CONTENTS}

diff --git a/index.php b/index.php index ffb2810..439ab5f 100644 --- a/index.php +++ b/index.php @@ -1,45 +1,50 @@ setErrorHandling(PEAR_ERROR_PRINT); + +$output = ''; $stack = array(); function startElement($parser, $name, $attrs) { - global $depth, $stack; - $stack[] = $name; - echo str_repeat(TAB, @$depth[$parser]); - echo "<$name> "; - foreach ($attrs as $attr => $val) { - echo "$attr: '$val' "; + global $stack; + $class = "BIFE_$name"; + if (class_exists($class)) { + $obj =& new $class($attrs); + if (!is_a($obj, 'bife_base')) { + trigger_error("Class '$class' is not a BIFE_Base.", E_USER_WARNING); + } + $stack[] =& $obj; + } else { + trigger_error("Class not found '$class'.", E_USER_ERROR); } - echo "\n"; - @$depth[$parser]++; } function endElement($parser, $name) { - global $depth, $stack; + global $stack, $template, $output; + end($stack); + $current =& $stack[key($stack)]; array_pop($stack); - $depth[$parser]--; + end($stack); + $parent =& $stack[key($stack)]; + if ($parent) { + $parent->addContents($current->process($template)); + } else { + $output = $current->process($template); + } } function characterData($parser, $data) { - static $last = ''; - global $depth, $stack; - $current = join('/', $stack); - $data = trim($data); - if ($data) { - echo str_repeat(TAB, @$depth[$parser]); - if ($current !== $last) { - $last = $current; - echo "En $current: "; - } else { - echo " "; - } - echo "'$data'\n"; - } + global $stack; + end($stack); + $current =& $stack[key($stack)]; + $current->addContents($data); } $xml_parser = xml_parser_create(); @@ -58,4 +63,86 @@ while ($data = fread($fp, 4096)) { } xml_parser_free($xml_parser); +class BIFE_Base { + + function BIFE_Base() { + trigger_error('Can\'t instanciate abstract class BIFE_Base.', + E_USER_ERROR); + } + + function addContents($contents) { + trigger_error('Method not implemented '.get_class($this). + '::addContents().', E_USER_ERROR); + } + + function process(&$template) { + trigger_error('Method not implemented '.get_class($this). + '::addContents().', E_USER_ERROR); + } + +} + +class BIFE_Common extends BIFE_Base { + + var $attrs; + var $contents; + + function BIFE_Common($attrs) { + $this->attrs = $attrs; + $this->contents = ''; + } + + function addContents($contents) { + $this->contents .= trim($contents); + } + + function process(&$template) { + $template->loadTemplateFile(get_class($this).'.html'); + $template->setVariable($this->attrs); + $template->setVariable('CONTENTS', $this->contents); + return $template->get(); + } + +} + +class BIFE_Page extends BIFE_Common { + function BIFE_Page($attrs) { + $this->BIFE_Common($attrs); + } +} + +class BIFE_Title extends BIFE_Common { + function BIFE_Title($attrs) { + $this->BIFE_Common($attrs); + } +} + +class BIFE_Album extends BIFE_Base { + var $attrs; + function BIFE_Album($attrs) { + $defaults = array( + 'DIR' => '.', + 'RECURSIVE' => true, + 'THUMBSFORMAT' => 'jpeg', + 'THUMBSDIR' => '.thumbs', + 'EXTENSIONS' => 'png,jpg,jpeg,gif', + 'SELECTED' => '', + 'MAXROWS' => 0, + 'COLUMNS' => 4, + ); + $this->attrs = array_merge($defaults, $attrs); + } + function addContents($contents) { + trigger_error('BIFE_Album is not a container, you can\'t add contents.', + E_USER_ERROR); + } + function process(&$template) { + extract($this->attrs, EXTR_SKIP); + $album =& new Hook_Album($DIR, $RECURSIVE, $THUMBSFORMAT, $THUMBSDIR, $EXTENSIONS); + return $album->album($template, $SELECTED, $MAXROWS, $COLUMNS); + } +} + +echo $output; + ?> diff --git a/photo.html b/photo.html new file mode 100644 index 0000000..4ff6528 --- /dev/null +++ b/photo.html @@ -0,0 +1,2 @@ +{DESC} +
{DESC}
diff --git a/simple.xml b/simple.xml new file mode 100644 index 0000000..8a2fbf2 --- /dev/null +++ b/simple.xml @@ -0,0 +1,4 @@ + + Datos! + +