[Rt-commit] [svn] r1859 - in rt/branches/PLATANO-EXPERIMENTAL-CSS: . bin etc etc/upgrade/3.3.11 html/Elements/CollectionAsTable html/Elements/RT__Ticket html/Search html/Search/Elements lib/RT lib/RT/Interface sbin

jesse at pallas.eruditorum.org jesse at pallas.eruditorum.org
Thu Nov 11 03:46:18 EST 2004


Author: jesse
Date: Thu Nov 11 03:46:17 2004
New Revision: 1859

Added:
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.Pg
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.mysql
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditQuery
Modified:
   rt/branches/PLATANO-EXPERIMENTAL-CSS/   (props changed)
   rt/branches/PLATANO-EXPERIMENTAL-CSS/Makefile.in
   rt/branches/PLATANO-EXPERIMENTAL-CSS/bin/standalone_httpd.in
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Oracle
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Pg
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.SQLite
   rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.mysql
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/CollectionAsTable/Row
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/RT__Ticket/ColumnMap
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Build.html
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Bulk.html
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditSearches
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickBasics
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickCriteria
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectAndOr
   rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectPersonType
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFieldValues.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFields.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Interface/Web.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue_Overlay.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues_Overlay.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFields.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Queue_Overlay.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Ticket_Overlay.pm
   rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/factory
   rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/rt-setup-database.in
Log:
 r9121 at tinbook:  jesse | 2004-11-11T04:07:32.925469Z
  r6227 at tinbook:  jesse | 2004-11-07T14:48:07.801297Z
   r6202 at tinbook (orig r1718):  autrijus | 2004-11-05T08:56:10.440277Z
   * Log::Dispatch wants ->warning, not ->warn.
   
   
   r6205 at tinbook (orig r1721):  autrijus | 2004-11-05T11:43:18.999313Z
     r10186 at not (orig r1718):  autrijus | 2004-11-05T08:56:10.440277Z
     * Log::Dispatch wants ->warning, not ->warn.
    
    r10196 at not:  autrijus | 2004-11-05T11:41:58.476189Z
    * Fixes to standalone_httpd: 'protocol' was not defined, and query_string
      may be undefined too.  (Supposedly fixed in HTTP::Server::Simple.)
    
    r10197 at not:  autrijus | 2004-11-05T11:42:20.621065Z
    * Remove outdated comment.
    
    r10198 at not:  autrijus | 2004-11-05T11:43:55.045510Z
    * Refactor getting-an-uploaded-file-into-cf into _UploadFile call
      in Interface::Web; this unbreaks uploading a file cf on ticket creation.
    * The "CustomField-x" keys in $Ticket->Create now take hash references
      that contain CFV fields, eg. LargeContent, ContentType, Value.
    
   
   
   r6208 at tinbook (orig r1723):  autrijus | 2004-11-07T14:16:15.830464Z
    r10242 at not:  autrijus | 2004-11-06T06:59:58.274625Z
    * Schema changes for Pg, SQLite, mysql and Oracle.
    
   
   r6209 at tinbook (orig r1724):  autrijus | 2004-11-07T14:17:03.232005Z
    r10242 at not:  autrijus | 2004-11-06T06:59:58.274625Z
    * Schema changes for Pg, SQLite, mysql and Oracle.
    
    r10243 at not:  autrijus | 2004-11-06T07:00:15.865682Z
    * schema updater for Pg and mysql; Oracle comes later and SQLite is nontrivial.
    
   
   r6212 at tinbook (orig r1725):  autrijus | 2004-11-07T14:22:06.654667Z
    r10251 at not:  autrijus | 2004-11-06T10:17:29.202899Z
    * fallouts from the OCFV schema change.
    
    
   
   r6217 at tinbook (orig r1726):  autrijus | 2004-11-07T14:26:14.894843Z
    r10252 at not:  autrijus | 2004-11-06T10:17:41.433720Z
    * "make dropdb" on SQLite now works.
    
    
   
   r6218 at tinbook (orig r1727):  autrijus | 2004-11-07T14:28:27.582072Z
    r10253 at not:  autrijus | 2004-11-06T10:17:49.792085Z
    * "make initdb" now an alias of "make initialize-database".
    
    
   
   r6219 at tinbook (orig r1728):  autrijus | 2004-11-07T14:29:51.869060Z
    r10256 at not:  autrijus | 2004-11-06T10:35:22.448152Z
    * Escape ColumnMap return values properly to prevent cross-site scripting
      attack.  All HTML snippets are now returned as scalar references.
    
   
   r6220 at tinbook (orig r1729):  autrijus | 2004-11-07T14:30:06.090844Z
    r10260 at not:  autrijus | 2004-11-07T08:54:20.330259Z
    * Query builder now acts on multiple clauses.
    * Close a potential XSS bug by escaping the clause naems.
    * Refactor the clause display component.
    
   
   r6221 at tinbook (orig r1730):  autrijus | 2004-11-07T14:30:22.730305Z
    r10261 at not:  autrijus | 2004-11-07T08:55:02.919657Z
    * loc and layout fixed.
    
   
   r6222 at tinbook (orig r1731):  autrijus | 2004-11-07T14:32:12.241052Z
    r10263 at not:  autrijus | 2004-11-07T14:15:05.153388Z
    * one loc fix.
    
   
   r6226 at tinbook (orig r1734):  autrijus | 2004-11-07T14:38:43.706169Z
   * In query builder, parse custom fields by name.
   * Generate all Link-type result cell callbacks from %LINKTYPEMAP.
   * Display custom field contents, separated by newlines.
   * For Image custom fields we also show a thumbnail.
   
   
  
 


Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/Makefile.in
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/Makefile.in	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/Makefile.in	Thu Nov 11 03:46:17 2004
@@ -360,6 +360,8 @@
 	$(PERL)	$(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --dba-password '' --force
 	$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --dba-password ''
 
+initdb :: initialize-database
+
 initialize-database: 
 	$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --prompt-for-dba-password
 

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/bin/standalone_httpd.in
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/bin/standalone_httpd.in	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/bin/standalone_httpd.in	Thu Nov 11 03:46:17 2004
@@ -108,10 +108,12 @@
 
             last if ( $method !~ /^(GET|POST|HEAD)$/ );
 
+            $query_string = '' if !defined $query_string;
+
             build_cgi_env( method       => $method,
                            query_string => $query_string,
                            path         => $file,
-                           method       => $method,
+                           protocol     => $proto,
                            port         => $port,
                            peername     => $peername,
                            peeraddr     => $peeraddr,

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Oracle
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Oracle	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Oracle	Thu Nov 11 03:46:17 2004
@@ -297,21 +297,29 @@
 );
 
 
-CREATE SEQUENCE TICKETCUSTOMFIELDVALUES_seq;
-CREATE TABLE TicketCustomFieldValues (
+CREATE SEQUENCE OBJECTCUSTOMFIELDVALUES_seq;
+CREATE TABLE ObjectCustomFieldValues (
 	id		NUMBER(11,0) 
-		CONSTRAINT TicketCustomFieldValues_Key PRIMARY KEY,
-	Ticket		NUMBER(11,0),
+		CONSTRAINT ObjectCustomFieldValues_Key PRIMARY KEY,
 	CustomField	NUMBER(11,0) NOT NULL,
+	ObjectType	VARCHAR2(25) NOT NULL,
+	ObjectId	NUMBER(11,0) DEFAULT 0 NOT NULL,
+	SortOrder	NUMBER(11,0) DEFAULT 0 NOT NULL,
+
 	Content		VARCHAR2(255),
+  	LargeContent 	CLOB,
+  	ContentType 	VARCHAR2(80),
+  	ContentEncoding VARCHAR2(80),
+
 	Creator		NUMBER(11,0) DEFAULT 0 NOT NULL,
 	Created		DATE,
 	LastUpdatedBy	NUMBER(11,0) DEFAULT 0 NOT NULL,
-	LastUpdated	DATE
+	LastUpdated	DATE,
+	Disabled	NUMBER(11,0) DEFAULT 0 NOT NULL
 );
 
-CREATE INDEX TicketCustomFieldValues1 ON TicketCustomFieldValues (CustomField,Ticket,Content); 
-CREATE INDEX TicketCustomFieldValues2 ON TicketCustomFieldValues (CustomField,Ticket); 
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (Content); 
+CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId); 
 
 CREATE SEQUENCE CUSTOMFIELDS_seq;
 CREATE TABLE CustomFields (

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Pg
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Pg	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.Pg	Thu Nov 11 03:46:17 2004
@@ -491,7 +491,8 @@
   CustomField int NOT NULL  ,
   ObjectType varchar(255) NULL  ,
   ObjectId int NOT NULL  ,
-  Current int DEFAULT 1,
+  SortOrder integer NOT NULL DEFAULT 0  ,
+
   Content varchar(255) NULL  ,
   LargeContent text NULL,
   ContentType varchar(80) NULL,
@@ -501,6 +502,7 @@
   Created TIMESTAMP NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated TIMESTAMP NULL  ,
+  Disabled integer NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
 
 );

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.SQLite
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.SQLite	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.SQLite	Thu Nov 11 03:46:17 2004
@@ -340,8 +340,8 @@
   CustomField int NOT NULL  ,
   ObjectType varchar(255) NOT NULL,	    # Final target of the Object
   ObjectId int NOT NULL  ,		    # New -- Replaces Ticket
+  SortOrder integer NOT NULL DEFAULT 0  ,
 
-  Current BOOL DEFAULT 1,		    # New -- whether the value was current
   Content varchar(255) NULL  ,
   LargeContent LONGTEXT NULL,		    # New -- to hold 255+ strings
   ContentType varchar(80) NULL,		    # New -- only text/* gets searched
@@ -351,6 +351,7 @@
   Created DATETIME NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,
   PRIMARY KEY (id)
 ) ;
 

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.mysql
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.mysql	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/schema.mysql	Thu Nov 11 03:46:17 2004
@@ -346,8 +346,8 @@
   CustomField int NOT NULL  ,
   ObjectType varchar(255) NOT NULL,	    # Final target of the Object
   ObjectId int NOT NULL  ,		    # New -- Replaces Ticket
+  SortOrder integer NOT NULL DEFAULT 0  ,   # New -- ordering for multiple values
 
-  Current BOOL DEFAULT 1,		    # New -- whether the value was current
   Content varchar(255) NULL  ,
   LargeContent LONGTEXT NULL,		    # New -- to hold 255+ strings
   ContentType varchar(80) NULL,		    # New -- only text/* gets searched
@@ -357,6 +357,7 @@
   Created DATETIME NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
   LastUpdated DATETIME NULL  ,
+  Disabled int2 NOT NULL DEFAULT 0 ,        # New -- whether the value was current
   PRIMARY KEY (id)
 ) TYPE=InnoDB;
 

Added: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.Pg
==============================================================================
--- (empty file)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.Pg	Thu Nov 11 03:46:17 2004
@@ -0,0 +1,9 @@
+START TRANSACTION;
+
+ALTER TABLE ObjectCustomFieldValues ADD COLUMN SortOrder INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE ObjectCustomFieldValues ADD COLUMN Disabled INTEGER NOT NULL DEFAULT 0 ,
+
+UPDATE ObjectCustomFieldValues SET Disabled = 1 WHERE Current = 0;
+ALTER TABLE ObjectCustomFieldValues DROP COLUMN Current;
+
+COMMIT;

Added: rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.mysql
==============================================================================
--- (empty file)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/etc/upgrade/3.3.11/schema.mysql	Thu Nov 11 03:46:17 2004
@@ -0,0 +1,9 @@
+START TRANSACTION;
+
+ALTER TABLE ObjectCustomFieldValues ADD COLUMN SortOrder INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE ObjectCustomFieldValues ADD COLUMN Disabled int2 NOT NULL DEFAULT 0;
+
+UPDATE ObjectCustomFieldValues SET Disabled = 1 WHERE Current = 0;
+ALTER TABLE ObjectCustomFieldValues DROP COLUMN Current;
+
+COMMIT;

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/CollectionAsTable/Row
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/CollectionAsTable/Row	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/CollectionAsTable/Row	Thu Nov 11 03:46:17 2004
@@ -54,9 +54,16 @@
             my $value = $m->comp('/Elements/RT__Ticket/ColumnMap', Name => $col, Attr => 'value');
 
             if ( $value && ref($value)) {
-                $m->out( &{ $value } ( $record, $i ) );
+		# All HTML snippets are returned by the callback function
+		# as scalar references.  Data fetched from the objects are
+		# plain scalars, and needs to be escaped properly.
+		$m->out( 
+		    map { ref($_) ? $$_ : $m->interp->apply_escapes( $_ => 'h' ) }
+		    &{ $value } ( $record, $i )
+	        );
             } else {
-                $m->out($value );
+		# Simple value; just escape it.
+                $m->out( $m->interp->apply_escapes( $value => 'h' ) );
             }
         }
         else {

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/RT__Ticket/ColumnMap
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/RT__Ticket/ColumnMap	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Elements/RT__Ticket/ColumnMap	Thu Nov 11 03:46:17 2004
@@ -29,7 +29,7 @@
 
 
 <%INIT>
-our ( $COLUMN_MAP, $CUSTOM_FIELD_MAP );
+our ( $COLUMN_MAP );
 
 sub ColumnMap {
     my $name = shift;
@@ -42,46 +42,52 @@
 
     # now, let's deal with harder things, like Custom Fields
 
-    elsif ( $name =~ /^(?:CF|CustomField).(.*)$/ ) {
+    elsif ( $name =~ /^(?:CF|CustomField)\.\{(.+)\}$/ ) {
         my $field = $1;
-        my $cf;
-        if ( $CUSTOM_FIELD_MAP->{$field} ) {
-            $cf = $CUSTOM_FIELD_MAP->{$field};
-        }
-        else {
-
-            $cf = RT::CustomField->new( $session{'CurrentUser'} );
-
-            if ( $field =~ /^(.+?)\.{(.+)}$/ ) {
-                $cf->LoadByNameAndQueue( Queue => $1, Name => $2 );
-            }
-            else {
-                $field = $1 if $field =~ /^{(.+)}$/;    # trim { }
-                $cf->LoadByNameAndQueue( Queue => "0", Name => $field );
-            }
-            $CUSTOM_FIELD_MAP->{$field} = $cf if ( $cf->id );
-        }
-
-        unless ( $cf->id ) {
-            return undef;
-        }
 
         if ( $attr eq 'attribute' ) {
             return (undef);
         }
         elsif ( $attr eq 'title' ) {
-            return ( $cf->Name );
+            return ( $field );
         }
         elsif ( $attr eq 'value' ) {
-            my $value = eval "sub {
-                    my \$values = \$_[0]->CustomFieldValues('" . $cf->id . "');
-                    return ( join( ', ', map { \$_->Content } \@{ \$values->ItemsArrayRef } ))
-                  }" || die $@;
-            return ($value);
+	    # Display custom field contents, separated by newlines.
+            # For Image custom fields we also show a thumbnail here.
+            return sub {
+                my $values = $_[0]->CustomFieldValues($field);
+                return map {
+                    (
+                        ($_->CustomFieldObj->Type eq 'Image')
+                            ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ ))
+                            : $_->Content
+                    ),
+                    \'<br>',
+                } @{ $values->ItemsArrayRef }
+	    };
         }
     }
 }
 
+sub LinkCallback {
+    my $method = shift;
+
+    my $mode            = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
+    my $mode_uri        = $mode.'URI';
+    my $mode_is_local   = $mode.'IsLocal';
+    my $local_type      = 'Local'.$mode;
+
+    return sub {
+        map {
+            \'<A HREF="',
+            $_->$mode_uri->Resolver->HREF,
+            \'">',
+            ( $_->$mode_is_local ? $_->$local_type : $_->$mode ),
+            \'</A><BR>',
+        } @{ $_[0]->$method->ItemsArrayRef }
+    }
+}
+
 $COLUMN_MAP = {
     QueueName => {
         attribute => 'Queue',
@@ -116,10 +122,10 @@
                 if (   $Ticket->HasUnresolvedDependencies( Type => 'approval' )
                     or $Ticket->HasUnresolvedDependencies( Type => 'code' ) )
                 {
-                    return "<em>" . loc('(pending approval)') . "</em>";
+                    return \'<em>', loc('(pending approval)'), \'</em>';
                 }
                 else {
-                    return "<em>" . loc('(pending other Collection)') . "</em>";
+                    return \'<em>', loc('(pending other Collection)'), \'</em>';
                 }
             }
             else {
@@ -205,7 +211,7 @@
         value     => sub { 
 	    my $date = $_[0]->DueObj;
 	    if ($date && $date->Unix > 0 && $date->Unix < time()) {
-		return '<span class="overdue">' . $date->AgeAsString . '</span>';
+		return \'<span class="overdue">' . $date->AgeAsString . \'</span>';
 	    } else {
 		return $date->AgeAsString;
 	    }
@@ -256,140 +262,10 @@
         value     => sub { return $_[0]->ResolvedObj->AsString }
     },
 
-    DependedOnBy => {
-        title => 'Depended On By',
-        value => sub {
-            my $links = $_[0]->DependedOnBy;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->BaseURI->Resolver->HREF . '">'
-                          . ( $_->BaseIsLocal ? $_->LocalBase : $_->Base )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    Members => {
-        value => sub {
-            my $links = $_[0]->Members;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->BaseURI->Resolver->HREF . '">'
-                          . ( $_->BaseIsLocal ? $_->LocalBase : $_->Base )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    Children => {
-        value => sub {
-            my $links = $_[0]->Members;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->BaseURI->Resolver->HREF . '">'
-                          . ( $_->BaseIsLocal ? $_->LocalBase : $_->Base )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    ReferredToBy => {
-        title => 'Referred to By',
-        value => sub {
-            my $links = $_[0]->ReferredToBy;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->BaseURI->Resolver->HREF . '">'
-                          . ( $_->BaseIsLocal ? $_->LocalBase : $_->Base )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-
-    DependsOn => {
-        title => 'Depends On',
-        value => sub {
-            my $links = $_[0]->DependsOn;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->TargetURI->Resolver->HREF . '">'
-                          . ( $_->TargetIsLocal ? $_->LocalTarget : $_->Target )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    MemberOf => {
-        title => 'Member Of',
-        value => sub {
-            my $links = $_[0]->MemberOf;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->TargetURI->Resolver->HREF . '">'
-                          . ( $_->TargetIsLocal ? $_->LocalTarget : $_->Target )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    Parents => {
-        value => sub {
-            my $links = $_[0]->MemberOf;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->TargetURI->Resolver->HREF . '">'
-                          . ( $_->TargetIsLocal ? $_->LocalTarget : $_->Target )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
-    RefersTo => {
-        title => 'Refers To',
-        value => sub {
-            my $links = $_[0]->RefersTo;
-            return (
-                join(
-                    "<br>",
-                    map {
-                            '<A HREF="'
-                          . $_->TargetURI->Resolver->HREF . '">'
-                          . ( $_->TargetIsLocal ? $_->LocalTarget : $_->Target )
-                          . '</A>'
-                      } @{ $links->ItemsArrayRef }
-                )
-            );
-          }
-    },
+    # Everything from LINKTYPEMAP
+    (map {
+        $_ => { value => LinkCallback( $_ ) }
+    } keys %RT::Ticket::LINKTYPEMAP),
 
     '_CLASS' => {
         value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Build.html
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Build.html	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Build.html	Thu Nov 11 03:46:17 2004
@@ -58,36 +58,28 @@
 <input type=hidden name=SearchId value="<%$SearchId%>">
 <input type=hidden name=Query value="<%$Query%>">
 <input type=hidden name=Format value="<%$Format%>">
-<table width=100%>
-<tr>
-<td valign=top class="boxcontainer">
+<table width=100% border="0" cellpadding="5">
+<tr valign="top">
+<td class="boxcontainer" rowspan="2" width="65%">
 <& Elements/PickCriteria, query => $Query, cfqueues => \%queues &>
 <& /Elements/Submit, Caption => loc('Add additional criteria'), Label => loc('Add'), Name => 'AddClause'&>
+</td>
 
+<td>
+<& Elements/EditQuery,
+    %ARGS,
+    actions => \@actions,
+    optionlist => $optionlist,
+    Description => $Description &>
 </td>
-<td valign=top class="boxcontainer">
-<& /Elements/TitleBoxStart, title => loc("Query") . ": " .$Description &>
-<& Elements/NewListActions, actions => \@actions &>
-<select size="10" name="clauses" style="width: 100%">
-<%$optionlist|n%>
-</select>
-</td></tr><tr><td bgcolor="#dddddd" colspan="2">
-<center>
-<input type=submit name="Up" value="^">
-<input type=submit name="Down" value="v">
-<input type=submit name="Left" value="<">
-<input type=submit name="Right" value=">">
-<input type=submit name="DeleteClause" value="Delete">
-<br />
-<input type=submit name="Clear" value="Clear">
-<input type=submit name="Toggle" value="And/Or">
-%#<input type=submit name="EditQuery" value="Advanced">
-</center>
-<& /Elements/TitleBoxEnd &>
-<br>
+</tr>
+
+<tr valign="top">
+<td>
 <& Elements/EditSearches, CurrentSearch => $search_hash, Dirty => $dirty, SearchId => $SearchId &>
 </td>
 </tr>
+
 <tr>
 <td colspan=2 class="boxcontainer">
 
@@ -97,7 +89,7 @@
 </tr>
 <tr>
 <td colspan=2 class="boxcontainer">
-<& /Elements/Submit, Caption => "Do the Search", Label => loc('Search'), Name => 'DoSearch'&>
+<& /Elements/Submit, Caption => loc("Do the Search"), Label => loc('Search'), Name => 'DoSearch'&>
 </td>
 </tr>
 </table>
@@ -242,10 +234,9 @@
 %queues = ();
 
 # Build the optionlist from the tree, so we can do additions and movements based on it
-$optionlist = build_array( \$Query, $ARGS{clauses}, $tree, \@options, \%queues );
+$optionlist = build_array( \$Query, \@clauses, $tree, \@options, \%queues );
 
-my $currentkey;
-$currentkey = $options[$ARGS{clauses}] if defined $ARGS{clauses};
+my @current_values = @options[@clauses];
 
 # {{{ Try to find if we're adding a clause
 foreach my $arg ( keys %ARGS ) {
@@ -285,16 +276,16 @@
         };
 	    
 	my $newnode = Tree::Simple->new($clause);
-	if ($currentkey) {
-	    my $newindex = $currentkey->getIndex() + 1;
-	    if (!$currentkey->getParent->getParent()->isRoot()) {
-	    }
-	    $currentkey->insertSibling($newindex, $newnode);
-	    $currentkey = $newnode;
+	if (@current_values) {
+            foreach my $value (@current_values) {
+                my $newindex = $value->getIndex() + 1;
+                $value->insertSibling($newindex, $newnode);
+                $value = $newnode;
+            }
 	}
 	else {
 	    $tree->getChild(0)->addChild($newnode);
-	    $currentkey = $newnode;
+	    @current_values = $newnode;
 	}
 	$newnode->getParent()->setNodeValue($ARGS{'AndOr'});
     }
@@ -303,108 +294,118 @@
 
 # {{{ Move things around
 if ( $ARGS{"Up"} ) {
-    if ($currentkey) {
-	my $index = $currentkey->getIndex();
-	if ( $currentkey->getIndex() > 0 ) {
-	    my $parent = $currentkey->getParent();
-	    $parent->removeChild($index);
-	    $parent->insertChild($index - 1, $currentkey);
-	    $currentkey = $parent->getChild($index - 1);
-	}
-        else {
-            push( @actions, [ "error: can't move up", -1 ] );
+    if (@current_values) {
+        foreach my $value (@current_values) {
+            my $index = $value->getIndex();
+            if ( $value->getIndex() > 0 ) {
+                my $parent = $value->getParent();
+                $parent->removeChild($index);
+                $parent->insertChild($index - 1, $value);
+                $value = $parent->getChild($index - 1);
+            }
+            else {
+                push( @actions, [ loc("error: can't move up"), -1 ] );
+            }
         }
     }
     else {
-        push( @actions, [ "error: nothing to move", -1 ] );
+        push( @actions, [ loc("error: nothing to move"), -1 ] );
     }
 }
 elsif ( $ARGS{"Down"} ) {
-    if ($currentkey) {
-	my $index = $currentkey->getIndex();
-	my $parent = $currentkey->getParent();
-	if ( $currentkey->getIndex() < ($parent->getChildCount - 1) ) {
-	    $parent->removeChild($index);
-	    $parent->insertChild($index + 1, $currentkey);
-	    $currentkey = $parent->getChild($index + 1);
-	}
-        else {
-            push( @actions, [ "error: can't move down", -1 ] );
+    if (@current_values) {
+        foreach my $value (@current_values) {
+            my $index = $value->getIndex();
+            my $parent = $value->getParent();
+            if ( $value->getIndex() < ($parent->getChildCount - 1) ) {
+                $parent->removeChild($index);
+                $parent->insertChild($index + 1, $value);
+                $value = $parent->getChild($index + 1);
+            }
+            else {
+                push( @actions, [ loc("error: can't move down"), -1 ] );
+            }
         }
     }
     else {
-        push( @actions, [ "error: nothing to move", -1 ] );
+        push( @actions, [ loc("error: nothing to move"), -1 ] );
     }
 }
 elsif ( $ARGS{"Left"} ) {
-    if ($currentkey) {
-	my $parent = $currentkey->getParent();
-	my $grandparent = $parent->getParent();
-	if (!$grandparent->isRoot) {
-	    my $index = $parent->getIndex();
-	    $parent->removeChild($currentkey);
-	    $grandparent->insertChild($index, $currentkey);
-	    if ($parent->isLeaf()) {
-		$grandparent->removeChild($parent);
-	    }
-        }
-        else {
-            push( @actions, [ "error: can't move left", -1 ] );
+    if (@current_values) {
+        foreach my $value (@current_values) {
+            my $parent = $value->getParent();
+            my $grandparent = $parent->getParent();
+            if (!$grandparent->isRoot) {
+                my $index = $parent->getIndex();
+                $parent->removeChild($value);
+                $grandparent->insertChild($index, $value);
+                if ($parent->isLeaf()) {
+                    $grandparent->removeChild($parent);
+                }
+            }
+            else {
+                push( @actions, [ loc("error: can't move left"), -1 ] );
+            }
         }
     }
     else {
-        push( @actions, [ "error: nothing to move", -1 ] );
+        push( @actions, [ loc("error: nothing to move"), -1 ] );
     }
 }
 elsif ( $ARGS{"Right"} ) {
-    if ($currentkey) {
-	my $parent = $currentkey->getParent();
-	my $index = $currentkey->getIndex();
-	my $newparent;
-	if ($index > 0 ) {
-	    my $sibling = $parent->getChild($index - 1);
-	    if (ref($sibling->getNodeValue)) {
-		$parent->removeChild($currentkey);
-		my $newtree = Tree::Simple->new('AND', $parent);
-		$newtree->addChild($currentkey);
-	    } else {
-		$parent->removeChild($index);
-		$sibling->addChild($currentkey);
-	    }
-	}
-	else {
-	    $parent->removeChild($currentkey);
-	    $newparent = Tree::Simple->new('AND', $parent);
-	    $newparent->addChild($currentkey);
-	}
+    if (@current_values) {
+        foreach my $value (@current_values) {
+            my $parent = $value->getParent();
+            my $index = $value->getIndex();
+            my $newparent;
+            if ($index > 0 ) {
+                my $sibling = $parent->getChild($index - 1);
+                if (ref($sibling->getNodeValue)) {
+                    $parent->removeChild($value);
+                    my $newtree = Tree::Simple->new('AND', $parent);
+                    $newtree->addChild($value);
+                } else {
+                    $parent->removeChild($index);
+                    $sibling->addChild($value);
+                }
+            }
+            else {
+                $parent->removeChild($value);
+                $newparent = Tree::Simple->new('AND', $parent);
+                $newparent->addChild($value);
+            }
+        }
     } else {
-        push( @actions, [ "error: nothing to move", -1 ] );
+        push( @actions, [ loc("error: nothing to move"), -1 ] );
     }
 }
 elsif ( $ARGS{"DeleteClause"} ) {
-    if ($currentkey) {
-	$currentkey->getParent()->removeChild($currentkey);
+    if (@current_values) {
+	$_->getParent()->removeChild($_) for @current_values;
     }
     else {
-        push( @actions, [ "error: nothing to delete", -1 ] );
+        push( @actions, [ loc("error: nothing to delete"), -1 ] );
     }
 }
 elsif ( $ARGS{"Toggle"} ) {
     my $ea;
-    if ($currentkey) {
-	my $value = $currentkey->getNodeValue();
-	my $parent = $currentkey->getParent();
-	my $parentvalue = $parent->getNodeValue();
+    if (@current_values) {
+        foreach my $value (@current_values) {
+            my $value = $value->getNodeValue();
+            my $parent = $value->getParent();
+            my $parentvalue = $parent->getNodeValue();
 
-	if ( $parentvalue eq 'AND') {
-            $parent->setNodeValue('OR');
-	}
-        else {
-	    $parent->setNodeValue('AND');
-	}
+            if ( $parentvalue eq 'AND') {
+                $parent->setNodeValue('OR');
+            }
+            else {
+                $parent->setNodeValue('AND');
+            }
+        }
     }
     else {
-        push( @actions, [ "error: nothing to toggle", -1 ] );
+        push( @actions, [ loc("error: nothing to toggle"), -1 ] );
     }
 }
 elsif ( $ARGS{"Clear"} ) {
@@ -416,11 +417,11 @@
 $Query   = "";
 @options = ();
 %queues  = ();
-$optionlist = build_array( \$Query, $currentkey, $tree, \@options, \%queues );
+$optionlist = build_array( \$Query, \@current_values, $tree, \@options, \%queues );
 
 sub build_array {
     my $Query     = shift;
-    my $currentkey = shift;
+    my $values_ref = shift;
     my $tree = shift;
     my ($keys, $queues)    = @_;
     my $i = 0;
@@ -449,7 +450,7 @@
 	}
 
 	my $selected;
-	if ($_tree == $currentkey) {
+	if (grep { $_ == $_tree } @$values_ref ) {
 	    $selected = "SELECTED";
 	}
 	else {
@@ -464,7 +465,7 @@
 	}
 
 	$optionlist .= "<option value=$i $selected>" .
-	  ("&nbsp;" x 5 x ($_tree->getDepth() - 1)) . "$str</option>\n";
+	  ("&nbsp;" x 5 x ($_tree->getDepth() - 1)) . $m->interp->apply_escapes($str, 'h') . "</option>\n";
 	my $parent = $_tree->getParent();
 	if (!($parent->isRoot || $parent->getParent()->isRoot) &&
 	    !ref($parent->getNodeValue())) {
@@ -561,7 +562,7 @@
             # Error
             # FIXME: I will only print out the highest $want value
             my $token = $tokens[ ( ( log $want ) / ( log 2 ) ) ];
-            push @actions, [ "current: $current, want $want, Error near ->$val<- expecting a " . $token . " in '$string'\n", -1 ];
+            push @actions, [ loc("current: $current, want $want, Error near ->$val<- expecting a " . $token . " in '$string'\n"), -1 ];
         }
 
         # State Machine:
@@ -621,12 +622,12 @@
                 $val = "'$val'";
             }
 
-            push @actions, [ "Unknown field: $key", -1 ] unless $class;
+            push @actions, [ loc("Unknown field: $key"), -1 ] unless $class;
 
             $want = PAREN | AGGREG;
         }
         else {
-            push @actions, [ "I'm lost", -1 ];
+            push @actions, [ loc("I'm lost"), -1 ];
         }
 
         if ( $current & VALUE ) {
@@ -649,14 +650,14 @@
         $last = $current;
     }    # while
 
-    push @actions, [ "Incomplete query", -1 ]
+    push @actions, [ loc("Incomplete query"), -1 ]
       unless ( ( $want | PAREN ) || ( $want | KEYWORD ) );
 
-    push @actions, [ "Incomplete Query", -1 ]
+    push @actions, [ loc("Incomplete Query"), -1 ]
       unless ( $last && ( $last | PAREN ) || ( $last || VALUE ) );
 
     # This will never happen, because the parser will complain
-    push @actions, [ "Mismatched parentheses", -1 ]
+    push @actions, [ loc("Mismatched parentheses"), -1 ]
       unless $depth == 1;
 }
 
@@ -803,4 +804,5 @@
 $OrderBy => undef
 $RowsPerPage => undef
 $HideResults => 0
+ at clauses => ()
 </%ARGS>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Bulk.html
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Bulk.html	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Bulk.html	Thu Nov 11 03:46:17 2004
@@ -76,7 +76,6 @@
       </%PERL>
 <TR bgcolor="<%$bgcolor%>">
 <TD><input type=checkbox name="UpdateTicket<%$Ticket->Id%>" CHECKED></TD>
-%# The ticket view is controlled by config.pm, WebOptions
 %foreach my $col (@cols) {
 <TD>
 % if ($col eq 'id') {

Added: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditQuery
==============================================================================
--- (empty file)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditQuery	Thu Nov 11 03:46:17 2004
@@ -0,0 +1,65 @@
+%# {{{ BEGIN BPS TAGGED BLOCK
+%# 
+%# COPYRIGHT:
+%#  
+%# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC 
+%#                                          <jesse at bestpractical.com>
+%# 
+%# (Except where explicitly superseded by other copyright notices)
+%# 
+%# 
+%# LICENSE:
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%# 
+%# 
+%# CONTRIBUTION SUBMISSION POLICY:
+%# 
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%# 
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%# 
+%# }}} END BPS TAGGED BLOCK
+<& NewListActions, actions => $actions &>
+<& /Elements/TitleBoxStart, title => join(': ', grep defined, loc("Query"), $Description) &>
+<select size="10" name="clauses" style="width: 100%" multiple>
+% $m->out($optionlist);
+</select>
+<p align="center">
+<input type=submit name="Up" value="^">
+<input type=submit name="Down" value="v">
+<input type=submit name="Left" value="<">
+<input type=submit name="Right" value=">">
+<input type=submit name="Toggle" value="<&|/l&>And/Or</&>">
+<input type=submit name="DeleteClause" value="<&|/l&>Delete</&>">
+%#<input type=submit name="EditQuery" value="Advanced">
+</p>
+<& /Elements/TitleBoxEnd &>
+<%ARGS>
+$Description
+$optionlist
+$actions
+</%ARGS>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditSearches
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditSearches	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/EditSearches	Thu Nov 11 03:46:17 2004
@@ -55,13 +55,14 @@
 % }
 <&|/l&>Description</&>:<br>
 <font size="-1"><input size="25" name="Description" value="<%$CurrentSearch->{'Description'}%>"></font>
-<br>
+<nobr>
 % if ($SearchId ne 'new') {
 % if ($Dirty) {
 <input type="submit" name="Revert" value="<%loc('Revert')%>">
 % }
 <input type="submit" name="Delete" value="<%loc('Delete')%>">
 <input type="submit" name="CopySearch" value="<%loc('Copy')%>">
+</nobr>
 
 % }
 

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickBasics
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickBasics	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickBasics	Thu Nov 11 03:46:17 2004
@@ -125,8 +125,8 @@
 <& SelectPersonType, Name => 'WatcherGroupField', Default => 'RequestorGroup', Suffix => 'Group' &>
 </td><td>
 <& /Elements/SelectBoolean, Name => "WatcherGroupOp", 
-					  True=> 'belongs to', 
-					  False=> 'does not belong to', 
+					  True=> loc('belongs to'), 
+					  False=> loc('does not belong to'), 
 					  TrueVal=> '=', 
 					  FalseVal => '!='
 &>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickCriteria
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickCriteria	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/PickCriteria	Thu Nov 11 03:46:17 2004
@@ -49,7 +49,7 @@
     <td>
       <table cellspacing=0 border=0>
         <tr><td class=label>
-        Aggregator:
+        <&|/l&>Aggregator</&>:
         </td>
         <td><& SelectAndOr, Name => "AndOr" &>
         </td></tr>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectAndOr
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectAndOr	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectAndOr	Thu Nov 11 03:46:17 2004
@@ -43,9 +43,9 @@
 %# those contributions and any derivatives thereof.
 %# 
 %# }}} END BPS TAGGED BLOCK
-<input type=radio NAME="<%$Name%>" CHECKED VALUE="AND">AND</input>
-<input type=radio NAME="<%$Name%>" VALUE="OR">OR</input>
+<input type=radio NAME="<%$Name%>" CHECKED VALUE="AND"><&|/l&>AND</&></input>
+<input type=radio NAME="<%$Name%>" VALUE="OR"><&|/l&>OR</&></input>
 
 <%ARGS>
 $Name => "Operator"
-</%ARGS>
\ No newline at end of file
+</%ARGS>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectPersonType
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectPersonType	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/html/Search/Elements/SelectPersonType	Thu Nov 11 03:46:17 2004
@@ -53,7 +53,7 @@
 %   next;
 %  }
 %  foreach my $subtype (@subtypes) {
-<OPTION VALUE="<%"$option.$subtype"%>" <%$option eq $Default && $subtype eq 'EmailAddress' && "SELECTED"%> ><%loc("[_1] [_2]",$option, $subtype)%></OPTION>
+<OPTION VALUE="<%"$option.$subtype"%>" <%$option eq $Default && $subtype eq 'EmailAddress' && "SELECTED"%> ><% loc($option) %> <% loc($subtype) %></OPTION>
 %  }
 % }
 </SELECT>

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFieldValues.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFieldValues.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFieldValues.pm	Thu Nov 11 03:46:17 2004
@@ -83,10 +83,15 @@
 
 
 
-  # By default, order by name
-  $self->OrderBy( ALIAS => 'main',
-                  FIELD => 'SortOrder',
-                  ORDER => 'ASC');
+  # By default, order by SortOrder
+  $self->OrderByCols(
+	 { ALIAS => 'main',
+	   FIELD => 'SortOrder',
+	   ORDER => 'ASC' },
+	 { ALIAS => 'main',
+	   FIELD => 'id',
+	   ORDER => 'ASC' },
+     );
 
     return ( $self->SUPER::_Init(@_) );
 }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFields.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFields.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/CustomFields.pm	Thu Nov 11 03:46:17 2004
@@ -83,10 +83,15 @@
 
 
 
-  # By default, order by name
-  $self->OrderBy( ALIAS => 'main',
-                  FIELD => 'SortOrder',
-                  ORDER => 'ASC');
+  # By default, order by SortOrder
+  $self->OrderByCols(
+	 { ALIAS => 'main',
+	   FIELD => 'SortOrder',
+	   ORDER => 'ASC' },
+	 { ALIAS => 'main',
+	   FIELD => 'id',
+	   ORDER => 'ASC' },
+     );
 
     return ( $self->SUPER::_Init(@_) );
 }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Interface/Web.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Interface/Web.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Interface/Web.pm	Thu Nov 11 03:46:17 2004
@@ -326,7 +326,12 @@
                 $ARGS{$arg} = [split('\n', $ARGS{$arg})];
             }
 
-            $create_args{"CustomField-".$cfid} = $ARGS{"$arg"};
+            if ( $arg =~ /-Upload$/ ) {
+                $create_args{"CustomField-".$cfid} = _UploadedFile($arg);
+            }
+            else {
+                $create_args{"CustomField-".$cfid} = $ARGS{"$arg"};
+            }
         }
     }
 
@@ -825,19 +830,6 @@
 
 # }}}
 
-# {{{ sub Config 
-# TODO: This might eventually read the cookies, user configuration
-# information from the DB, queue configuration information from the
-# DB, etc.
-
-sub Config {
-    my $args = shift;
-    my $key  = shift;
-    return $args->{$key} || $RT::WebOptions{$key};
-}
-
-# }}}
-
 # {{{ sub ProcessACLChanges
 
 sub ProcessACLChanges {
@@ -1149,16 +1141,11 @@
 			}
 		    }
 		    elsif ( $arg =~ /-Upload$/ ) {
-			my $cgi_object = $m->cgi_object;
-			my $fh = $cgi_object->upload($arg) or next;
-			my $upload_info = $cgi_object->uploadInfo($fh);
-			my $filename = "$fh";
-			$filename =~ s#^.*[\\/]##;
+                        my $value_hash = _UploadedFile($arg) or next;
+
 			my ( $val, $msg ) = $Object->AddCustomFieldValue(
-			    Field => $cf,
-			    Value => $filename,
-			    LargeContent => do { local $/; scalar <$fh> },
-			    ContentType => $upload_info->{'Content-Type'},
+                            %$value_hash,
+                            Field => $cf,
 			);
 			push ( @results, $msg );
 		    }
@@ -1468,6 +1455,35 @@
     return (@results);
 }
 
+# {{{ sub _UploadedFile
+
+=head2 _UploadedFile ( $arg );
+
+Takes a CGI parameter name; if a file is uploaded under that name,
+return a hash reference suitable for AddCustomFieldValue's use:
+C<( Value => $filename, LargeContent => $content, ContentType => $type )>.
+
+Returns C<undef> if no files were uploaded in the C<$arg> field.
+
+=cut
+
+sub _UploadedFile {
+    my $arg = shift;
+    my $cgi_object = $m->cgi_object;
+    my $fh = $cgi_object->upload($arg) or return undef;
+    my $upload_info = $cgi_object->uploadInfo($fh);
+
+    my $filename = "$fh";
+    $filename =~ s#^.*[\\/]##;
+    binmode($fh);
+
+    return {
+        Value => $filename,
+        LargeContent => do { local $/; scalar <$fh> },
+        ContentType => $upload_info->{'Content-Type'},
+    };
+}
+
 eval "require RT::Interface::Web_Vendor";
 die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web_Vendor.pm});
 eval "require RT::Interface::Web_Local";

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue.pm	Thu Nov 11 03:46:17 2004
@@ -91,11 +91,12 @@
   int(11) 'CustomField'.
   varchar(255) 'ObjectType'.
   int(11) 'ObjectId'.
-  tinyint(1) 'Current' defaults to '1'.
+  int(11) 'SortOrder'.
   varchar(255) 'Content'.
   longtext 'LargeContent'.
   varchar(80) 'ContentType'.
   varchar(80) 'ContentEncoding'.
+  smallint(6) 'Disabled'.
 
 =cut
 
@@ -108,22 +109,24 @@
                 CustomField => '0',
                 ObjectType => '',
                 ObjectId => '0',
-                Current => '1',
+                SortOrder => '0',
                 Content => '',
                 LargeContent => '',
                 ContentType => '',
                 ContentEncoding => '',
+                Disabled => '0',
 
 		  @_);
     $self->SUPER::Create(
                          CustomField => $args{'CustomField'},
                          ObjectType => $args{'ObjectType'},
                          ObjectId => $args{'ObjectId'},
-                         Current => $args{'Current'},
+                         SortOrder => $args{'SortOrder'},
                          Content => $args{'Content'},
                          LargeContent => $args{'LargeContent'},
                          ContentType => $args{'ContentType'},
                          ContentEncoding => $args{'ContentEncoding'},
+                         Disabled => $args{'Disabled'},
 );
 
 }
@@ -207,19 +210,19 @@
 =cut
 
 
-=head2 Current
+=head2 SortOrder
 
-Returns the current value of Current. 
-(In the database, Current is stored as tinyint(1).)
+Returns the current value of SortOrder. 
+(In the database, SortOrder is stored as int(11).)
 
 
 
-=head2 SetCurrent VALUE
+=head2 SetSortOrder VALUE
 
 
-Set Current to VALUE. 
+Set SortOrder to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Current will be stored as a tinyint(1).)
+(In the database, SortOrder will be stored as a int(11).)
 
 
 =cut
@@ -333,6 +336,24 @@
 =cut
 
 
+=head2 Disabled
+
+Returns the current value of Disabled. 
+(In the database, Disabled is stored as smallint(6).)
+
+
+
+=head2 SetDisabled VALUE
+
+
+Set Disabled to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, Disabled will be stored as a smallint(6).)
+
+
+=cut
+
+
 
 sub _CoreAccessible {
     {
@@ -345,8 +366,8 @@
 		{read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ObjectId => 
 		{read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
-        Current => 
-		{read => 1, write => 1, sql_type => -6, length => 1,  is_blob => 0,  is_numeric => 1,  type => 'tinyint(1)', default => '1'},
+        SortOrder => 
+		{read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Content => 
 		{read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         LargeContent => 
@@ -363,6 +384,8 @@
 		{read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
 		{read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
+        Disabled => 
+		{read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
 
  }
 };

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue_Overlay.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue_Overlay.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValue_Overlay.pm	Thu Nov 11 03:46:17 2004
@@ -53,7 +53,7 @@
                 CustomField => '0',
                 ObjectType => '',
                 ObjectId => '0',
-                Current => '1',
+                Disabled => '0',
                 Content => '',
                 LargeContent => '',
                 ContentType => '',
@@ -65,7 +65,7 @@
                          CustomField => $args{'CustomField'},
                          ObjectType => $args{'ObjectType'},
                          ObjectId => $args{'ObjectId'},
-                         Current => $args{'Current'},
+                         Disabled => $args{'Disabled'},
                          Content => $args{'Content'},
                          LargeContent => $args{'LargeContent'},
                          ContentType => $args{'ContentType'},
@@ -131,7 +131,7 @@
 
 sub Delete {
     my $self = shift;
-    $self->SetCurrent(0);
+    $self->SetDisabled(1);
 }
 
 1;

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues.pm	Thu Nov 11 03:46:17 2004
@@ -82,6 +82,17 @@
     $self->{'primary_key'} = 'id';
 
 
+
+  # By default, order by SortOrder
+  $self->OrderByCols(
+	 { ALIAS => 'main',
+	   FIELD => 'SortOrder',
+	   ORDER => 'ASC' },
+	 { ALIAS => 'main',
+	   FIELD => 'id',
+	   ORDER => 'ASC' },
+     );
+
     return ( $self->SUPER::_Init(@_) );
 }
 

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues_Overlay.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues_Overlay.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFieldValues_Overlay.pm	Thu Nov 11 03:46:17 2004
@@ -124,7 +124,7 @@
     
     #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
     unless($self->{'find_expired_rows'}) {
-        $self->LimitToCurrent();
+        $self->LimitToEnabled();
     }
     
     return($self->SUPER::_DoSearch(@_));
@@ -136,20 +136,12 @@
     
     #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
     unless($self->{'find_expired_rows'}) {
-        $self->LimitToCurrent();
+        $self->LimitToEnabled();
     }
     
     return($self->SUPER::_DoCount(@_));
     
 }
 
-sub LimitToCurrent {
-    my $self = shift;
-    
-    $self->Limit( FIELD => 'Current',
-		  VALUE => '1',
-		  OPERATOR => '=' );
-}
-
 1;
 

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFields.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFields.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/ObjectCustomFields.pm	Thu Nov 11 03:46:17 2004
@@ -83,10 +83,15 @@
 
 
 
-  # By default, order by name
-  $self->OrderBy( ALIAS => 'main',
-                  FIELD => 'SortOrder',
-                  ORDER => 'ASC');
+  # By default, order by SortOrder
+  $self->OrderByCols(
+	 { ALIAS => 'main',
+	   FIELD => 'SortOrder',
+	   ORDER => 'ASC' },
+	 { ALIAS => 'main',
+	   FIELD => 'id',
+	   ORDER => 'ASC' },
+     );
 
     return ( $self->SUPER::_Init(@_) );
 }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Queue_Overlay.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Queue_Overlay.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Queue_Overlay.pm	Thu Nov 11 03:46:17 2004
@@ -182,7 +182,7 @@
     if (@RT::ActiveStatus) {
     	return (@RT::ActiveStatus)
     } else {
-        $RT::Logger->warn("RT::ActiveStatus undefined, falling back to deprecated defaults");
+        $RT::Logger->warning("RT::ActiveStatus undefined, falling back to deprecated defaults");
         return (@DEFAULT_ACTIVE_STATUS);
     }
 }
@@ -202,7 +202,7 @@
     if (@RT::InactiveStatus) {
     	return (@RT::InactiveStatus)
     } else {
-        $RT::Logger->warn("RT::InactiveStatus undefined, falling back to deprecated defaults");
+        $RT::Logger->warning("RT::InactiveStatus undefined, falling back to deprecated defaults");
         return (@DEFAULT_INACTIVE_STATUS);
     }
 }
@@ -649,7 +649,7 @@
             }
         }
      else {
-            $RT::Logger->warn( "$self -> AddWatcher got passed a bogus type");
+            $RT::Logger->warning( "$self -> AddWatcher got passed a bogus type");
             return ( 0, $self->loc('Error in parameters to Queue->AddWatcher') );
         }
     }
@@ -810,7 +810,7 @@
             }
         }
         else {
-            $RT::Logger->warn( "$self -> DeleteWatcher got passed a bogus type");
+            $RT::Logger->warning( "$self -> DeleteWatcher got passed a bogus type");
             return ( 0, $self->loc('Error in parameters to Queue->DeleteWatcher') );
         }
     }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Ticket_Overlay.pm	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/lib/RT/Ticket_Overlay.pm	Thu Nov 11 03:46:17 2004
@@ -692,10 +692,15 @@
           my $value ( UNIVERSAL::isa( $args{$arg} => 'ARRAY' ) ? @{ $args{$arg} } : ( $args{$arg} ) )
         {
             next unless ( length($value) );
+
+            # Allow passing in uploaded LargeContent etc by hash reference
             $self->_AddCustomFieldValue(
+                (UNIVERSAL::isa( $value => 'HASH' )
+                    ? %$value
+                    : (Value => $value)
+                ),
                 Field             => $cfid,
-                Value             => $value,
-                RecordTransaction => 0
+                RecordTransaction => 0,
             );
         }
     }
@@ -1317,7 +1322,7 @@
             }
         }
         else {
-            $RT::Logger->warn( "$self -> AddWatcher got passed a bogus type");
+            $RT::Logger->warning( "$self -> AddWatcher got passed a bogus type");
             return ( 0, $self->loc('Error in parameters to Ticket->AddWatcher') );
         }
     }

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/factory
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/factory	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/factory	Thu Nov 11 03:46:17 2004
@@ -349,10 +349,15 @@
 
         $CollectionClass .= "
 
-  # By default, order by name
-  \$self->OrderBy( ALIAS => 'main',
-                  FIELD => 'SortOrder',
-                  ORDER => 'ASC');
+  # By default, order by SortOrder
+  \$self->OrderByCols(
+	 { ALIAS => 'main',
+	   FIELD => 'SortOrder',
+	   ORDER => 'ASC' },
+	 { ALIAS => 'main',
+	   FIELD => 'id',
+	   ORDER => 'ASC' },
+     );
 ";
     }
     $CollectionClass .= "

Modified: rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/rt-setup-database.in
==============================================================================
--- rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/rt-setup-database.in	(original)
+++ rt/branches/PLATANO-EXPERIMENTAL-CSS/sbin/rt-setup-database.in	Thu Nov 11 03:46:17 2004
@@ -217,7 +217,6 @@
 
 # {{{ sub drop_db
 sub drop_db {
-    return if ( $RT::DatabaseType eq 'SQLite' );
     if ( $RT::DatabaseType eq 'Oracle' ) {
         print <<END;
 
@@ -241,6 +240,10 @@
 
     print "Dropping $RT::DatabaseType database $RT::DatabaseName.\n";
 
+    if ( $RT::DatabaseType eq 'SQLite' ) {
+	unlink $RT::DatabaseName or warn $!;
+	return;
+    }
     $dbh->do("Drop DATABASE $RT::DatabaseName") or warn $DBI::errstr;
 }
 


More information about the Rt-commit mailing list