[ansel] Patch for date searching

Heath S. Hendrickson heath at outerspaceconsultants.com
Wed May 19 22:57:23 PDT 2004


Well, I managed to get a revised search page working that allows the 
user to do either a "Text Based" search (non date fields) or a "Date 
Based" search.

For the "Date Based" search, the user has the option of "Between" 
"Before" or "After" searches.

This necessitated a patch to only search.php (attached), but it is 
predicated on the patch to lib/Exif.php that I sent out earlier.  This 
patch includes the earlier patches to search.php, so if that one hasn't 
been applied it can be safely skipped in favor of this one.

Also attached is a CLI script that will convert all EXIF date fields to 
timestamp format in the datatree.

I'm not the best with the Horde Forms, so it's not the prettiest thing 
out there.  I would rather have had the date fields be all on one line, 
but I'm not sure how to do that with the stock Horde Forms.  Also, I'd 
have liked to have a separation between the two section of search fields 
to help delineate them, with perhaps the selector being on the left and 
the two sets of fields on the right.  Maybe with nice boxes around them 
to further help break them apart.

       Type              Text   Field Operator Value

                             Date   Operator  Month1 Day1 Year1
                                                     Month2 Day2 Year2


Anyway, the searches work for me on my install (I tested a date search 
with Between a date and today and an After search with the same starting 
date and they both returned the same number of images).

h

-------------- next part --------------
Index: search.php
===================================================================
RCS file: /usr/local/horde/cvs/ansel/search.php,v
retrieving revision 1.5
diff -u -r1.5 search.php
--- search.php	18 May 2004 15:25:28 -0000	1.5
+++ search.php	20 May 2004 05:46:02 -0000
@@ -31,11 +31,21 @@
         $fields = Ansel_ImageData::getFields();
 
         // Now add on any others that we may want.
-        $fields = array_merge($fields, array('description' => _("Description"),
-                                             'date-uploaded' => _("Date Uploaded"),
-                                             'filename' => _("Filename"),
-                                             'gallery' => _("Gallery Name")));
-        asort($fields);
+        $fields += array('description' => array( 'description' => _("Description"), 'type' => 'text'),
+                         'date-uploaded' => array( 'description' => _("Date Uploaded"), 'type' => 'date'),
+                         'filename' => array( 'description' => _("Filename"), 'type' => 'text'),
+                         'gallery' => array( 'description' => _("Gallery Name"), 'type' => 'text'));
+
+        // reformat the array so that the Form Renderer likes it
+        // amd grab only the non-date based fields
+        $searchFields = array();
+        foreach ($fields as $field => $data) {
+            if ($data['type'] != 'date') {
+                $searchFields += array( $field => $data['description'] );
+            }
+        }
+ 
+        asort($searchFields);
 
         $ops = array('=' => _("Is"),
                      '!=' => _("Is Not"),
@@ -44,14 +54,59 @@
                      'LIKE' => _("Contains"),
                      'NOT LIKE' => _("Does Not Contain"));
 
-        $this->addVariable(_("Field"), 'field', 'enum', false, false, null, array($fields));
-        $this->addVariable(_("Operator"), 'op', 'enum', false, false, null, array($ops));
-        $this->addVariable(_("Value"), 'value', 'text', false, false, null);
+        // add the radio buttons to tells us what type of search to perform
+        $this->addVariable(_("Search Type"), 'searchType', 'enum', false, false, null, 
+                           array(array('TEXT' => _("Text Fields"), 'DATE' => _("Date Fields"))));
+
+        // add the text search form items
+        $this->addVariable(_("Field"), 'textField', 'enum', false, false, null, array($searchFields));
+        $this->addVariable(_("Operator"), 'textOp', 'enum', false, false, null, array($ops));
+        $this->addVariable(_("Value"), 'textValue', 'text', false, false, null);
+
+        // reformat the array so that the Form Renderer likes it
+        // and grab only the date based fields.
+        $searchFields = array();
+        foreach ($fields as $field => $data) {
+            if ($data['type'] == 'date') {
+                $searchFields += array( $field => $data['description'] );
+            }
+        }
+ 
+        asort($searchFields);
+
+        $ops = array('BETWEEN' => _("Between"),
+                     '>' => _("After"),
+                     '<' => _("Before"));
+
+        $days =array();
+        for($day = 1; $day <= 31; $day++) {
+            $days += array($day => $day);
+        }
+        $months = array('01' => _("January"), '02' => _("February"), '03' => _("March"),
+                        '04' => _("April"), '05' => _("May"),
+                        '06' => _("June"), '07' => _("July"), '08' => _("August"),
+                        '09' => _("September"), '10' => _("October"),
+                        '11' => _("November"), '12' => _("December"));
+
+        $years = array();
+        for ($year = 1970; $year <= 2004; $year++) {
+            $years += array( $year => $year );
+        }
+
+        $this->addVariable(_("Field"), 'dateField', 'enum', false, false, null, array($searchFields));
+        $this->addVariable(_("Operator"), 'dateOp', 'enum', false, false, null, array($ops));
+        $this->addVariable(_("Month"), 'dateMonth1', 'enum', false, false, null,  array($months));
+        $this->addVariable(_("Day"), 'dateDay1', 'enum', false, false, null, array($days));
+        $this->addVariable(_("Year"), 'dateYear1', 'enum', false, false, null, array($years));
+        $this->addVariable(_("Month"), 'dateMonth2', 'enum', false, false, null, array($months));
+        $this->addVariable(_("Day"), 'dateDay2', 'enum', false, false, null, array($days));
+        $this->addVariable(_("Year"), 'dateYear2', 'enum', false, false, null, array($years));
     }
 
 }
 
 $actionID = Util::getFormData('actionID');
+$searchType = Util::getFormData('searchType');
 $vars = &Variables::getDefaultVariables();
 $title = _("Search for Images");
 require ANSEL_TEMPLATES . '/common-header.inc';
@@ -66,61 +121,136 @@
 // Now display any results, if a search was performed.
 switch ($actionID) {
 case 'search':
-    // Set up the search criteria to use.
-    $attr_name = Util::getFormData('field');
-    $attr_op = Util::getFormData('op');
-    $attr_value = Util::getFormData('value');
-
-    // Escape any SQL wildcards.
-    $attr_value = str_replace(array('%', '_'), array('\%', '\_'), $attr_value);
-
-    // For the CONTAINS and DOES NOT CONTAIN cases, we add the SQL
-    // regex wildcards to the front and back of the value.
-    if ($attr_op == 'LIKE' || $attr_op == 'NOT LIKE') {
-        $attr_value = '%' . $attr_value . '%';
-    } elseif ($attr_op == 'BEGIN') {
-        $attr_op = 'LIKE';
-        $attr_value = $attr_value . '%';
-    } elseif ($attr_op == 'END') {
-        $attr_op = 'LIKE';
-        $attr_value = '%' . $attr_value;
-    }
+    switch ($searchType) {
+    case 'TEXT':
+        // Set up the search criteria to use.
+        $attr_name = Util::getFormData('textField');
+        $attr_op = Util::getFormData('textOp');
+        $attr_value = Util::getFormData('textValue');
+
+        // Escape any SQL wildcards.
+        $attr_value = str_replace(array('%', '_'), array('\%', '\_'), $attr_value);
+
+        // For the CONTAINS and DOES NOT CONTAIN cases, we add the SQL
+        // regex wildcards to the front and back of the value.
+        if ($attr_op == 'LIKE' || $attr_op == 'NOT LIKE') {
+            $attr_value = '%' . $attr_value . '%';
+        } elseif ($attr_op == 'BEGIN') {
+            $attr_op = 'LIKE';
+            $attr_value = $attr_value . '%';
+        } elseif ($attr_op == 'END') {
+            $attr_op = 'LIKE';
+            $attr_value = '%' . $attr_value;
+        }
+    
+        $criteria['AND'] = array(array('field' => 'name',
+                                    'op' => '=',
+                                    'test' => $attr_name),
+                                array('field' => 'value',
+                                    'op' => $attr_op,
+                                    'test' => $attr_value));
+    
+        $imagelist = $ansel_shares->searchAllImages($criteria);
+    
+        // Now display the results.
+        Horde::addScriptFile('popup.js', 'horde');
+    
+        $i = 0;
+        $images = array();
+        foreach ($imagelist as $id => $name) {
+            $image = &$ansel_shares->getImage($name);
+            $galleryName = $image->get('gallery');
+            $gallery = $ansel_shares->getShare($galleryName);
+            if (is_a($gallery, 'PEAR_Error') || !$gallery->hasPermission(Auth::getAuth(), PERMS_READ)) {
+                continue;
+            }
+    
+            $img = Util::addParameter('image.php', array('gallery' => $image->get('gallery'),
+                                                        'image' => $image->getId(),
+                                                        'actionID' => 'imagethumb'));
+            $images[] = array('i' => ($i++ %2),
+                            'image' => Horde::link('', _("Thumbnail"), '', '', 'popup(\'' . Horde::applicationUrl($img) . '\',' . ($conf['thumbnail']['width'] + 10) . ', ' . ($conf['thumbnail']['height'] + 10) . '); return false;') . $image->get('filename') . '</a>',
+                            'gallery' => Horde::link(Horde::applicationUrl(Util::addParameter('view.php', array('gallery' => $galleryName, 'page' => '1')))) . $gallery->get('name') . '</a>',
+                            'description' => $image->get('description') ? htmlspecialchars($image->get('description')) : '&nbsp;');
+        }
 
-    $criteria['AND'] = array(array('field' => 'name',
-                                   'op' => '=',
-                                   'test' => $attr_name),
-                             array('field' => 'value',
-                                   'op' => $attr_op,
-                                   'test' => $attr_value));
-
-    $imagelist = $ansel_shares->searchAllImages($criteria);
-
-    // Now display the results.
-    Horde::addScriptFile('popup.js', 'horde');
-
-    $i = 0;
-    $images = array();
-    foreach ($imagelist as $id => $name) {
-        $image = &$ansel_shares->getImage($name);
-        $galleryName = $image->get('gallery');
-        $gallery = $ansel_shares->getShare($galleryName);
-        if (is_a($gallery, 'PEAR_Error') || !$gallery->hasPermission(Auth::getAuth(), PERMS_READ)) {
-            continue;
-        }
-
-        $img = Util::addParameter('image.php', array('gallery' => $image->get('gallery'),
-                                                     'image' => $image->getId(),
-                                                     'actionID' => 'imagethumb'));
-        $images[] = array('i' => ($i++ %2),
-                          'image' => Horde::link('', _("Thumbnail"), '', '', 'popup(\'' . Horde::applicationUrl($img) . '\',' . ($conf['thumbnail']['width'] + 10) . ', ' . ($conf['thumbnail']['height'] + 10) . '); return false;') . $image->get('filename') . '</a>',
-                          'gallery' => Horde::link(Horde::applicationUrl(Util::addParameter('view.php', array('gallery' => $galleryName, 'page' => '1')))) . $gallery->get('name') . '</a>',
-                          'description' => $image->get('description') ? htmlspecialchars($image->get('description')) : '&nbsp;');
+        $template = &new Horde_Template();
+        $template->set('images', $images);
+        $template->set('heading', count($images) == 1 ? _("Matched 1 image") : sprintf(_("Matched %s images"), count($images)));
+        echo $template->fetch(ANSEL_TEMPLATES . '/search/search.html');
+        break;
+
+    case 'DATE':
+        $attr_name = Util::getFormData('dateField');
+        $attr_op = Util::getFormData('dateOp');
+        $attr_day1 = Util::getFormData('dateDay1');
+        $attr_day2 = Util::getFormData('dateDay2');
+        $attr_month1 = Util::getFormData('dateMonth1');
+        $attr_month2 = Util::getFormData('dateMonth2');
+        $attr_year1 = Util::getFormData('dateYear1');
+        $attr_year2 = Util::getFormData('dateYear2');
+    
+        // set up the proper search criteria
+        $criteria = array();
+        if ($attr_op == "BETWEEN") {
+            $date1 = strtotime("$attr_month1/$attr_day1/$attr_year1 00:00:00");
+            $date2 = strtotime("$attr_month2/$attr_day2/$attr_year2 00:00:00");
+    
+            $criteria['AND'] = array(array('AND' => array(
+                                                        array('field' => 'name',
+                                                            'op' => '=',
+                                                            'test' => $attr_name),
+                                                        array('field' => 'value',
+                                                            'op' => '>',
+                                                            'test' => $date1))),
+                                    array('AND' => array(
+                                                        array('field' => 'name',
+                                                            'op' => '=',
+                                                            'test' => $attr_name),
+                                                        array('field' => 'value',
+                                                            'op' => '<',
+                                                            'test' => $date2))));
+        } else {
+            $date = strtotime("$attr_month1/$attr_day1/$attr_year1 00:00:00");
+            $criteria['AND'] = array(array('field' => 'name',
+                                        'op' => '=',
+                                        'test' => $attr_name),
+                                    array('field' => 'value',
+                                        'op' => $attr_op,
+                                        'test' => $date));
+        }
+    
+        $imagelist = $ansel_shares->searchAllImages($criteria);
+
+        // Now display the results.
+        Horde::addScriptFile('popup.js', 'horde');
+    
+        $i = 0;
+        $images = array();
+        foreach ($imagelist as $id => $name) {
+            $image = &$ansel_shares->getImage($name);
+            $galleryName = $image->get('gallery');
+            $gallery = $ansel_shares->getShare($galleryName);
+            if (is_a($gallery, 'PEAR_Error') || !$gallery->hasPermission(Auth::getAuth(), PERMS_READ)) {
+                continue;
+            }
+    
+            $img = Util::addParameter('image.php', array('gallery' => $image->get('gallery'),
+                                                        'image' => $image->getId(),
+                                                        'actionID' => 'imagethumb'));
+            $images[] = array('i' => ($i++ %2),
+                            'image' => Horde::link('', _("Thumbnail"), '', '', 'popup(\'' . Horde::applicationUrl($img) . '\',' . ($conf['thumbnail']['width'] + 10) . ', ' . ($conf['thumbnail']['height'] + 10) . '); return false;') . $image->get('filename') . '</a>',
+                            'gallery' => Horde::link(Horde::applicationUrl(Util::addParameter('view.php', array('gallery' => $galleryName, 'page' => '1')))) . $gallery->get('name') . '</a>',
+                            'description' => $image->get('description') ? htmlspecialchars($image->get('description')) : '&nbsp;');
+        }
+    
+        $template = &new Horde_Template();
+        $template->set('images', $images);
+        $template->set('heading', count($images) == 1 ? _("Matched 1 image") : sprintf(_("Matched %s images"), count($images)));
+        echo $template->fetch(ANSEL_TEMPLATES . '/search/search.html');
+        break;
     }
 
-    $template = &new Horde_Template();
-    $template->set('images', $images);
-    $template->set('heading', count($images) == 1 ? _("Matched 1 image") : sprintf(_("Matched %s images"), count($images)));
-    echo $template->fetch(ANSEL_TEMPLATES . '/search/search.html');
 }
 
 require $registry->getParam('templates', 'horde') . '/common-footer.inc';
-------------- next part --------------
#!/usr/local/bin/php
<?php
/**
 * $Horde: ansel/scripts/fix_paths_vfs_sql.php,v 1.6 2004/01/24 20:04:32 chuck Exp $
 *
 * This is a script to fix the value stored in the date-uploaded attribute
 */

/**
 ** Set this to true if you want DB inserts done.
 **/
$live = true;

@define('AUTH_HANDLER', true);
@define('ANSEL_BASE', dirname(__FILE__) . '/..');
@define('HORDE_BASE', ANSEL_BASE . '/..');

// Do CLI checks and environment setup first.
require_once HORDE_BASE . '/lib/core.php';
require_once 'Horde/CLI.php';

// Make sure no one runs this from the web.
if (!Horde_CLI::runningFromCLI()) {
    exit("Must be run from the command line\n");
}

// Load the CLI environment - make sure there's no time limit, init
// some variables, etc.

require_once ANSEL_BASE . '/lib/base.php';
require_once 'Horde/Share.php';
Horde_CLI::init();

Horde_CLI::init();
$cli = &Horde_CLI::singleton();
$registry = &Registry::singleton();
$registry->pushApp('ansel', false);
$shares = &Horde_Share::singleton($registry->getApp());

$crit['AND'] = array( array('field' => 'name', 'op' => '=', 'test' => 'filename'),
                      array('field' => 'value', 'op' => '!=', 'test' => ''));

$images = &$ansel_shares->searchAllImages($crit);

$fields = array( 'DateTime', 'DateTimeOriginal', 'DateTimeDigitized' );
$count = 0;
foreach ($images as $id => $name) {
   $image = &$ansel_shares->getImage($name);
   $count++;

   foreach ($fields as $key => $field) {

      $timeVal = $image->get($field);
      if (!empty($timeVal)) {
         if (strstr($timeVal, ":")){
            list($ymd, $hms) = split(" ", $timeVal, 2);
            list($year, $month, $day) = split(":",$ymd, 3);
            $time = "$month/$day/$year $hms";
            $timecode = strtotime($time);
         } else {
            $timecode = $timeVal;
         }
         echo "$count: $id($field) => $timeVal = " . $timecode . "\n";
         if ($live) {
              $image->set($field, $timecode, false);
         }
      }
   }

   if ($live) {
        $image->update();
   }
}

if ($live) {
    echo $count . " row(s) updated.\n";
} else {
    echo $count . " row(s) would have been updated.\n";
}


More information about the ansel mailing list