singapore: the smallest big galery
home » forum » Mods » search (csv only)

You are not logged in.

#1 2006-09-18 04:54:47

Egypt Urnash
Member

search (csv only)

My installation is 0.10.0, with some of my own mods and a recent security patch. As always, make a backup before applying a large-size modification like this!

io_csv.class.php, replace &getGallery:

Code:

  /**
   * Fetches gallery info for the specified gallery and immediate children.
   * @param string  gallery id
   * @param string  language code spec for this request (optional)
   * @param int     number of levels of child galleries to fetch (optional)
   * @param string    search string (optional)
   * @return sgGallery  the gallery object created
   */
  function &getGallery($galleryId, &$parent, $getChildGalleries = 1, $language = null, $search = null) 
  {
    $gal =& new sgGallery($galleryId, $parent);

    if($language == null) {
      $translator =& Translator::getInstance();
      $language = $translator->language;
    }

    //try to open language specific metadata
    $fp = @fopen($this->config->base_path.$this->config->pathto_galleries.$galleryId."/metadata.$language.csv","r");

    //if fail then try to open generic metadata
    if(!$fp) 
      $fp = @fopen($this->config->base_path.$this->config->pathto_galleries.$galleryId."/metadata.csv","r");
    if($fp) {

      while($temp[] = fgetcsv($fp,2048));
      fclose($fp);

      list(
        $gal->filename,
        $gal->thumbnail,
        $gal->owner,
        $gal->groups,
        $gal->permissions,
        $gal->categories,
        $gal->name,
        $gal->artist,
        $gal->email,
        $gal->copyright,
        $gal->desc,
        $gal->summary,
        $gal->date
      ) = $temp[1];

      //only fetch individual images if child galleries are required
      if($getChildGalleries || (isset($search) && $search !='xxxbadsearchxxx')) {
        if (isset($search))
            $searchstring = '/'.$search.'/i';
        for($i=$index=0;$i<count($temp)-3;$i++) {

        //filtering based on search string here is a little illegible,
        //but not creating and populating objects is a real speed gain.
            if (isset($search)) {
                if (!preg_match ($searchstring,$temp[$i+2][6].' '.$temp[$i+2][10].' '.$temp[$i+2][5])) {
                    continue;
                }
            }

          $gal->images[$index] =& new sgImage($temp[$i+2][0], $gal, $this->config);
          list(,
            $gal->images[$index]->thumbnail,
            $gal->images[$index]->owner,
            $gal->images[$index]->groups,
            $gal->images[$index]->permissions,
            $gal->images[$index]->categories,
            $gal->images[$index]->name,
            $gal->images[$index]->artist,
            $gal->images[$index]->email,
            $gal->images[$index]->copyright,
            $gal->images[$index]->desc,
            $gal->images[$index]->location,
            $gal->images[$index]->date,
            $gal->images[$index]->camera,
            $gal->images[$index]->lens,
            $gal->images[$index]->film,
            $gal->images[$index]->darkroom,
            $gal->images[$index]->digital
          ) = $temp[$i+2];

          //get image size and type
          list(
            $gal->images[$index]->width, 
            $gal->images[$index]->height, 
            $gal->images[$index]->type
          ) = @GetImageSize($gal->images[$index]->realPath());
            $index++;
        }
      //otherwise just fill in empty images
      } else if(count($temp) > 3 && !(isset($search))) {
        for($i=0;$i<count($temp)-3;$i++)
          $gal->images[$i] =& new sgImage($temp[$i+2][0], $gal);
      }

    } else 
      //no metadata found so use iifn method implemented in superclass
      return parent::getGallery($galleryId, $parent, $getChildGalleries, $language,$search);

    //discover child galleries
    $dir = Singapore::getListing($this->config->base_path.$this->config->pathto_galleries.$galleryId."/");
    if($getChildGalleries || (isset($search) && $search != 'xxxbadsearchxxx')) {
      //but only fetch their info if required too
      foreach($dir->dirs as $gallery) 
        $gal->galleries[] = $this->getGallery($galleryId."/".$gallery, $gal, $getChildGalleries-1, $language, $search);
    }else
      //otherwise just copy their names in so they can be counted
      $gal->galleries = $dir->dirs;

    return $gal;
  }

singapore.class.php, replace Singapore() and selectGallery():

Code:

  function Singapore($basePath = "")
  {
    //import class definitions
    //io handler class included once config is loaded
    require_once $basePath."includes/translator.class.php";
    require_once $basePath."includes/thumbnail.class.php";
    require_once $basePath."includes/gallery.class.php";
    require_once $basePath."includes/config.class.php";
    require_once $basePath."includes/image.class.php";
    require_once $basePath."includes/user.class.php";
    
    //start execution timer
    $this->scriptStartTime = microtime();
    
    //remove slashes
    if(get_magic_quotes_gpc())
      $_REQUEST = array_map(array("Singapore","arraystripslashes"), $_REQUEST);

    //desanitize request
    $_REQUEST = array_map("htmlentities", $_REQUEST);
    
    //load config from singapore root directory
    $this->config =& sgConfig::getInstance();
    $this->config->loadConfig($basePath."singapore.ini");
    $this->config->loadConfig($basePath."secret.ini.php");
    
    //if instantiated remotely...
    if(!empty($basePath)) {
      //...try to guess base path and relative url
      if(empty($this->config->base_path))
        $this->config->base_path = $basePath;
      if(empty($this->config->base_url))
        $this->config->base_url  = $basePath;
      //...load local config if present
      //may over-ride guessed values above
      $this->config->loadConfig("singapore.local.ini");
    }
    
    //set current gallery to root if not specified in url
    $galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : ".";

    //load config from gallery ini file (gallery.ini) if present
    $this->config->loadConfig($basePath.$this->config->pathto_galleries.$galleryId."/gallery.ini");
    
    //set current template from request vars or config
    $this->template = $this->config->default_template;
    if(isset($_REQUEST[$this->config->url_template])) {
        $templates = Singapore::getListing($this->config->base_path.$this->config->pathto_templates);
        foreach($templates->dirs as $single) {
            if($single == $_REQUEST[$this->config->url_template]) {
                $this->template = $single;
                break;
            }
        }
    }

    $this->config->pathto_current_template = $this->config->pathto_templates.$this->template.'/';

    //load config from template ini file (template.ini) if present
    $this->config->loadConfig($basePath.$this->config->pathto_current_template."template.ini");
        
    //set runtime values
    $this->config->pathto_logs = $this->config->pathto_data_dir."logs/";
    $this->config->pathto_cache = $this->config->pathto_data_dir."cache/";
    $this->config->pathto_admin_template = $this->config->pathto_templates.$this->config->admin_template_name."/";
    
    //set current language from request vars or config
    if(!empty($_REQUEST[$this->config->url_lang]))
      $this->language = $_REQUEST[$this->config->url_lang];
    else {
      $this->language = $this->config->default_language;
      if($this->config->detect_language)
        foreach($this->getBrowserLanguages() as $lang)
          if($lang=="en" || file_exists($basePath.$this->config->pathto_locale."singapore.".$lang.".pmo")) {
            $this->language = $lang;
            break;
          }
    }
    
    //read the language file
    $this->translator =& Translator::getInstance($this->language);
    $this->translator->readLanguageFile($this->config->base_path.$this->config->pathto_locale."singapore.".$this->language.".pmo");
    
    //clear the UMASK
    umask(0);
    
    //include IO handler class and create instance
    require_once $basePath."includes/io_".$this->config->io_handler.".class.php";
    $ioClassName = "sgIO_".$this->config->io_handler;
    $this->io = new $ioClassName($this->config);

    if (isset($_REQUEST[$this->config->url_search])) {
        // we don't cache searches
        $this->config->cache = false;
        $search = $this->config->searchstring = $_REQUEST[$this->config->url_search];
        if ($search == '' || $search == 'Search') $search = $this->config->searchstring = NULL;
    }

    //load gallery and image info
    $this->selectGallery($galleryId, $search);
    
    //set character set
    if(!empty($this->translator->languageStrings[0]["charset"]))
      $this->character_set = $this->translator->languageStrings[0]["charset"];
    else
      $this->character_set = $this->config->default_charset;
    
    //set action to perform
    if (isset($_REQUEST[$this->config->url_search])) $this->action = "search";
    elseif(empty($_REQUEST["action"])) $this->action = "view";
    else $this->action = $_REQUEST["action"];
  }
  
  /**
   * Load gallery and image info
   * @param string the id of the gallery to load (optional)
   */
  function selectGallery($galleryId = "", $search = null)
  {
    if(empty($galleryId)) $galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : ".";

    //try to validate gallery id
    if(strlen($galleryId)>1 && $galleryId{1} != '/') $galleryId = './'.$galleryId;
    
    //detect back-references to avoid file-system walking
    if(strpos($galleryId,"../")!==false) $galleryId = ".";
    
    //find all ancestors to current gallery
    $this->ancestors = array();
    $ancestorNames = explode("/", $galleryId);
    $numberOfAncestors = count($ancestorNames);
    
    //construct fully qualified gallery ids
    $ancestorIds[0] = ".";
    for($i=1; $i<$numberOfAncestors; $i++)
      $ancestorIds[$i] = $ancestorIds[$i-1]."/".$ancestorNames[$i];
    
    //fetch galleries passing previous gallery as parent pointer
    for($i=0; $i<$numberOfAncestors; $i++)
      $this->ancestors[$i] =& 
          $this->io->getGallery(
              $ancestorIds[$i], $this->ancestors[$i-1],
              //only fetch children of bottom level gallery
              ($i==$numberOfAncestors-1) ? 1 : 0,
              null, $search
          );

    //need to remove bogus parent of root gallery created by previous step
    unset($this->ancestors[-1]);
    
    //set reference to current gallery
    $this->gallery = &$this->ancestors[count($this->ancestors)-1];
    
    //check if gallery was successfully fetched
    if($this->gallery == null) {
      $this->gallery = new sgGallery($galleryId, $this->ancestors[0]);
      $this->gallery->name = $this->translator->_g("Gallery not found '%s'",htmlspecialchars($galleryId));
    }
    
    //sort galleries and images
    $GLOBALS["sgSortOrder"] = $this->config->gallery_sort_order;
    if($this->config->gallery_sort_order!="x") usort($this->gallery->galleries, array("Singapore","multiSort"));
    $GLOBALS["sgSortOrder"] = $this->config->image_sort_order;
    if($this->config->image_sort_order!="x") usort($this->gallery->images, array("Singapore","multiSort"));
    unset($GLOBALS["sgSortOrder"]);
    
    //if startat is set then cast to int otherwise startat 0
    $this->gallery->startat = isset($_REQUEST[$this->config->url_startat]) ? (int)$_REQUEST[$this->config->url_startat] : 0;
    $this->startat = $this->gallery->startat; //depreciated
    
    //select the image (if any)
    if(!empty($_REQUEST[$this->config->url_image]))
      $this->selectImage($_REQUEST[$this->config->url_image]);
    
    //load hit data
    if($this->config->track_views || $this->config->show_views)
      $this->io->getHits($this->gallery);
    
    //update and save hit data
    if($this->config->track_views) {
      if($this->isImagePage()) {
        $this->image->hits++;
        $this->image->lasthit = time();
      } elseif($this->gallery->startat == 0) {
        $this->gallery->hits++;
        $this->gallery->lasthit = time();
      }
      $this->io->putHits($this->gallery);
    }
  }

Add searchBox() to singapore.class.php:

Code:

/**
 * Generates the HTML code for the search box
 * @return string search box HTML code
 */
function searchBox()
{
    if ($this->config->use_mod_rewrite)
        $ret = "<form action='".$this->config->base_url.$this->config->url_search."/' method='get' id='search'><input type='text' name='q' value='Search' /></form>";
    else
        $ret = "<form action='".$_SERVER["PHP_SELF"]."' method='get' id='search'><input type='text' name='".$this->config->url_search."' value='Search' /></form>";
    return $ret;
}

In item.class.php, replace URL():

Code:

function URL($startat = null, $action = null)
{
  $encodeThis = $this->idEncoded();
  if ($this->isImage()) $encodeParent = $this->parent->idEncoded();

  $query = array();
  if($this->config->use_mod_rewrite) { //format url for use with mod_rewrite
    $ret  = $this->config->base_url;
      if (isset($this->config->searchstring) && !$this->isImage()) {
        $ret .= $this->config->url_search;
        if($startat) $ret .= ','.$startat;
        $ret .= '/?q='.$this->config->searchstring;
      }
    else {
        $ret .= $this->isImage() ? $encodeParent : $encodeThis;
        if($startat) $ret .= ','.$startat;
        $ret .= '/';
        if($this->isImage())   $ret .= $encodeThis;
      }
    
    if($action)  $query[] = $this->config->url_action."=".$action;
    if($this->translator->language != $this->config->default_language) $query[] = $this->config->url_lang.'='.$this->translator->language;
    if($GLOBALS["sg"]->template != $this->config->default_template) $query[] = $this->config->url_template.'='.$GLOBALS["sg"]->template;
    
    if(!empty($query))
      $ret .= '?'.implode(ini_get('arg_separator.output'), $query);
  
  } else { //format plain url
    
      if (isset($this->config->searchstring) && !$this->isImage())
        $query[] = $this->config->url_search."=".$this->config->searchstring;
      else
        $query[] = $this->config->url_gallery."=".($this->isImage() ? $encodeParent : $encodeThis);
    if($this->isImage()) $query[] = $this->config->url_image."=".$encodeThis;
    if($startat)         $query[] = $this->config->url_startat."=".$startat;
    if($action)          $query[] = $this->config->url_action."=".$action;
    if($this->translator->language != $this->config->default_language)
                         $query[] = $this->config->url_lang.'='.$this->translator->language;
    if(isset($GLOBALS["sg"]->template) && $GLOBALS["sg"]->template != $this->config->default_template)
                         $query[] = $this->config->url_template.'='.$GLOBALS["sg"]->template;
                         
    $ret = $this->config->index_file_url.implode(ini_get('arg_separator.output'), $query);
  }
  
  return $ret;
}

In your templates:
replace index.tpl.php:

Code:

<?php

/**
 * Default singapore template.
 * 
 * @author Tamlyn Rhodes <tam at zenology dot co dot uk>
 * @copyright (c)2003, 2004 Tamlyn Rhodes
 * @version 1.0
 */

//include header file
include $sg->config->base_path.$sg->config->pathto_current_template."header.tpl.php";

switch($sg->action) {
case "addcomment" :
  include $sg->config->base_path.$sg->config->pathto_current_template."addcomment.tpl.php";
case "search" :
     include $sg->config->base_path.$sg->config->pathto_current_template."search.tpl.php";
    break;
default :
  if ($sg->isImagePage()) {
    //this is an 'image' page so include the 'image' template file
    include $sg->config->base_path.$sg->config->pathto_current_template."image.tpl.php";
  } elseif($sg->isAlbumPage()) {
    //this is an 'album' page so include the 'album' template file
    include $sg->config->base_path.$sg->config->pathto_current_template."album.tpl.php";
  } else {
    //this is a 'gallery' page so include the 'gallery' template file
    include $sg->config->base_path.$sg->config->pathto_current_template."gallery.tpl.php";
  }
}
//include footer file
include $sg->config->base_path.$sg->config->pathto_current_template."footer.tpl.php";

?>

and create search.tpl.php:

Code:

<?php
function flattenGallery($gal) {
    if (sizeof($gal->images))
        foreach ($gal->images as $image)
            $images[] = $image;
    if (sizeof($gal->galleries))
        foreach ($gal->galleries as $daughter)
            if (!$daughter->faked)
                $images = array_merge((array)$images,(array)flattenGallery($daughter));
    return $images;
}

$sg->gallery->images = flattenGallery($sg->gallery);
$sg->gallery->desc = 'Search results for "'.$sg->config->searchstring.'"';

if (sizeof($sg->gallery->images) == 0) $sg->gallery->desc = 'Sorry, your search for "'.$sg->config->searchstring.'" returned no results.';

if ($sg->config->searchstring == '' || $sg->config->searchstring == 'xxxbadsearchxxx') $sg->gallery->desc = 'You didn\'t search for anything!';

include $sg->config->base_path.$sg->config->pathto_current_template."album.tpl.php";
?>

Next, go into singapore.ini and add this at the bottom:

Code:

url_search = "search"

Finally, you'll need to work some .htaccess magic if you're using that for pretty URLs:

Code:

# rewrite for searches
RewriteCond %{QUERY_STRING} q=(.+)
RewriteRule ^([^,]+)(,([0-9]+))?/$ /index.php?search=%1&startat=$3 [l]

Now, go into your templates, and create a search box wherever you like by inserting

Code:

<?php echo $sg->searchBox()?>

- then do some css to style it into your site's look.

(I use a completely custom template, so I can't tell you where to best put it in the templates that ship with Singapore. I added it to album.tpl.php and to gallery.tpl.php.)

Last edited by Egypt Urnash (2007-02-06 22:46:48)

Offline

 

#2 2006-09-18 04:57:20

Egypt Urnash
Member

Re: search (csv only)

* all the functionality of search.tpl really ought to be somewhere in Singapore
* and its strings ought to be translatable

but I will handle that next week, or let someone else do it.

Offline

 

#3 2007-01-29 16:28:10

eddiejanzer
Member

Re: search (csv only)

so I finally got around to making this work, after a long break. Now, with mod rewrite on I am lost as to how to add the rule on this. In my htacess file I use pretty much the rules as they are set up. Adding this rule, for search though I don't know how to incorporate. Thanks for all the help so far, hoping I can get this part accomplished. Rick

Offline

 

#4 2007-01-29 20:48:07

pavian
Moderator

Re: search (csv only)

What would the current URL of the search-box be and what would you like to use to replace it?

e.g

singapore/search/hello -> singapore/index.php?search=hello

or how?

Offline

 

#5 2007-01-29 20:58:16

eddiejanzer
Member

Re: search (csv only)

(http://localhost:8888/index.php?search=)
above is how it looks in my browser, (http://localhost:8888/search) is what I'd like.
Hope that is an answer?

Offline

 

#6 2007-01-29 21:05:16

pavian
Moderator

Re: search (csv only)

but uhm were is the search string?
What does it look like when you search for "hello"?

Offline

 

#7 2007-01-29 21:15:57

eddiejanzer
Member

Re: search (csv only)

http://localhost:8888/index.php?search=hello

this what you mean?, that's what shows in my browser when I search for hello

Offline

 

#8 2007-01-30 00:03:01

pavian
Moderator

Re: search (csv only)

Does this work?

Code:

 RewriteRule /search/(.*) /index.php?search=$1 [R,NE]

maybe play around with it a little or check here: http://httpd.apache.org/docs/2.0/mod/mo … ewriterule

Offline

 

#9 2007-01-30 01:36:59

eddiejanzer
Member

Re: search (csv only)

no, does not work. I will read up at the link you provided, I get this in the browser (http://localhost:8888/search/?q=french)
and below
(You are here: HOME > Gallery not found './search')
in the breadcrumb

Offline

 

#10 2007-01-30 02:25:14

Egypt Urnash
Member

Re: search (csv only)

Oooh, yeah, looks like I forgot about that part of it! I'll edit the original post.

This is cut out of my .htaccess:

Code:

# rewrite for searches
RewriteCond %{QUERY_STRING} q=(.+)
RewriteRule ^([^,]+)(,([0-9]+))?/$ /index.php?search=%1&startat=$3 [l]

(yes, it supports pagination on your searches. it was easier that way, and prettier. *grin*)

Offline

 

#11 2007-01-30 02:26:35

Egypt Urnash
Member

Re: search (csv only)

And someday I should properly clean all this up and submit Official Patches instead of Ugly Hacks. What can I say? My installation of Singapore is a complicated tapestry of personal tweaks and modifications that work well enough for me.

Offline

 

#12 2007-01-30 03:05:38

eddiejanzer
Member

Re: search (csv only)

it did not make any difference to my problem. This is rewrite I have for galleries in the htaccess file, pretty much unedited,

Code:

# example: /singapore/gallery/subgallery,20/
# becomes: /singapore/index.php?gallery=gallery/subgallery&startat=20
RewriteRule ^([^,]+)(,([0-9]+))?/$ index.php?gallery=$1&startat=$3&%{QUERY_STRING} [ne]

Mod rewrite works fine for me, by the way, except the search page.

Offline

 

#13 2007-01-30 05:00:15

Egypt Urnash
Member

Re: search (csv only)

Ah, yes, the other crucial piece of information, <i>where</i> to put it! I will attempt to excuse that lapse by saying I'm on the tail end of a cold. *grin*

The search stuff needs to go before all of the other Singapore rewrites. Like this:

Code:

Options +FollowSymlinks
RewriteEngine On

# rewrite for searches
RewriteCond %{QUERY_STRING} q=(.+)
RewriteRule ^([^,]+)(,([0-9]+))?/$ /singapore/index.php?search=%1&startat=$3 [l]

# rewrite galleries
# url must end in / and gallery names must not contain commas (,)
# example: /singapore/gallery/subgallery,20/
# becomes: /singapore/index.php?gallery=gallery/subgallery&startat=20
RewriteRule ^([^,]+)(,([0-9]+))?/$ /singapore/index.php?gallery=$1&startat=$3&%{QUERY_STRING} [ne]

# rewrite images
# do not rewrite requests to files and directories that really exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

# example: /singapore/gallery/subgallery/myphoto.jpeg
# becomes: /singapore/index.php?gallery=gallery/subgallery&image=myphoto.jpeg
RewriteRule ^((.*)/)?([^/]+\.(jpeg|jpg|jpe|png|gif|bmp|tif|tiff))$ /singapore/index.php?gallery=$2&image=$3&%{QUERY_STRING} [ne,nc]

# rewrite feed.xml to the rss template
# example: /singapore/gallery/feed.xml
# becomes: /singapore/index.php?gallery=gallery&template=rss
RewriteRule ^((.*)/)?feed.xml$ /singapore/index.php?gallery=$2&template=rss&%{QUERY_STRING} [ne]

(That's the .htaccess provided with Singapore, with the search stuff inserted where it belongs.)

TIP: Debugging rewrite rules is easier if you add the R flag to the rewrite rule - RewriteRule pattern substitution [R] - (if you have other flags on the rules, add ,R in the brackets: [ne] becomes [ne,r]) because then you can see what it's turning into.

Last edited by Egypt Urnash (2007-02-06 22:52:26)

Offline

 

#14 2007-01-30 05:27:46

eddiejanzer
Member

Re: search (csv only)

thanks for all this. That being said, I still can't get it to work. Did as above, and I get, in the browser:

Code:

http://localhost:8888/search/?q=french]

and this in the crumbline: You are here: HOME > Gallery not found './search'
I was shocked to discover that it worked in the first place. Without the mod rewrite of course. Here is what the browser looks like when it's working (without mod rewrite on)

Code:

http://localhost:8888/index.php?search=french

and the crumbline just says: You are here: HOME

Offline

 

#15 2007-01-30 16:00:29

Paul
Member

Re: search (csv only)

Did you mistype? You seem to have an extra ] in the URL, there.

Offline