summaryrefslogtreecommitdiff
path: root/rt/etc
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2015-07-09 22:18:55 -0700
committerIvan Kohler <ivan@freeside.biz>2015-07-09 22:18:55 -0700
commit1c538bfabc2cd31f27067505f0c3d1a46cba6ef0 (patch)
tree96922ad4459eda1e649327fd391d60c58d454c53 /rt/etc
parent4f5619288413a185e9933088d9dd8c5afbc55dfa (diff)
RT 4.2.11, ticket#13852
Diffstat (limited to 'rt/etc')
-rw-r--r--rt/etc/RT_Config.pm.in1106
-rw-r--r--rt/etc/RT_SiteConfig.pm2
-rwxr-xr-xrt/etc/acl.Pg13
-rwxr-xr-xrt/etc/acl.mysql7
-rw-r--r--rt/etc/initialdata350
-rwxr-xr-xrt/etc/schema.Pg52
-rw-r--r--rt/etc/schema.SQLite257
-rw-r--r--rt/etc/schema.mysql55
-rw-r--r--rt/etc/upgrade/3.1.0/content2
-rw-r--r--rt/etc/upgrade/3.1.0/schema.Oracle20
-rw-r--r--rt/etc/upgrade/3.1.15/content5
-rw-r--r--rt/etc/upgrade/3.1.17/content7
-rw-r--r--rt/etc/upgrade/3.3.0/content1
-rw-r--r--rt/etc/upgrade/3.3.11/content1
-rw-r--r--rt/etc/upgrade/3.5.1/content21
-rw-r--r--rt/etc/upgrade/3.7.1/content5
-rw-r--r--rt/etc/upgrade/3.7.10/content5
-rw-r--r--rt/etc/upgrade/3.7.15/content5
-rw-r--r--rt/etc/upgrade/3.7.19/content49
-rw-r--r--rt/etc/upgrade/3.7.82/content5
-rw-r--r--rt/etc/upgrade/3.7.85/content15
-rw-r--r--rt/etc/upgrade/3.7.86/content13
-rw-r--r--rt/etc/upgrade/3.7.87/content5
-rw-r--r--rt/etc/upgrade/3.8-ical-extension.in6
-rw-r--r--rt/etc/upgrade/3.8.0/content13
-rw-r--r--rt/etc/upgrade/3.8.1/content13
-rw-r--r--rt/etc/upgrade/3.8.2/content77
-rw-r--r--rt/etc/upgrade/3.8.3/content55
-rw-r--r--rt/etc/upgrade/3.8.4/content10
-rw-r--r--rt/etc/upgrade/3.8.6/content5
-rw-r--r--rt/etc/upgrade/3.8.8/content9
-rw-r--r--rt/etc/upgrade/3.8.9/content10
-rw-r--r--rt/etc/upgrade/3.9.1/content15
-rw-r--r--rt/etc/upgrade/3.9.2/content15
-rw-r--r--rt/etc/upgrade/3.9.3/schema.Oracle3
-rw-r--r--rt/etc/upgrade/3.9.3/schema.Pg5
-rw-r--r--rt/etc/upgrade/3.9.3/schema.mysql5
-rw-r--r--rt/etc/upgrade/3.9.5/backcompat16
-rw-r--r--rt/etc/upgrade/3.9.5/schema.Oracle30
-rw-r--r--rt/etc/upgrade/3.9.5/schema.Pg27
-rw-r--r--rt/etc/upgrade/3.9.5/schema.mysql9
-rw-r--r--rt/etc/upgrade/3.9.7/content29
-rw-r--r--rt/etc/upgrade/3.9.7/schema.Oracle16
-rw-r--r--rt/etc/upgrade/3.9.7/schema.Pg14
-rw-r--r--rt/etc/upgrade/3.9.7/schema.mysql8
-rw-r--r--rt/etc/upgrade/3.9.8/content11
-rw-r--r--rt/etc/upgrade/3.9.8/schema.Pg5
-rw-r--r--rt/etc/upgrade/3.9.8/schema.SQLite6
-rw-r--r--rt/etc/upgrade/3.9.8/schema.mysql5
-rwxr-xr-xrt/etc/upgrade/4.0-customfield-checkbox-extension7
-rw-r--r--rt/etc/upgrade/4.0-customfield-checkbox-extension.in7
-rw-r--r--rt/etc/upgrade/4.0.0rc7/content13
-rw-r--r--rt/etc/upgrade/4.0.1/content42
-rw-r--r--rt/etc/upgrade/4.0.18/content14
-rw-r--r--rt/etc/upgrade/4.0.19/content29
-rw-r--r--rt/etc/upgrade/4.0.19/schema.mysql5
-rw-r--r--rt/etc/upgrade/4.0.3/content5
-rw-r--r--rt/etc/upgrade/4.0.4/content7
-rw-r--r--rt/etc/upgrade/4.0.6/content7
-rw-r--r--rt/etc/upgrade/4.0.9/content12
-rw-r--r--rt/etc/upgrade/4.1.0/content43
-rw-r--r--rt/etc/upgrade/4.1.1/acl.Pg31
-rw-r--r--rt/etc/upgrade/4.1.1/content36
-rw-r--r--rt/etc/upgrade/4.1.1/schema.Oracle29
-rw-r--r--rt/etc/upgrade/4.1.1/schema.Pg36
-rw-r--r--rt/etc/upgrade/4.1.1/schema.SQLite31
-rw-r--r--rt/etc/upgrade/4.1.1/schema.mysql32
-rw-r--r--rt/etc/upgrade/4.1.10/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.10/schema.Pg1
-rw-r--r--rt/etc/upgrade/4.1.10/schema.mysql1
-rw-r--r--rt/etc/upgrade/4.1.11/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.11/schema.Pg1
-rw-r--r--rt/etc/upgrade/4.1.11/schema.mysql1
-rw-r--r--rt/etc/upgrade/4.1.12/content10
-rw-r--r--rt/etc/upgrade/4.1.13/backcompat34
-rw-r--r--rt/etc/upgrade/4.1.13/schema.Oracle3
-rw-r--r--rt/etc/upgrade/4.1.13/schema.Pg3
-rw-r--r--rt/etc/upgrade/4.1.13/schema.SQLite3
-rw-r--r--rt/etc/upgrade/4.1.13/schema.mysql2
-rw-r--r--rt/etc/upgrade/4.1.14/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.14/schema.Pg3
-rw-r--r--rt/etc/upgrade/4.1.14/schema.mysql3
-rw-r--r--rt/etc/upgrade/4.1.15/content22
-rw-r--r--rt/etc/upgrade/4.1.16/content16
-rw-r--r--rt/etc/upgrade/4.1.17/content26
-rw-r--r--rt/etc/upgrade/4.1.18/content16
-rw-r--r--rt/etc/upgrade/4.1.19/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.19/schema.Pg3
-rw-r--r--rt/etc/upgrade/4.1.19/schema.mysql3
-rw-r--r--rt/etc/upgrade/4.1.20/content56
-rw-r--r--rt/etc/upgrade/4.1.21/content64
-rw-r--r--rt/etc/upgrade/4.1.22/content85
-rw-r--r--rt/etc/upgrade/4.1.22/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.22/schema.Pg1
-rw-r--r--rt/etc/upgrade/4.1.22/schema.SQLite1
-rw-r--r--rt/etc/upgrade/4.1.22/schema.mysql1
-rw-r--r--rt/etc/upgrade/4.1.23/indexes168
-rw-r--r--rt/etc/upgrade/4.1.4/content49
-rw-r--r--rt/etc/upgrade/4.1.4/schema.Oracle1
-rw-r--r--rt/etc/upgrade/4.1.4/schema.Pg1
-rw-r--r--rt/etc/upgrade/4.1.4/schema.SQLite1
-rw-r--r--rt/etc/upgrade/4.1.4/schema.mysql1
-rw-r--r--rt/etc/upgrade/4.1.5/content34
-rw-r--r--rt/etc/upgrade/4.1.5/schema.Oracle6
-rw-r--r--rt/etc/upgrade/4.1.5/schema.Pg2
-rw-r--r--rt/etc/upgrade/4.1.5/schema.mysql2
-rw-r--r--rt/etc/upgrade/4.1.6/content43
-rw-r--r--rt/etc/upgrade/4.1.7/schema.Oracle5
-rw-r--r--rt/etc/upgrade/4.1.7/schema.Pg5
-rw-r--r--rt/etc/upgrade/4.1.7/schema.SQLite2
-rw-r--r--rt/etc/upgrade/4.1.7/schema.mysql5
-rw-r--r--rt/etc/upgrade/4.1.8/schema.Oracle2
-rw-r--r--rt/etc/upgrade/4.1.8/schema.Pg2
-rw-r--r--rt/etc/upgrade/4.1.8/schema.SQLite3
-rw-r--r--rt/etc/upgrade/4.1.8/schema.mysql2
-rw-r--r--rt/etc/upgrade/4.1.9/content190
-rw-r--r--rt/etc/upgrade/4.2.1/content14
-rw-r--r--rt/etc/upgrade/4.2.10/content19
-rw-r--r--rt/etc/upgrade/4.2.11/content60
-rw-r--r--rt/etc/upgrade/4.2.2/content59
-rw-r--r--rt/etc/upgrade/4.2.2/schema.mysql5
-rw-r--r--rt/etc/upgrade/4.2.4/content47
-rw-r--r--rt/etc/upgrade/4.2.6/content9
-rw-r--r--rt/etc/upgrade/4.2.6/schema.mysql4
-rw-r--r--rt/etc/upgrade/4.2.7/content15
-rw-r--r--rt/etc/upgrade/4.2.8/content16
-rw-r--r--rt/etc/upgrade/generate-rtaddressregexp.in11
-rw-r--r--rt/etc/upgrade/sanity-check-stylesheets.in (renamed from rt/etc/upgrade/sanity-check-stylesheets.pl)27
-rw-r--r--rt/etc/upgrade/shrink-cgm-table.in (renamed from rt/etc/upgrade/shrink_cgm_table.pl)16
-rw-r--r--rt/etc/upgrade/shrink-transactions-table.in (renamed from rt/etc/upgrade/shrink_transactions_table.pl)20
-rw-r--r--rt/etc/upgrade/split-out-cf-categories.in11
-rw-r--r--rt/etc/upgrade/switch-templates-to.in145
-rw-r--r--rt/etc/upgrade/time-worked-history.in111
-rwxr-xr-xrt/etc/upgrade/upgrade-articles13
-rw-r--r--rt/etc/upgrade/upgrade-articles.in9
-rwxr-xr-xrt/etc/upgrade/vulnerable-passwords.in5
136 files changed, 3338 insertions, 970 deletions
diff --git a/rt/etc/RT_Config.pm.in b/rt/etc/RT_Config.pm.in
index 498e53c71..fd976de1f 100644
--- a/rt/etc/RT_Config.pm.in
+++ b/rt/etc/RT_Config.pm.in
@@ -115,19 +115,40 @@ Set($Timezone, "US/Eastern");
=item C<@Plugins>
-Set C<@Plugins> to a list of external RT plugins that should be
-enabled (those plugins have to be previously downloaded and
-installed).
+Once a plugin has been downloaded and installed, use C<Plugin()> to add
+to the enabled C<@Plugins> list:
-Example:
+ Plugin( "RT::Extension::SLA" );
+ Plugin( "RT::Authen::ExternalAuth" );
-C<Set(@Plugins, (qw(RT::Extension::SLA RT::Authen::ExternalAuth)));>
+RT will also accept the distribution name (i.e. C<RT-Extension-SLA>)
+instead of the package name (C<RT::Extension::SLA>).
=cut
Set(@Plugins, (qw(RTx::Calendar
RT::Extension::MobileUI))); #RTx::Checklist ));
+=item C<@StaticRoots>
+
+Set C<@StaticRoots> to serve extra paths with a static handler. The
+contents of each hashref should be the the same arguments as
+L<Plack::Middleware::Static> takes. These paths will be checked before
+any plugin or core static paths.
+
+Example:
+
+ Set( @StaticRoots,
+ {
+ path => qr{^/static/},
+ root => '/local/path/to/static/parent',
+ },
+ );
+
+=cut
+
+Set( @StaticRoots, () );
+
=back
@@ -140,7 +161,7 @@ Set(@Plugins, (qw(RTx::Calendar
=item C<$DatabaseType>
Database driver being used; case matters. Valid types are "mysql",
-"Oracle" and "Pg".
+"Oracle", and "Pg". "SQLite" is also available for non-production use.
=cut
@@ -194,15 +215,39 @@ SID and database objects are created in C<$DatabaseUser>'s schema.
Set($DatabaseName, q{@DB_DATABASE@});
-=item C<$DatabaseRequireSSL>
+=item C<%DatabaseExtraDSN>
+
+Allows additional properties to be passed to the database connection
+step. Possible properties are specific to the database-type; see
+https://metacpan.org/pod/DBI#connect
+
+For PostgreSQL, for instance, the following enables SSL (but does no
+certificate checking, providing data hiding but no MITM protection):
+
+ # See https://metacpan.org/pod/DBD::Pg#connect
+ # and http://www.postgresql.org/docs/8.4/static/libpq-ssl.html
+ Set( %DatabaseExtraDSN, sslmode => 'require' );
+
+For MySQL, the following acts similarly if the server has enabled SSL.
+Otherwise, it provides no protection; MySQL provides no way to I<force>
+SSL connections:
+
+ # See https://metacpan.org/pod/DBD::mysql#connect
+ # and http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html
+ Set( %DatabaseExtraDSN, mysql_ssl => 1 );
+
+=cut
+
+Set(%DatabaseExtraDSN, ());
+
+=item C<$DatabaseAdmin>
-If you're using PostgreSQL and have compiled in SSL support, set
-C<$DatabaseRequireSSL> to 1 to turn on SSL communication with the
-database.
+The name of the database administrator to connect to the database as
+during upgrades.
=cut
-Set($DatabaseRequireSSL, undef);
+Set($DatabaseAdmin, "@DB_DBA@");
=back
@@ -222,7 +267,7 @@ message.
=over 4
-=item C<$LogToSyslog>, C<$LogToScreen>
+=item C<$LogToSyslog>, C<$LogToSTDERR>
The minimum level error that will be logged to the specific device.
From lowest to highest priority, the levels are:
@@ -240,7 +285,7 @@ in your web server's error logs).
=cut
Set($LogToSyslog, "info");
-Set($LogToScreen, "info");
+Set($LogToSTDERR, "info");
=item C<$LogToFile>, C<$LogDir>, C<$LogToFileNamed>
@@ -275,11 +320,9 @@ Set($LogStackTraces, "");
=item C<@LogToSyslogConf>
-On Solaris or UnixWare, set to ( socket => 'inet' ). Options here
-override any other options RT passes to L<Log::Dispatch::Syslog>.
-Other interesting flags include facility and logopt. (See the
-L<Log::Dispatch::Syslog> documentation for more information.) (Maybe
-ident too, if you have multiple RT installations.)
+Additional options to pass to L<Log::Dispatch::Syslog>; the most
+interesting flags include C<facility>, C<logopt>, and possibly C<ident>.
+See the L<Log::Dispatch::Syslog> documentation for more information.
=cut
@@ -301,14 +344,7 @@ queue-specific subject tags, you'll likely never have to change this
configuration.
Be B<very careful> with it. Note that it overrides C<$rtname> for
-subject token matching and that you should use only "non-capturing"
-parenthesis grouping. For example:
-
-C<Set($EmailSubjectTagRegex, qr/(?:example.com|example.org)/i );>
-
-and NOT
-
-C<Set($EmailSubjectTagRegex, qr/(example.com|example.org)/i );>
+subject token matching.
The setting below would make RT behave exactly as it does without the
setting enabled.
@@ -320,8 +356,10 @@ setting enabled.
=item C<$OwnerEmail>
C<$OwnerEmail> is the address of a human who manages RT. RT will send
-errors generated by the mail gateway to this address. This address
-should I<not> be an address that's managed by your RT instance.
+errors generated by the mail gateway to this address; it will also be
+displayed as the contact person on the RT's login page. Because RT
+sends errors to this address, it should I<not> be an address that's
+managed by your RT instance, to avoid mail loops.
=cut
@@ -350,11 +388,14 @@ Set($StoreLoops, undef);
C<$MaxAttachmentSize> sets the maximum size (in bytes) of attachments
stored in the database. This setting is irrelevant unless one of
-$TruncateLongAttachments or $DropLongAttachments (below) are set.
+$TruncateLongAttachments or $DropLongAttachments (below) are set, B<OR>
+the database is stored in Oracle. On Oracle, attachments larger than
+this can be fully stored, but will be truncated to this length when
+read.
=cut
-Set($MaxAttachmentSize, 10_000_000);
+Set($MaxAttachmentSize, 10_000_000); # 10M
=item C<$TruncateLongAttachments>
@@ -412,38 +453,31 @@ Set($IgnoreCcRegexp, undef);
=item C<$CanonicalizeEmailAddressMatch>, C<$CanonicalizeEmailAddressReplace>
RT provides functionality which allows the system to rewrite incoming
-email addresses. In its simplest form, you can substitute the value
-in C<CanonicalizeEmailAddressReplace> for the value in
-C<CanonicalizeEmailAddressMatch> (These values are passed to the
-C<CanonicalizeEmailAddress> subroutine in F<RT/User.pm>)
-
-By default, that routine performs a C<s/$Match/$Replace/gi> on any
-address passed to it.
+email addresses, using L<RT::User/CanonicalizeEmailAddress>. The
+default implementation replaces all occurrences of the regular
+expression in C<CanonicalizeEmailAddressMatch> with
+C<CanonicalizeEmailAddressReplace>, via C<s/$Match/$Replace/gi>. The
+most common use of this is to replace C<@something.example.com> with
+C<@example.com>. If more complex noramlization is required,
+L<RT::User/CanonicalizeEmailAddress> can be overridden to provide it.
=cut
# Set($CanonicalizeEmailAddressMatch, '@subdomain\.example\.com$');
# Set($CanonicalizeEmailAddressReplace, '@example.com');
-=item C<$CanonicalizeOnCreate>
-
-Set this to 1 and the create new user page will use the values that
-you enter in the form but use the function CanonicalizeUserInfo in
-F<RT/User_Local.pm>
-
-=cut
-
-Set($CanonicalizeOnCreate, 0);
-
=item C<$ValidateUserEmailAddresses>
-If C<$ValidateUserEmailAddresses> is 1, RT will refuse to create
+By default C<$ValidateUserEmailAddresses> is 1, and RT will refuse to create
users with an invalid email address (as specified in RFC 2822) or with
an email address made of multiple email addresses.
+Set this to 0 to skip any email address validation. Doing so may open up
+vulnerabilities.
+
=cut
-Set($ValidateUserEmailAddresses, undef);
+Set($ValidateUserEmailAddresses, 1);
=item C<$NonCustomerEmailRegexp>
@@ -515,25 +549,15 @@ Set( $CheckMoreMSMailHeaders, 0);
C<$MailCommand> defines which method RT will use to try to send mail.
We know that 'sendmailpipe' works fairly well. If 'sendmailpipe'
-doesn't work well for you, try 'sendmail'. Other options are 'smtp'
-or 'qmail'.
-
-Note that you should remove the '-t' from C<$SendmailArguments> if you
-use 'sendmail' rather than 'sendmailpipe'
+doesn't work well for you, try 'sendmail'. 'qmail' is also a supported
+value.
For testing purposes, or to simply disable sending mail out into the
-world, you can set C<$MailCommand> to 'testfile' which writes all mail
-to a temporary file. RT will log the location of the temporary file
-so you can extract mail from it afterward.
-
-On shutdown, RT will clean up the temporary file created when using
-the 'testfile' option. If testing while the RT server is still running,
-you can find the files in the location noted in the log file. If you run
-a tool like C<rt-crontool> however, or if you look after stopping the server,
-the files will have been deleted when the process completed. If you need to
-keep the files for development or debugging, you can manually set
-C<< UNLINK => 0 >> where the testfile config is processed in
-F<lib/RT/Interface/Email.pm>.
+world, you can set C<$MailCommand> to 'mbox' which logs all mail, in
+mbox format, to files in F</opt/rt4/var/> based in the process start
+time. The 'testfile' option is similar, but the files that it creates
+(under /tmp) are temporary, and removed upon process completion; the
+format is also not mbox-compatable.
=cut
@@ -567,7 +591,7 @@ address of the queue as it is handed to sendmail -f. This helps force
the From_ header away from www-data or other email addresses that show
up in the "Sent by" line in Outlook.
-The option is a hash reference of queue name to email address. If
+The option is a hash reference of queue id/name to email address. If
there is no ticket involved, then the value of the C<Default> key will
be used.
@@ -715,6 +739,29 @@ will use the address of the current user and remove RT's subject tag.
Set($ForwardFromUser, 0);
+=item C<$HTMLFormatter>
+
+RT's default pure-perl formatter may fail to successfully convert even
+on some relatively simple HTML; this will result in blank C<text/plain>
+parts, which is particuarly unfortunate if HTML templates are not in
+use.
+
+If the optional dependency L<HTML::FormatExternal> is installed, RT will
+use external programs to render HTML to plain text. The default is to
+try, in order, C<w3m>, C<elinks>, C<html2text>, C<links>, C<lynx>, and
+then fall back to the C<core> pure-perl formatter if none are installed.
+
+Set C<$HTMLFormatter> to one of the above programs (or the full path to
+such) to use a different program than the above would choose by default.
+Setting this requires that L<HTML::FormatExternal> be installed.
+
+If the chosen formatter is not in the webserver's $PATH, you may set
+this option the full path to one of the aforementioned executables.
+
+=cut
+
+Set($HTMLFormatter, undef);
+
=back
=head2 Email dashboards
@@ -762,16 +809,13 @@ These options only take effect if C<$MailCommand> is 'sendmail' or
=item C<$SendmailArguments>
C<$SendmailArguments> defines what flags to pass to C<$SendmailPath>
-If you picked 'sendmailpipe', you MUST add a -t flag to
-C<$SendmailArguments> These options are good for most sendmail
-wrappers and work-a-likes.
+These options are good for most sendmail wrappers and work-a-likes.
These arguments are good for sendmail brand sendmail 8 and newer:
-C<Set($SendmailArguments,"-oi -t -ODeliveryMode=b -OErrorMode=m");>
+C<Set($SendmailArguments,"-oi -ODeliveryMode=b -OErrorMode=m");>
=cut
-#Set($SendmailArguments, "-oi -t");
Set($SendmailArguments, "-oi");
@@ -796,39 +840,6 @@ Set($SendmailPath, "/usr/sbin/sendmail");
=back
-=head2 SMTP configuration
-
-These options only take effect if C<$MailCommand> is 'smtp'
-
-=over 4
-
-=item C<$SMTPServer>
-
-C<$SMTPServer> should be set to the hostname of the SMTP server to use
-
-=cut
-
-Set($SMTPServer, undef);
-
-=item C<$SMTPFrom>
-
-C<$SMTPFrom> should be set to the 'From' address to use, if not the
-email's 'From'
-
-=cut
-
-Set($SMTPFrom, undef);
-
-=item C<$SMTPDebug>
-
-C<$SMTPDebug> should be set to 1 to debug SMTP mail sending
-
-=cut
-
-Set($SMTPDebug, 0);
-
-=back
-
=head2 Other mailers
=over 4
@@ -836,7 +847,7 @@ Set($SMTPDebug, 0);
=item C<@MailParams>
C<@MailParams> defines a list of options passed to $MailCommand if it
-is not 'sendmailpipe', 'sendmail', or 'smtp'
+is not 'sendmailpipe' or 'sendmail';
=cut
@@ -854,15 +865,16 @@ Set(@MailParams, ());
This determines the default stylesheet the RT web interface will use.
RT ships with several themes by default:
- web2 The default layout for RT 3.8
+ rudder The default theme for RT 4.2
aileron The default layout for RT 4.0
+ web2 The default layout for RT 3.8
ballard Theme which doesn't rely on JavaScript for menuing
This bundled distibution of RT also includes:
- freeside3 Integration with Freeside (enabled by default)
- freeside2.1 Previous Freeside theme
+ freeside4 Integration with Freeside (enabled by default)
+ freeside3 Previous Freeside theme
-This value actually specifies a directory in F<share/html/NoAuth/css/>
+This value actually specifies a directory in F<share/static/css/>
from which RT will try to load the file main.css (which should @import
any other files the stylesheet needs). This allows you to easily and
cleanly create your own stylesheets to apply to RT. This option can
@@ -870,7 +882,7 @@ be overridden by users in their preferences.
=cut
-Set($WebDefaultStylesheet, "freeside3");
+Set($WebDefaultStylesheet, "freeside4");
=item C<$DefaultQueue>
@@ -909,6 +921,48 @@ custom field values from external sources at runtime.
Set(@CustomFieldValuesSources, ('RT::CustomFieldValues::Queues'));
+=item C<%CustomFieldGroupings>
+
+This option affects the display of ticket and user custom fields in the
+web interface. It does not address the sorting of custom fields within
+the groupings; which is controlled by the Ticket Custom Fields tab in
+Queue Configuration in the Admin UI.
+
+A nested datastructure defines how to group together custom fields
+under a mix of built-in and arbitrary headings ("groupings").
+
+Set C<%CustomFieldGroupings> to a nested structure similar to the following:
+
+ Set(%CustomFieldGroupings,
+ 'RT::Ticket' => [
+ 'Grouping Name' => ['CF Name', 'Another CF'],
+ 'Another Grouping' => ['Some CF'],
+ 'Dates' => ['Shipped date'],
+ ],
+ 'RT::User' => [
+ 'Phones' => ['Fax number'],
+ ],
+ );
+
+The first level keys are record types for which CFs may be used, and the
+values are either hashrefs or arrayrefs -- if arrayrefs, then the
+ordering is preserved during display, otherwise groupings are displayed
+alphabetically. The second level keys are the grouping names and the
+values are array refs containing a list of CF names.
+
+There are several special built-in groupings which RT displays in
+specific places (usually the collapsible box of the same title). The
+ordering of these standard groupings cannot be modified. You may also
+only append Custom Fields to the list in these boxes, not reorder or
+remove core fields.
+
+For C<RT::Ticket>, these groupings are: C<Basics>, C<Dates>, C<Links>, C<People>
+
+For C<RT::User>: C<Identity>, C<Access control>, C<Location>, C<Phones>
+
+Extensions may also add their own built-in groupings, refer to the individual
+extension documentation for those.
+
=item C<$CanonicalizeRedirectURLs>
Set C<$CanonicalizeRedirectURLs> to 1 to use C<$WebURL> when
@@ -925,32 +979,25 @@ enable this option.
Set($CanonicalizeRedirectURLs, 0);
-=item C<@JSFiles>
+=item C<$CanonicalizeURLsInFeeds>
+
+Set C<$CanonicalizeURLsInFeeds> to 1 to use C<$WebURL> in feeds
+rather than the one we get from request.
+
+If you use RT behind a reverse proxy, you almost certainly want to
+enable this option.
-A list of JavaScript files to be included in head. Removing any of
-the default entries is not suggested.
+=cut
+
+Set($CanonicalizeURLsInFeeds, 0);
-If you're a plugin author, refer to RT->AddJavaScript.
+=item C<@JSFiles>
+
+A list of additional JavaScript files to be included in head.
=cut
-Set(@JSFiles, qw/
- jquery-1.4.2.min.js
- jquery_noconflict.js
- jquery-ui-1.8.4.custom.min.js
- jquery-ui-timepicker-addon.js
- jquery-ui-patch-datepicker.js
- jquery.cookie.js
- titlebox-state.js
- util.js
- userautocomplete.js
- jquery.event.hover-1.0.js
- superfish.js
- supersubs.js
- jquery.supposition.js
- history-folding.js
- late.js
-/);
+Set(@JSFiles, qw//);
=item C<$JSMinPath>
@@ -977,14 +1024,75 @@ Set(@CSSFiles, qw//);
=item C<$UsernameFormat>
-This determines how user info is displayed. 'concise' will show one of
-either NickName, RealName, Name or EmailAddress, depending on what
-exists and whether the user is privileged or not. 'verbose' will show
-RealName and EmailAddress.
+This determines how user info is displayed. 'concise' will show the
+first of RealName, Name or EmailAddress that has a value. 'verbose' will
+show EmailAddress, and the first of RealName or Name which is defined.
+The default, 'role', uses 'verbose' for unprivileged users, and the Name
+followed by the RealName for privileged users.
=cut
-Set($UsernameFormat, "verbose");
+Set($UsernameFormat, "concise");
+
+=item C<$UserSearchResultFormat>
+
+This controls the display of lists of users returned from the User
+Summary Search. The display of users in the Admin interface is
+controlled by C<%AdminSearchResultFormat>.
+
+=cut
+
+Set($UserSearchResultFormat,
+ q{ '<a href="__WebPath__/User/Summary.html?id=__id__">__id__</a>/TITLE:#'}
+ .q{,'<a href="__WebPath__/User/Summary.html?id=__id__">__Name__</a>/TITLE:Name'}
+ .q{,__RealName__, __EmailAddress__}
+);
+
+=item C<@UserSummaryPortlets>
+
+A list of portlets to be displayed on the User Summary page.
+By default, we show all of the available portlets.
+Extensions may provide their own portlets for this page.
+
+=cut
+
+Set(@UserSummaryPortlets, (qw/ExtraInfo CreateTicket ActiveTickets InactiveTickets/));
+
+=item C<$UserSummaryExtraInfo>
+
+This controls what information is displayed on the User Summary
+portal. By default the user's Real Name, Email Address and Username
+are displayed. You can remove these or add more as needed. This
+expects a Format string of user attributes. Please note that not all
+the attributes are supported in this display because we're not
+building a table.
+
+=cut
+
+Set($UserSummaryExtraInfo, "RealName, EmailAddress, Name");
+
+=item C<$UserSummaryTicketListFormat>
+
+Control the appearance of the Active and Inactive ticket lists in the
+User Summary.
+
+=cut
+
+Set($UserSummaryTicketListFormat, q{
+ '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__id__</a></B>/TITLE:#',
+ '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject',
+ Status,
+ QueueName,
+ Owner,
+ Priority,
+ '__NEWLINE__',
+ '',
+ '<small>__Requestors__</small>',
+ '<small>__CreatedRelative__</small>',
+ '<small>__ToldRelative__</small>',
+ '<small>__LastUpdatedRelative__</small>',
+ '<small>__TimeLeft__</small>'
+});
=item C<$WebBaseURL>, C<$WebURL>
@@ -1018,7 +1126,7 @@ Define the directory name to be used for images in RT web documents.
=cut
-Set($WebImagesURL, RT->Config->Get('WebPath') . "/NoAuth/images/");
+Set($WebImagesURL, RT->Config->Get('WebPath') . "/static/images/");
=item C<$LogoURL>
@@ -1046,24 +1154,6 @@ will be passed through C<loc> for localization.
Set($LogoAltText, "Best Practical Solutions, LLC corporate logo");
-=item C<$LogoImageHeight>
-
-C<$LogoImageHeight> is the value of the C<height> attribute of the logo
-C<img> tag.
-
-=cut
-
-Set($LogoImageHeight, 38);
-
-=item C<$LogoImageWidth>
-
-C<$LogoImageWidth> is the value of the C<width> attribute of the logo
-C<img> tag.
-
-=cut
-
-Set($LogoImageWidth, 181);
-
=item C<$WebNoAuthRegex>
What portion of RT's URL space should not require authentication. The
@@ -1112,10 +1202,10 @@ RT comes with two TrueType fonts covering most available languages.
Set(
%ChartFont,
- 'zh-cn' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
- 'zh-tw' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
- 'ja' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
- 'others' => "$RT::BasePath/share/fonts/DroidSans.ttf",
+ 'zh-cn' => "$RT::FontPath/DroidSansFallback.ttf",
+ 'zh-tw' => "$RT::FontPath/DroidSansFallback.ttf",
+ 'ja' => "$RT::FontPath/DroidSansFallback.ttf",
+ 'others' => "$RT::FontPath/DroidSans.ttf",
);
=item C<$ChartsTimezonesInDB>
@@ -1132,6 +1222,19 @@ At this time, this feature only applies to MySQL and PostgreSQL.
Set($ChartsTimezonesInDB, 0);
+=item C<@ChartColors>
+
+An array of 6-digit hexadecimal RGB color values used for chart series. By
+default there are 12 distinct colors.
+
+=cut
+
+Set(@ChartColors, qw(
+ 66cc66 ff6666 ffcc66 663399
+ 3333cc 339933 993333 996633
+ 33cc33 cc3333 cc9933 6633cc
+));
+
=back
@@ -1168,7 +1271,7 @@ user's customized homepage ("RT at a glance").
Set(
$HomepageComponents,
[
- qw(QuickCreate Quicksearch MyCalendar MyAdminQueues MySupportQueues MyReminders RefreshHomepage Dashboards SavedSearches ) # loc_qw
+ qw(QuickCreate Quicksearch MyCalendar MyAdminQueues MySupportQueues MyReminders RefreshHomepage Dashboards SavedSearches FindUser ) # loc_qw
]
);
@@ -1184,16 +1287,13 @@ Set(
=item C<$UseSQLForACLChecks>
Historically, ACLs were checked on display, which could lead to empty
-search pages and wrong ticket counts. Set C<$UseSQLForACLChecks> to 1
-to limit search results in SQL instead, which eliminates these
-problems.
-
-This option is still relatively new; it may result in performance
-problems in some cases, or significant speedups in others.
+search pages and wrong ticket counts. Set C<$UseSQLForACLChecks> to 0
+to go back to this method; this will reduce the complexity of the
+generated SQL statements, at the cost of the aforementioned bugs.
=cut
-Set($UseSQLForACLChecks, undef);
+Set($UseSQLForACLChecks, 1);
=item C<$TicketsItemMapSize>
@@ -1234,7 +1334,7 @@ Set ($DefaultSearchResultFormat, qq{
Customer,
Status,
QueueName,
- OwnerName,
+ Owner,
Priority,
'__NEWLINE__',
'__NBSP__',
@@ -1245,6 +1345,23 @@ Set ($DefaultSearchResultFormat, qq{
'<small>__LastUpdatedRelative__</small>',
'<small>__TimeLeft__</small>'});
+=item C<$DefaultSearchResultOrderBy>
+
+What Tickets column should we order by for RT Ticket search results.
+
+=cut
+
+Set($DefaultSearchResultOrderBy, 'id');
+
+=item C<$DefaultSearchResultOrder>
+
+When ordering RT Ticket search results by C<$DefaultSearchResultOrderBy>,
+should the sort be ascending (ASC) or descending (DESC).
+
+=cut
+
+Set($DefaultSearchResultOrder, 'ASC');
+
=item C<$DefaultSelfServiceSearchResultFormat>
C<$DefaultSelfServiceSearchResultFormat> is the default format of
@@ -1257,7 +1374,7 @@ Set($DefaultSelfServiceSearchResultFormat, qq{
'<B><A HREF="__WebPath__/SelfService/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject',
Status,
Requestors,
- OwnerName});
+ Owner});
=item C<%FullTextSearch>
@@ -1337,6 +1454,20 @@ Ticket/Display.html. This option can be controlled by users also.
Set($MoreAboutRequestorTicketList, "Active");
+=item C<$MoreAboutRequestorTicketListFormat>
+
+Control the appearance of the ticket lists in the 'More About Requestors' box.
+
+=cut
+
+Set($MoreAboutRequestorTicketListFormat, q{
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
+ '__Owner__',
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
+ '__Status__',
+});
+
+
=item C<$MoreAboutRequestorExtraInfo>
By default, the 'More about requestor' box on Ticket/Display.html
@@ -1398,6 +1529,12 @@ builder are replaced by text fields that autocomplete. This can
alleviate the sometimes huge owner list for installations where many
users have the OwnTicket right.
+Autocompleter is automatically turned on if list contains more than
+50 users, but penalty of executing potentially slow query is still paid.
+
+Drop down doesn't show unprivileged users. If your setup allows unprivileged
+to own ticket then you have to enable autocompleting.
+
=cut
Set($AutocompleteOwners, 0);
@@ -1412,15 +1549,19 @@ is ignored. Helpful when owners list is huge in the query builder.
Set($AutocompleteOwnersForSearch, 0);
-=item C<$UserAutocompleteFields>
+=item C<$UserSearchFields>
+
+Used by the User Autocompleter as well as the User Search.
-Specifies which fields of L<RT::User> to match against and how to
-match each field when autocompleting users. Valid match methods are
-LIKE, STARTSWITH, ENDSWITH, =, and !=.
+Specifies which fields of L<RT::User> to match against and how to match
+each field when autocompleting users. Valid match methods are LIKE,
+STARTSWITH, ENDSWITH, =, and !=. Valid search fields are the core User
+fields, as well as custom fields, which are specified as "CF.1234" or
+"CF.Name"
=cut
-Set($UserAutocompleteFields, {
+Set($UserSearchFields, {
EmailAddress => 'STARTSWITH',
Name => 'STARTSWITH',
RealName => 'LIKE',
@@ -1428,14 +1569,31 @@ Set($UserAutocompleteFields, {
=item C<$AllowUserAutocompleteForUnprivileged>
-Should unprivileged users be allowed to autocomplete users. Setting
-this option to 1 means unprivileged users will be able to search all
-your users.
+Should unprivileged users (users of SelfService) be allowed to
+autocomplete users. Setting this option to 1 means unprivileged users
+will be able to search all your users.
=cut
Set($AllowUserAutocompleteForUnprivileged, 0);
+=item C<$TicketAutocompleteFields>
+
+Specifies which fields of L<RT::Ticket> to match against and how to match each
+field when autocompleting users. Valid match methods are LIKE, STARTSWITH,
+ENDSWITH, C<=>, and C<!=>.
+
+Not all Ticket fields are publically accessible and hence won't work for
+autocomplete unless you override their accessibility using a local overlay or a
+plugin. Out of the box the following fields are public: id, Subject.
+
+=cut
+
+Set( $TicketAutocompleteFields, {
+ id => 'STARTSWITH',
+ Subject => 'LIKE',
+});
+
=item C<$DisplayTicketAfterQuickCreate>
Enable this to redirect to the created ticket display page
@@ -1542,15 +1700,6 @@ for Rich Text settings.
Set($MessageBoxWidth, undef);
Set($MessageBoxHeight, 15);
-=item C<$MessageBoxWrap>
-
-Wrapping is disabled when using MessageBoxRichText because of a bad
-interaction between IE and wrapping with the Rich Text Editor.
-
-=cut
-
-Set($MessageBoxWrap, "SOFT");
-
=item C<$MessageBoxRichText>
Should "rich text" editing be enabled? This option lets your users
@@ -1580,7 +1729,7 @@ Set($MessageBoxIncludeSignature, 1);
=item C<$MessageBoxIncludeSignatureOnComment>
Should your users' signatures (from their Preferences page) be
-included in Comments. Setting this to false overrides
+included in Comments. Setting this to 0 overrides
C<$MessageBoxIncludeSignature>.
=cut
@@ -1604,15 +1753,39 @@ option can be overridden by users in their preferences.
Set($OldestTransactionsFirst, 1);
-=item C<$DeferTransactionLoading>
+=item C<$ShowHistory>
+
+This option controls how history is shown on the ticket display page. It
+accepts one of three possible modes and is overrideable on a per-user
+preference level. If you regularly deal with long tickets and don't care much
+about the history, you may wish to change this option to C<click>.
+
+=over
+
+=item C<delay> (the default)
+
+When set to C<delay>, history is loaded via javascript after the rest of the
+page has been loaded. This speeds up apparent page load times and generally
+provides a smoother experience. You may notice slight delays before the ticket
+history appears on very long tickets.
+
+=item C<click>
-When set, defers loading ticket history until the user clicks a link.
-This should end up serving pages to users quicker, since generating
-all the HTML for transaction history can be slow for long tickets.
+When set to C<click>, history is loaded on demand when a placeholder link is
+clicked. This speeds up ticket display page loads and history is never loaded
+if not requested.
+
+=item C<always>
+
+When set to C<always>, history is loaded before showing the page. This ensures
+history is always available immediately, but at the expense of longer page load
+times. This behaviour was the default in RT 4.0.
+
+=back
=cut
-# Set($DeferTransactionLoading, 1);
+Set($ShowHistory, 'delay');
=item C<$ShowBccHeader>
@@ -1642,28 +1815,24 @@ overrides C<TrustHTMLAttachments>.
Set($AlwaysDownloadAttachments, undef);
-=item C<$AttachmentUnits>
-
-Controls the units (kilobytes or bytes) that attachment sizes use for
-display. The default is to display kilobytes if the attachment is
-larger than 1024 bytes, bytes otherwise. If you set
-C<$AttachmentUnits> to C<'k'> then attachment sizes will always be
-displayed in kilobytes. If set to C<'b'>, then sizes will be bytes.
-
-=cut
+=item C<$PreferRichText>
-Set($AttachmentUnits, undef);
+By default, RT shows rich text (HTML) messages if possible. If
+C<$PreferRichText> is set to 0, RT will show plain text messages in
+preference to any rich text alternatives.
-=item C<$PreferRichText>
+As a security precaution, RT limits the HTML that is displayed to a
+known-good subset -- as allowing arbitrary HTML to be displayed exposes
+multiple vectors for XSS and phishing attacks. If
+L</$TrustHTMLAttachments> is enabled, the original HTML is available for
+viewing via the "Download" link.
-If C<$PreferRichText> is set to 1, RT will show HTML/Rich text messages
-in preference to their plain-text alternatives. RT "scrubs" the HTML to
-show only a minimal subset of HTML to avoid possible contamination by
-cross-site-scripting attacks.
+If the optional L<HTML::Gumbo> dependency is installed, RT will leverage
+this to allow a broader set of HTML through, including tables.
=cut
-Set($PreferRichText, undef);
+Set($PreferRichText, 1);
=item C<$MaxInlineBody>
@@ -1686,23 +1855,25 @@ behavior.
Set($ShowTransactionImages, 1);
-=item C<$PlainTextPre>
+=item C<$ShowRemoteImages>
-Normally plaintext attachments are displayed as HTML with line breaks
-preserved. This causes space- and tab-based formatting not to be
-displayed correctly. By setting $PlainTextPre messages will be
-displayed using <pre>.
+By default, RT doesn't show remote images attached to incoming (and outgoing)
+ticket updates inline. Set this variable to 1 if you'd like to enable remote
+image display. Showing remote images may allow spammers and other senders to
+track when messages are viewed and see referer information.
-=cut
+Note that this setting is independent of L</$ShowTransactionImages> above.
-Set($PlainTextPre, 0);
+=cut
+Set($ShowRemoteImages, 0);
=item C<$PlainTextMono>
-Set C<$PlainTextMono> to 1 to use monospaced font and preserve
-formatting; unlike C<$PlainTextPre>, the text will wrap to fit width
-of the browser window; this option overrides C<$PlainTextPre>.
+Normally plaintext attachments are displayed as HTML with line breaks
+preserved. This causes space- and tab-based formatting not to be
+displayed correctly. Set C<$PlainTextMono> to 1 to use a monospaced
+font and preserve formatting.
=cut
@@ -1729,17 +1900,35 @@ provides two formats:
link after the URL.
* 'httpurl_overwrite': also detects URLs as 'httpurl' format, but
- replaces the URL with a link.
+ replaces the URL with a link. Enabled by default.
See F<share/html/Elements/MakeClicky> for documentation on how to add
your own styles of link detection.
=cut
-Set(@Active_MakeClicky, qw());
+Set(@Active_MakeClicky, qw(httpurl_overwrite));
-=back
+=item C<$QuoteFolding>
+
+Quote folding is the hiding of old replies in transaction history.
+It defaults to on. Set this to 0 to disable it.
+
+=cut
+
+Set($QuoteFolding, 1);
+
+=item C<$AllowLoginPasswordAutoComplete>
+Allow browsers to remember the user's password on login (in case the
+browser can do so, and has the appropriate setting enabled). Default
+is 0.
+
+=cut
+
+Set($AllowLoginPasswordAutoComplete, 0);
+
+=back
=head1 Application logic
@@ -1805,8 +1994,9 @@ Set($ApprovalRejectionNotes, 1);
=item C<$ForceApprovalsView>
Should approval tickets only be viewed and modified through the standard
-approval interface? Changing this setting to 1 will redirect any attempt to
-use the normal ticket display and modify page for approval tickets.
+approval interface? With this setting enabled (by default), any attempt to use
+the normal ticket display and modify page for approval tickets will be
+redirected.
For example, with this option set to 1 and an approval ticket #123:
@@ -1816,11 +2006,13 @@ is redirected to
/Approval/Display.html?id=123
+With this option set to 0, the redirect won't happen.
+
=back
=cut
-Set($ForceApprovalsView, 0);
+Set($ForceApprovalsView, 1);
=head1 Extra security
@@ -1832,7 +2024,7 @@ defaults alone.
=item C<$DisallowExecuteCode>
-If set to a true value, the C<ExecuteCode> right will be removed from
+If set to 1, the C<ExecuteCode> right will be removed from
all users, B<including> the superuser. This is intended for when RT is
installed into a shared environment where even the superuser should not
be allowed to run arbitrary Perl code on the server via scrips.
@@ -1843,7 +2035,7 @@ Set($DisallowExecuteCode, 0);
=item C<$Framebusting>
-If set to a false value, framekiller javascript will be disabled and the
+If set to 0, framekiller javascript will be disabled and the
X-Frame-Options: DENY header will be suppressed from all responses.
This disables RT's clickjacking protection.
@@ -1853,7 +2045,7 @@ Set($Framebusting, 1);
=item C<$RestrictReferrer>
-If set to a false value, the HTTP C<Referer> (sic) header will not be
+If set to 0, the HTTP C<Referer> (sic) header will not be
checked to ensure that requests come from RT's own domain. As RT allows
for GET requests to alter state, disabling this opens RT up to
cross-site request forgery (CSRF) attacks.
@@ -1864,9 +2056,9 @@ Set($RestrictReferrer, 1);
=item C<$RestrictLoginReferrer>
-If set to a false value, RT will allow the user to log in from any link
+If set to 0, RT will allow the user to log in from any link
or request, merely by passing in C<user> and C<pass> parameters; setting
-it to a true value forces all logins to come from the login box, so the
+it to 1 forces all logins to come from the login box, so the
user is aware that they are being logged in. The default is off, for
backwards compatability.
@@ -1901,6 +2093,17 @@ Simple wildcards, similar to SSL certificates, are allowed. For example:
Set(@ReferrerWhitelist, qw());
+
+=item C<$BcryptCost>
+
+This sets the default cost parameter used for the C<bcrypt> key
+derivation function. Valid values range from 4 to 31, inclusive, with
+higher numbers denoting greater effort.
+
+=cut
+
+Set($BcryptCost, 10);
+
=back
@@ -1909,74 +2112,89 @@ Set(@ReferrerWhitelist, qw());
=over 4
-=item C<$WebExternalAuth>
+=item C<$WebRemoteUserAuth>
-If C<$WebExternalAuth> is defined, RT will defer to the environment's
-REMOTE_USER variable.
+If C<$WebRemoteUserAuth> is defined, RT will defer to the environment's
+REMOTE_USER variable, which should be set by the webserver's
+authentication layer.
=cut
-Set($WebExternalAuth, undef);
+Set($WebRemoteUserAuth, undef);
-=item C<$WebExternalAuthContinuous>
+=item C<$WebRemoteUserContinuous>
-If C<$WebExternalAuthContinuous> is defined, RT will check for the
+If C<$WebRemoteUserContinuous> is defined, RT will check for the
REMOTE_USER on each access. If you would prefer this to only happen
-once (at initial login) set this to a false value. The default
-setting will help ensure that if your external authentication system
+once (at initial login) set this to 0. The default
+setting will help ensure that if your webserver's authentication layer
deauthenticates a user, RT notices as soon as possible.
=cut
-Set($WebExternalAuthContinuous, 1);
+Set($WebRemoteUserContinuous, 1);
-=item C<$WebFallbackToInternalAuth>
+=item C<$WebFallbackToRTLogin>
-If C<$WebFallbackToInternalAuth> is defined, the user is allowed a
+If C<$WebFallbackToRTLogin> is defined, the user is allowed a
chance of fallback to the login screen, even if REMOTE_USER failed.
=cut
-Set($WebFallbackToInternalAuth, undef);
+Set($WebFallbackToRTLogin, undef);
-=item C<$WebExternalGecos>
+=item C<$WebRemoteUserGecos>
-C<$WebExternalGecos> means to match 'gecos' field as the user
-identity); useful with mod_auth_pwcheck and IIS Integrated Windows
-logon.
+C<$WebRemoteUserGecos> means to match 'gecos' field as the user
+identity; useful with C<mod_auth_external>.
=cut
-Set($WebExternalGecos, undef);
+Set($WebRemoteUserGecos, undef);
-=item C<$WebExternalAuto>
+=item C<$WebRemoteUserAutocreate>
-C<$WebExternalAuto> will create users under the same name as
-REMOTE_USER upon login, if it's missing in the Users table.
+C<$WebRemoteUserAutocreate> will create users under the same name as
+REMOTE_USER upon login, if they are missing from the Users table.
=cut
-Set($WebExternalAuto, undef);
+Set($WebRemoteUserAutocreate, undef);
-=item C<$AutoCreate>
+=item C<$UserAutocreateDefaultsOnLogin>
-If C<$WebExternalAuto> is set to 1, C<$AutoCreate> will be passed to
-User's Create method. Use it to set defaults, such as creating
-Unprivileged users with C<{ Privileged => 0 }> This must be a hashref.
+If C<$WebRemoteUserAutocreate> is set to 1, C<$UserAutocreateDefaultsOnLogin>
+will be passed to L<RT::User/Create>. Use it to set defaults, such as
+creating unprivileged users with C<<{ Privileged => 0 }>>. This must be
+a hashref.
=cut
-Set($AutoCreate, undef);
+Set($UserAutocreateDefaultsOnLogin, undef);
=item C<$WebSessionClass>
-C<$WebSessionClass> is the class you wish to use for managing sessions.
-It defaults to use your SQL database, except on Oracle, where it
-defaults to files on disk.
+C<$WebSessionClass> is the class you wish to use for storing sessions. On
+MySQL, Pg, and Oracle it defaults to using your database, in other cases
+sessions are stored in files using L<Apache::Session::File>. Other installed
+Apache::Session::* modules can be used to store sessions.
+
+ Set($WebSessionClass, "Apache::Session::File");
=cut
-# Set($WebSessionClass, "Apache::Session::File");
+Set($WebSessionClass, undef);
+
+=item C<%WebSessionProperties>
+
+C<%WebSessionProperties> is the hash to configure class L</$WebSessionClass>
+in case custom class is used. By default it's empty and values are picked
+depending on the class. Make sure that it's empty if you're using DB as session
+backend.
+
+=cut
+
+Set( %WebSessionProperties );
=item C<$AutoLogoff>
@@ -2149,12 +2367,139 @@ them.
Set($SimpleSearchIncludeResolved, 0);
+=item C<$TimeInICal>
+
+By default, events in the iCal feed on the ticket search page
+contain only dates, making them all day calendar events. Set
+C<$TimeInICal> if you have start or due dates on tickets that
+have significant time values and you want those times to be
+included in the events in the iCal feed.
+
+This option can also be set as an individual user preference.
+
+=cut
+
+Set($TimeInICal, 0);
+
=back
+=head1 Cryptography
+
+A complete description of RT's cryptography capabilities can be found in
+L<RT::Crypt>. At this moment, GnuPG (PGP) and SMIME security protocols are
+supported.
+
+=over 4
+
+=item C<%Crypt>
+
+The following options apply to all cryptography protocols.
+
+By default, all enabled security protocols will analyze each incoming
+email. You may set C<Incoming> to a subset of this list, if some enabled
+protocols do not apply to incoming mail; however, this is usually
+unnecessary. Note that for any verification or decryption to occur for
+incoming mail, the C<Auth::Crypt> mail plugin must be added to
+L</@MailPlugins> as specified in L<RT::Crypt/Handling incoming messages>.
+
+For outgoing emails, the first security protocol from the above list is
+used. Use the C<Outgoing> option to set a security protocol that should
+be used in outgoing emails. At this moment, only one protocol can be
+used to protect outgoing emails.
+
+Set C<RejectOnUnencrypted> to 1 if all incoming email must be
+properly encrypted. All unencrypted emails will be rejected by RT.
+
+Set C<RejectOnMissingPrivateKey> to 0 if you don't want to reject
+emails encrypted for key RT doesn't have and can not decrypt.
+
+Set C<RejectOnBadData> to 0 if you don't want to reject letters
+with incorrect data.
+
+If you want to allow people to encrypt attachments inside the DB then
+set C<AllowEncryptDataInDB> to 1.
+
+Set C<Dashboards> to a hash with Encrypt and Sign keys to control
+whether dashboards should be encrypted and/or signed correspondingly.
+By default they are not encrypted or signed.
+
+=back
+
+=cut
-=head1 GnuPG integration
+Set( %Crypt,
+ Incoming => undef, # ['GnuPG', 'SMIME']
+ Outgoing => undef, # 'SMIME'
+
+ RejectOnUnencrypted => 0,
+ RejectOnMissingPrivateKey => 1,
+ RejectOnBadData => 1,
+
+ AllowEncryptDataInDB => 0,
+
+ Dashboards => {
+ Encrypt => 0,
+ Sign => 0,
+ },
+);
+
+=head2 SMIME configuration
+
+A full description of the SMIME integration can be found in
+L<RT::Crypt::SMIME>.
+
+=over 4
+
+=item C<%SMIME>
+
+Set C<Enable> to 0 or 1 to disable or enable SMIME for
+encrypting and signing messages.
+
+Set C<OpenSSL> to path to F<openssl> executable.
+
+Set C<Keyring> to directory with key files. Key and certificates should
+be stored in a PEM file in this directory named named, e.g.,
+F<email.address@example.com.pem>.
+
+Set C<CAPath> to either a PEM-formatted certificate of a single signing
+certificate authority, or a directory of such (including hash symlinks
+as created by the openssl tool C<c_rehash>). Only SMIME certificates
+signed by these certificate authorities will be treated as valid
+signatures. If left unset (and C<AcceptUntrustedCAs> is unset, as it is
+by default), no signatures will be marked as valid!
+
+Set C<AcceptUntrustedCAs> to allow arbitrary SMIME certificates, no
+matter their signing entities. Such mails will be marked as untrusted,
+but signed; C<CAPath> will be used to mark which mails are signed by
+trusted certificate authorities. This configuration is generally
+insecure, as it allows the possibility of accepting forged mail signed
+by an untrusted certificate authority.
+
+Setting C<AcceptUntrustedCAs> also allows encryption to users with
+certificates created by untrusted CAs.
+
+Set C<Passphrase> to a scalar (to use for all keys), an anonymous
+function, or a hash (to look up by address). If the hash is used, the
+'' key is used as a default.
+
+See L<RT::Crypt::SMIME> for details.
+
+=back
+
+=cut
+
+Set( %SMIME,
+ Enable => @RT_SMIME@,
+ OpenSSL => 'openssl',
+ Keyring => q{@RT_VAR_PATH@/data/smime},
+ CAPath => undef,
+ AcceptUntrustedCAs => undef,
+ Passphrase => undef,
+);
+
+=head2 GnuPG configuration
A full description of the (somewhat extensive) GnuPG integration can
be found by running the command `perldoc L<RT::Crypt::GnuPG>` (or
@@ -2164,27 +2509,25 @@ be found by running the command `perldoc L<RT::Crypt::GnuPG>` (or
=item C<%GnuPG>
-Set C<OutgoingMessagesFormat> to 'inline' to use inline encryption and
-signatures instead of 'RFC' (GPG/MIME: RFC3156 and RFC1847) format.
+Set C<Enable> to 0 or 1 to disable or enable GnuPG interfaces
+for encrypting and signing outgoing messages.
-If you want to allow people to encrypt attachments inside the DB then
-set C<AllowEncryptDataInDB> to 1.
+Set C<GnuPG> to the name or path of the gpg binary to use.
-Set C<RejectOnMissingPrivateKey> to false if you don't want to reject
-emails encrypted for key RT doesn't have and can not decrypt.
+Set C<Passphrase> to a scalar (to use for all keys), an anonymous
+function, or a hash (to look up by address). If the hash is used, the
+'' key is used as a default.
-Set C<RejectOnBadData> to false if you don't want to reject letters
-with incorrect GnuPG data.
+Set C<OutgoingMessagesFormat> to 'inline' to use inline encryption and
+signatures instead of 'RFC' (GPG/MIME: RFC3156 and RFC1847) format.
=cut
Set(%GnuPG,
- Enable => @RT_GPG@,
+ Enable => @RT_GPG@,
+ GnuPG => 'gpg',
+ Passphrase => undef,
OutgoingMessagesFormat => "RFC", # Inline
- AllowEncryptDataInDB => 0,
-
- RejectOnMissingPrivateKey => 1,
- RejectOnBadData => 1,
);
=item C<%GnuPGOptions>
@@ -2204,9 +2547,6 @@ Set(%GnuPGOptions,
# URL of a keyserver
# keyserver => 'hkp://subkeys.pgp.net',
-# enables the automatic retrieving of keys when encrypting
-# 'auto-key-locate' => 'keyserver',
-
# enables the automatic retrieving of keys when verifying signatures
# 'keyserver-options' => 'auto-key-retrieve',
);
@@ -2348,6 +2688,14 @@ all possible transitions in each lifecycle using the following format:
...
},
+The order of items in the listing for each transition line affects
+the order they appear in the drop-down. If you change the config
+for 'open' state listing to:
+
+ open => [qw(stalled rejected deleted resolved)],
+
+then the 'resolved' status will appear as the last item in the drop-down.
+
=head3 Statuses available during ticket creation
By default users can create tickets with a status of new,
@@ -2450,8 +2798,8 @@ For example:
Unless there is an explicit mapping between statuses in two different
lifecycles, you can not move tickets between queues with these
-lifecycles. This is true even if the different lifecycles use the exact
-same set of statuses. Such a mapping is defined as follows:
+lifecycles -- even if both use the exact same set of statuses.
+Such a mapping is defined as follows:
__maps__ => {
'from lifecycle -> to lifecycle' => {
@@ -2465,9 +2813,9 @@ same set of statuses. Such a mapping is defined as follows:
Set(%Lifecycles,
default => {
- initial => [ 'new' ],
- active => [ 'open', 'stalled' ],
- inactive => [ 'resolved', 'rejected', 'deleted' ],
+ initial => [qw(new)], # loc_qw
+ active => [qw(open stalled)], # loc_qw
+ inactive => [qw(resolved rejected deleted)], # loc_qw
defaults => {
on_create => 'new',
@@ -2479,64 +2827,32 @@ Set(%Lifecycles,
},
transitions => {
- '' => [qw(new open resolved)],
+ "" => [qw(new open resolved)],
# from => [ to list ],
- new => [qw(open stalled resolved rejected deleted)],
- open => [qw(new stalled resolved rejected deleted)],
- stalled => [qw(new open rejected resolved deleted)],
- resolved => [qw(new open stalled rejected deleted)],
- rejected => [qw(new open stalled resolved deleted)],
- deleted => [qw(new open stalled rejected resolved)],
+ new => [qw( open stalled resolved rejected deleted)],
+ open => [qw(new stalled resolved rejected deleted)],
+ stalled => [qw(new open rejected resolved deleted)],
+ resolved => [qw(new open stalled rejected deleted)],
+ rejected => [qw(new open stalled resolved deleted)],
+ deleted => [qw(new open stalled rejected resolved )],
},
rights => {
'* -> deleted' => 'DeleteTicket',
'* -> *' => 'ModifyTicket',
},
actions => [
- 'new -> open' => {
- label => 'Open It', # loc
- update => 'Respond',
- },
- 'new -> resolved' => {
- label => 'Resolve', # loc
- update => 'Comment',
- },
- 'new -> rejected' => {
- label => 'Reject', # loc
- update => 'Respond',
- },
- 'new -> deleted' => {
- label => 'Delete', # loc
- },
-
- 'open -> stalled' => {
- label => 'Stall', # loc
- update => 'Comment',
- },
- 'open -> resolved' => {
- label => 'Resolve', # loc
- update => 'Comment',
- },
- 'open -> rejected' => {
- label => 'Reject', # loc
- update => 'Respond',
- },
-
- 'stalled -> open' => {
- label => 'Open It', # loc
- },
- 'resolved -> open' => {
- label => 'Re-open', # loc
- update => 'Comment',
- },
- 'rejected -> open' => {
- label => 'Re-open', # loc
- update => 'Comment',
- },
- 'deleted -> open' => {
- label => 'Undelete', # loc
- },
+ 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label}
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'new -> deleted' => { label => 'Delete', }, # loc{label}
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label}
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'stalled -> open' => { label => 'Open It', }, # loc{label}
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'deleted -> open' => { label => 'Undelete', }, # loc{label}
],
},
# don't change lifecyle of the approvals, they are not capable to deal with
@@ -2570,49 +2886,17 @@ Set(%Lifecycles,
'* -> *' => 'ModifyTicket',
},
actions => [
- 'new -> open' => {
- label => 'Open It', # loc
- update => 'Respond',
- },
- 'new -> resolved' => {
- label => 'Resolve', # loc
- update => 'Comment',
- },
- 'new -> rejected' => {
- label => 'Reject', # loc
- update => 'Respond',
- },
- 'new -> deleted' => {
- label => 'Delete', # loc
- },
-
- 'open -> stalled' => {
- label => 'Stall', # loc
- update => 'Comment',
- },
- 'open -> resolved' => {
- label => 'Resolve', # loc
- update => 'Comment',
- },
- 'open -> rejected' => {
- label => 'Reject', # loc
- update => 'Respond',
- },
-
- 'stalled -> open' => {
- label => 'Open It', # loc
- },
- 'resolved -> open' => {
- label => 'Re-open', # loc
- update => 'Comment',
- },
- 'rejected -> open' => {
- label => 'Re-open', # loc
- update => 'Comment',
- },
- 'deleted -> open' => {
- label => 'Undelete', # loc
- },
+ 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label}
+ 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'new -> deleted' => { label => 'Delete', }, # loc{label}
+ 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label}
+ 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label}
+ 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label}
+ 'stalled -> open' => { label => 'Open It', }, # loc{label}
+ 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label}
+ 'deleted -> open' => { label => 'Undelete', }, # loc{label}
],
},
);
@@ -2629,7 +2913,7 @@ Set(%Lifecycles,
RT can show administrators a feed of recent RT releases and other
related announcements and information from Best Practical on the top
-level Configuration page. This feature helps you stay up to date on
+level Admin page. This feature helps you stay up to date on
RT security announcements and version updates.
RT provides this feature using an "iframe" on C</Admin/index.html>
@@ -2637,7 +2921,7 @@ which asks the administrator's browser to show an inline page from
Best Practical's website.
If you'd rather not make this feature available to your
-administrators, set C<$ShowRTPortal> to a false value.
+administrators, set C<$ShowRTPortal> to 0.
=cut
@@ -2655,41 +2939,53 @@ Set(%AdminSearchResultFormat,
Queues =>
q{'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
- .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Disabled__,__Lifecycle__},
+ .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Lifecycle__,__SubjectTag__,__Disabled__},
Groups =>
q{'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
- .q{,'__Description__'},
+ .q{,'__Description__',__Disabled__},
Users =>
q{'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
- .q{,__RealName__, __EmailAddress__},
+ .q{,__RealName__, __EmailAddress__,__Disabled__},
CustomFields =>
q{'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
- .q{,__AppliedTo__, __FriendlyType__, __FriendlyPattern__},
+ .q{,__AddedTo__, __FriendlyType__, __FriendlyPattern__,__Disabled__},
Scrips =>
- q{'<a href="__WebPath__/Admin/Queues/Scrip.html?id=__id__&Queue=__QueueId__">__id__</a>/TITLE:#'}
- .q{,'<a href="__WebPath__/Admin/Queues/Scrip.html?id=__id__&Queue=__QueueId__">__Description__</a>/TITLE:Description'}
- .q{,__Stage__, __Condition__, __Action__, __Template__},
-
- GlobalScrips =>
- q{'<a href="__WebPath__/Admin/Global/Scrip.html?id=__id__">__id__</a>/TITLE:#'}
- .q{,'<a href="__WebPath__/Admin/Global/Scrip.html?id=__id__">__Description__</a>/TITLE:Description'}
- .q{,__Stage__, __Condition__, __Action__, __Template__},
+ q{'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__id__</a>/TITLE:#'}
+ .q{,'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__Description__</a>/TITLE:Description'}
+ .q{,__Condition__, __Action__, __Template__, __Disabled__},
Templates =>
q{'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__Name__</a>/TITLE:Name'}
- .q{,'__Description__'},
+ .q{,'__Description__','__UsedBy__','__IsEmpty__'},
Classes =>
q{ '<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__id__</a>/TITLE:#'}
.q{,'<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
- .q{,__Description__},
+ .q{,__Description__,__Disabled__},
+);
+
+=item C<%AdminSearchResultRows>
+
+Use C<%AdminSearchResultRows> to define the search result rows in the admin
+interface on a per-RT-class basis.
+
+=cut
+
+Set(%AdminSearchResultRows,
+ Queues => 50,
+ Groups => 50,
+ Users => 50,
+ CustomFields => 50,
+ Scrips => 50,
+ Templates => 50,
+ Classes => 50,
);
=back
@@ -2741,7 +3037,7 @@ be added while the server is running.
=cut
-Set($DevelMode, "@RT_DEVEL_MODE@");
+Set($DevelMode, 0);
=item C<$RecordBaseClass>
@@ -2777,7 +3073,7 @@ C<$StatementLog> to be the level that you wish SQL statements to be
logged at.
Enabling this option will also expose the SQL Queries page in the
-Configuration -> Tools menu for SuperUsers.
+Admin -> Tools menu for SuperUsers.
=cut
@@ -2785,30 +3081,6 @@ Set($StatementLog, undef);
=back
-
-
-
-=head1 Deprecated options
-
-=over 4
-
-=item C<$LinkTransactionsRun1Scrip>
-
-RT-3.4 backward compatibility setting. Add/Delete Link used to record
-one transaction and run one scrip. Set this value to 1 if you want
-only one of the link transactions to have scrips run.
-
-=cut
-
-Set($LinkTransactionsRun1Scrip, 0);
-
-=item C<$ResolveDefaultUpdateType>
-
-This option has been deprecated. You can configure this site-wide
-with L</Lifecycles> (see L</Labeling and defining actions>).
-
-=back
-
=cut
1;
diff --git a/rt/etc/RT_SiteConfig.pm b/rt/etc/RT_SiteConfig.pm
index 4a397fa16..daf136399 100644
--- a/rt/etc/RT_SiteConfig.pm
+++ b/rt/etc/RT_SiteConfig.pm
@@ -10,7 +10,7 @@
#
# The converse is also true, if this file isn't valid perl, you're
# going to run into trouble. To check your SiteConfig file, use
-# this comamnd:
+# this command:
#
# perl -c /path/to/your/etc/RT_SiteConfig.pm
diff --git a/rt/etc/acl.Pg b/rt/etc/acl.Pg
index 9da28dba7..a659d8e99 100755
--- a/rt/etc/acl.Pg
+++ b/rt/etc/acl.Pg
@@ -23,6 +23,8 @@ sub acl {
Transactions
scrips_id_seq
Scrips
+ objectscrips_id_seq
+ ObjectScrips
acl_id_seq
ACL
groupmembers_id_seq
@@ -64,17 +66,14 @@ sub acl {
# if there's already an rt_user, use it.
my @row = $dbh->selectrow_array( "SELECT usename FROM pg_user WHERE usename = '$db_user'" );
unless ( $row[0] ) {
- push @acls, "CREATE USER \"$db_user\" WITH PASSWORD '$db_pass' NOCREATEDB NOCREATEUSER;";
+ push @acls, "CREATE USER \"$db_user\" WITH PASSWORD '$db_pass' NOCREATEDB NOCREATEUSER;";
}
- my $sequence_right
- = ( $dbh->{pg_server_version} >= 80200 )
- ? "USAGE, SELECT, UPDATE"
- : "SELECT, UPDATE";
foreach my $table (@tables) {
if ( $table =~ /^[a-z]/ && $table ne 'sessions' ) {
-# table like objectcustomfields_id_s
- push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";"
+ # Sequences; not all end with _seq because
+ # objectcustomfieldvalues_id_s is too long
+ push @acls, "GRANT USAGE, SELECT, UPDATE ON $table TO \"$db_user\";"
}
else {
push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";"
diff --git a/rt/etc/acl.mysql b/rt/etc/acl.mysql
index 16882378e..26e27fbfb 100755
--- a/rt/etc/acl.mysql
+++ b/rt/etc/acl.mysql
@@ -5,15 +5,14 @@ sub acl {
my $db_user = RT->Config->Get('DatabaseUser');
my $db_pass = RT->Config->Get('DatabasePassword');
unless ( $db_user ) {
- print STDERR "DatabaseUser option is not defined or empty. Skipping...\n";
+ RT->Logger->warn("DatabaseUser option is not defined or empty. Skipping...");
return;
}
if ( $db_user eq 'root' ) {
- print STDERR "DatabaseUser is root. Skipping...\n";
+ RT->Logger->warn("DatabaseUser is root. Skipping...");
return;
}
- print "Granting access to $db_user\@'$db_rthost' on $db_name.\n";
- $db_name =~ s/([_%])/\\$1/g;
+ $db_name =~ s/([_%\\])/\\$1/g;
return (
"GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE
ON `$db_name`.*
diff --git a/rt/etc/initialdata b/rt/etc/initialdata
index a30110489..9b2af3744 100644
--- a/rt/etc/initialdata
+++ b/rt/etc/initialdata
@@ -58,7 +58,14 @@
Description => 'Sends mail to the administrative Ccs', # loc
ExecModule => 'Notify',
Argument => 'AdminCc' },
-
+ { Name => 'Notify Owner and AdminCcs', # loc
+ Description => 'Sends mail to the Owner and administrative Ccs', # loc
+ ExecModule => 'Notify',
+ Argument => 'Owner,AdminCc' },
+ { Name => 'Notify Owner or AdminCcs', # loc
+ Description => 'Sends mail to the Owner if set, otherwise administrative Ccs', # loc
+ ExecModule => 'NotifyOwnerOrAdminCc',
+ },
{ Name => 'Notify Requestors and Ccs as Comment', # loc
Description => 'Send mail to requestors and Ccs as a comment', # loc
ExecModule => 'NotifyAsComment',
@@ -99,10 +106,15 @@
{ Name => 'Open Tickets', # loc
Description => 'Open tickets on correspondence', # loc
ExecModule => 'AutoOpen' },
+ { Name => 'Open Inactive Tickets', # loc
+ Description => 'Open inactive tickets', # loc
+ ExecModule => 'AutoOpenInactive' },
{ Name => 'Extract Subject Tag', # loc
Description => 'Extract tags from a Transaction\'s subject and add them to the Ticket\'s subject.', # loc
ExecModule => 'ExtractSubjectTag' },
-
+ { Name => 'Send Forward', # loc
+ Description => 'Send forwarded message', # loc
+ ExecModule => 'SendForward', },
#freeside
{ Name => 'Set Priority',
Description => 'Set ticket priority',
@@ -255,7 +267,7 @@
Content => '', },
{ Queue => '0',
Name => 'Autoreply', # loc
- Description => 'Default Autoresponse template', # loc
+ Description => 'Plain text Autoresponse template', # loc
Content => 'Subject: AutoReply: {$Ticket->Subject}
@@ -263,7 +275,7 @@ Greetings,
This message has been automatically generated in response to the
creation of a trouble ticket regarding:
- "{$Ticket->Subject()}",
+ "{$Ticket->Subject()}",
a summary of which appears below.
There is no need to reply to this message right now. Your ticket has been
@@ -283,10 +295,35 @@ you may reply to this message.
{$Transaction->Content()}
'
},
+ { Queue => '0',
+ Name => 'Autoreply in HTML', # loc
+ Description => 'HTML Autoresponse template', # loc
+ Content => q[Subject: AutoReply: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>This message has been automatically generated in response to the
+creation of a trouble ticket regarding <b>{$Ticket->Subject()}</b>,
+a summary of which appears below.</p>
+
+<p>There is no need to reply to this message right now. Your ticket has been
+assigned an ID of <b>{$Ticket->SubjectTag}</b>.</p>
+
+<p>Please include the string <b>{$Ticket->SubjectTag}</b>
+in the subject line of all future correspondence about this issue. To do so,
+you may reply to this message.</p>
+<p>Thank you,<br/>
+{$Ticket->QueueObj->CorrespondAddress()}</p>
+
+<hr/>
+{$Transaction->Content(Type => 'text/html')}
+],
+ },
{ Queue => '0',
Name => 'Transaction', # loc
- Description => 'Default transaction template', # loc
+ Description => 'Plain text transaction template', # loc
Content => 'RT-Attach-Message: yes
@@ -303,12 +340,43 @@ you may reply to this message.
{$Transaction->Content()}
'
},
-
+ { Queue => '0',
+ Name => 'Transaction in HTML', # loc
+ Description => 'HTML transaction template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+
+<b>{$Transaction->CreatedAsString}: Request <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{$Ticket->id}</a> was acted upon by {$Transaction->CreatorObj->Name}.</b>
+<br>
+<table border="0">
+<tr><td align="right"><b>Transaction:</b></td><td>{$Transaction->Description}</td></tr>
+<tr><td align="right"><b>Queue:</b></td><td>{$Ticket->QueueObj->Name}</td></tr>
+<tr><td align="right"><b>Subject:</b></td><td>{$Transaction->Subject || $Ticket->Subject || "(No subject given)"} </td></tr>
+<tr><td align="right"><b>Owner:</b></td><td>{$Ticket->OwnerObj->Name}</td></tr>
+<tr><td align="right"><b>Requestors:</b></td><td>{$Ticket->RequestorAddresses}</td></tr>
+<tr><td align="right"><b>Status:</b></td><td>{$Ticket->Status}</td></tr>
+<tr><td align="right"><b>Ticket URL:</b></td><td><a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a></td></tr>
+</table>
+<br/>
+<br/>
+{$Transaction->Content( Type => "text/html")}
+'
+ },
+ # Shadow the global templates of the same name to suppress duplicate
+ # notifications until rules is ripped out.
+ { Queue => "___Approvals",
+ Name => "Transaction in HTML",
+ Content => "",
+ },
+ { Queue => "___Approvals",
+ Name => "Transaction",
+ Content => "",
+ },
{
Queue => '0',
Name => 'Admin Correspondence', # loc
- Description => 'Default admin correspondence template', # loc
+ Description => 'Plain text admin correspondence template', # loc
Content => 'RT-Attach-Message: yes
@@ -317,19 +385,38 @@ you may reply to this message.
{$Transaction->Content()}
'
},
+ { Queue => '0',
+ Name => 'Admin Correspondence in HTML', # loc
+ Description => 'HTML admin correspondence template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+Ticket URL: <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a>
+<br />
+<br />
+{$Transaction->Content(Type => "text/html");}
+'
+ },
{ Queue => '0',
Name => 'Correspondence', # loc
- Description => 'Default correspondence template', # loc
+ Description => 'Plain text correspondence template', # loc
Content => 'RT-Attach-Message: yes
{$Transaction->Content()}
'
},
+ { Queue => '0',
+ Name => 'Correspondence in HTML', # loc
+ Description => 'HTML correspondence template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+{$Transaction->Content( Type => "text/html")}
+'
+ },
{ Queue => '0',
Name => 'Admin Comment', # loc
- Description => 'Default admin comment template', # loc
+ Description => 'Plain text admin comment template', # loc
Content =>
'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject||""); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;}
RT-Attach-Message: yes
@@ -341,6 +428,30 @@ This is a comment. It is not sent to the Requestor(s):
{$Transaction->Content()}
'
},
+ { Queue => '0',
+ Name => 'Admin Comment in HTML', # loc
+ Description => 'HTML admin comment template', # loc
+ Content =>
+'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject||""); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;}
+RT-Attach-Message: yes
+Content-Type: text/html
+
+<p>This is a comment about <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">ticket {$Ticket->id}</a>. It is not sent to the Requestor(s):</p>
+
+{$Transaction->Content(Type => "text/html")}
+'
+ },
+ { Queue => '0',
+ Name => 'Reminder', # loc
+ Description => 'Default reminder template', # loc
+ Content =>
+'Subject:{$Ticket->Subject} is due {$Ticket->DueObj->AsString}
+
+This reminder is for ticket #{$Target = $Ticket->RefersTo->First->TargetObj;$Target->Id}.
+
+{RT->Config->Get(\'WebURL\')}Ticket/Display.html?id={$Target->Id}
+'
+ },
{ Queue => '0',
Name => 'Status Change', # loc
@@ -353,7 +464,18 @@ This is a comment. It is not sent to the Requestor(s):
{$Transaction->Content()}
'
},
+ { Queue => '0',
+ Name => 'Status Change in HTML', # loc
+ Description => 'HTML Ticket status changed', # loc
+ Content => 'Subject: Status Changed to: {$Transaction->NewValue}
+Content-Type: text/html
+<a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a>
+<br/>
+<br/>
+{$Transaction->Content(Type => "text/html")}
+'
+ },
{
Queue => '0',
@@ -365,6 +487,15 @@ According to our records, your request has been resolved. If you have any
further questions or concerns, please respond to this message.
'
},
+ { Queue => '0',
+ Name => 'Resolved in HTML', # loc
+ Description => 'HTML Ticket Resolved', # loc
+ Content => 'Subject: Resolved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message.</p>
+'
+ },
{ Queue => '___Approvals',
Name => "New Pending Approval", # loc
Description =>
@@ -385,6 +516,25 @@ batch-process all your pending approvals.
'
},
{ Queue => '___Approvals',
+ Name => "New Pending Approval in HTML", # loc
+ Description => "Notify Owners and AdminCcs of new items pending their approval", # loc
+ Content => 'Subject: New Pending Approval: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>There is a new item pending your approval: <b>{$Ticket->Subject()}</b>,
+a summary of which appears below.</p>
+
+<p>Please <a href="{RT->Config->Get(\'WebURL\')}Approvals/Display.html?id={$Ticket->id}">approve
+or reject this ticket</a>, or visit the <a href="{RT->Config->Get(\'WebURL\')}Approvals/">approvals
+overview</a> to batch-process all your pending approvals.</p>
+
+<hr />
+{$Transaction->Content()}
+'
+ },
+ { Queue => '___Approvals',
Name => "Approval Passed", # loc
Description =>
"Notify Requestor of their ticket has been approved by some approver", # loc
@@ -399,6 +549,22 @@ Approver\'s notes: { $Notes }
'
},
{ Queue => '___Approvals',
+ Name => "Approval Passed in HTML", # loc
+ Description =>
+ "Notify Requestor of their ticket has been approved by some approver", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>.
+Other approvals may be pending.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
Name => "All Approvals Passed", # loc
Description =>
"Notify Requestor of their ticket has been approved by all approvers", # loc
@@ -413,6 +579,22 @@ Approver\'s notes: { $Notes }
'
},
{ Queue => '___Approvals',
+ Name => "All Approvals Passed in HTML", # loc
+ Description =>
+ "Notify Requestor of their ticket has been approved by all approvers", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>.
+Its Owner may now start to act on it.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
Name => "Approval Rejected", # loc
Description =>
"Notify Owner of their rejected ticket", # loc
@@ -426,6 +608,21 @@ Approver\'s notes: { $Notes }
'
},
{ Queue => '___Approvals',
+ Name => "Approval Rejected in HTML", # loc
+ Description =>
+ "Notify Owner of their rejected ticket", # loc
+ Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been rejected by <b>{ eval { $Approver->Name } }</b>.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
Name => "Approval Ready for Owner", # loc
Description =>
"Notify Owner of their ticket has been approved and is ready to be acted on", # loc
@@ -437,19 +634,42 @@ The ticket has been approved, you may now start to act on it.
'
},
+ { Queue => '___Approvals',
+ Name => "Approval Ready for Owner in HTML", # loc
+ Description =>
+ "Notify Owner of their ticket has been approved and is ready to be acted on", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>The ticket has been approved, you may now start to act on it.</p>
+
+'
+ },
{ Queue => 0,
Name => "Forward", # loc
- Description => "Heading of a forwarded message", # loc
+ Description => "Forwarded message", # loc
Content => q{
-This is a forward of transaction #{$Transaction->id} of ticket #{ $Ticket->id }
+
+{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of transaction #".$Transaction->id." of ticket #". $Ticket->id }
}
},
{ Queue => 0,
Name => "Forward Ticket", # loc
- Description => "Heading of a forwarded Ticket", # loc
+ Description => "Forwarded ticket message", # loc
Content => q{
-This is a forward of ticket #{ $Ticket->id }
+{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of ticket #". $Ticket->id }
+}
+ },
+ { Queue => 0,
+ Name => "Error: unencrypted message", # loc
+ Description =>
+ "Inform user that their unencrypted mail has been rejected", # loc
+ Content => q{Subject: RT requires that all incoming mail be encrypted
+
+You received this message because RT received mail from you that was not encrypted. As such, it has been rejected.
}
},
{ Queue => 0,
@@ -487,12 +707,12 @@ Please, check that you encrypt messages with correct keys
or contact the system administrator.}
},
{ Queue => 0,
- Name => "Error: bad GnuPG data", # loc
+ Name => "Error: bad encrypted data", # loc
Description =>
- "Inform user that a message he sent has invalid GnuPG data", # loc
+ "Inform user that a message he sent has invalid encryption data", # loc
Content => q{Subject: We received a message we cannot handle
-You sent us a message that we cannot handle due to corrupted GnuPG signature or encrypted block. we get the following error(s):
+You sent us a message that we cannot handle due to corrupted signature or encrypted block. we get the following error(s):
{ foreach my $msg ( @Messages ) {
$OUT .= "* $msg\n";
}
@@ -513,10 +733,10 @@ Your new password is:
}
},
- { Queue => '0',
- Name => 'Email Digest', # loc
- Description => 'Email template for periodic notification digests', # loc
- Content => q[Subject: RT Email Digest
+ { Queue => '0',
+ Name => 'Email Digest', # loc
+ Description => 'Email template for periodic notification digests', # loc
+ Content => q[Subject: RT Email Digest
{ $Argument }
],
@@ -561,58 +781,66 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
);
@Scrips = (
- { Description => 'On Correspond Open Tickets',
- ScripCondition => 'On Correspond',
- ScripAction => 'Open Tickets',
- Template => 'Blank' },
- { Description => 'On Owner Change Notify Owner',
- ScripCondition => 'On Owner Change',
- ScripAction => 'Notify Owner',
- Template => 'Transaction' },
- { Description => 'On Create Autoreply To Requestors',
- ScripCondition => 'On Create',
- ScripAction => 'AutoReply To Requestors',
- Template => 'AutoReply' },
- { Description => 'On Create Notify AdminCcs',
- ScripCondition => 'On Create',
- ScripAction => 'Notify AdminCcs',
- Template => 'Transaction' },
- { Description => 'On Correspond Notify AdminCcs',
- ScripCondition => 'On Correspond',
- ScripAction => 'Notify AdminCcs',
- Template => 'Admin Correspondence' },
-# { Description => 'On Correspond Notify Requestors and Ccs',
-# ScripCondition => 'On Correspond',
-# ScripAction => 'Notify Requestors And Ccs',
-# Template => 'Correspondence' },
-# { Description => 'On Correspond Notify Other Recipients',
-# ScripCondition => 'On Correspond',
-# ScripAction => 'Notify Other Recipients',
-# Template => 'Correspondence' },
- { Description => 'On Correspond Notify Requestors, Ccs, and Other Recipients',
- ScripCondition => 'On Correspond',
- ScripAction => 'Notify Requestors, Ccs, and Other Recipients',
- Template => 'Correspondence', },
{ Description => 'On Comment Notify AdminCcs as Comment',
ScripCondition => 'On Comment',
ScripAction => 'Notify AdminCcs As Comment',
- Template => 'Admin Comment' },
+ Template => 'Admin Comment in HTML' },
{ Description => 'On Comment Notify Other Recipients as Comment',
ScripCondition => 'On Comment',
ScripAction => 'Notify Other Recipients As Comment',
- Template => 'Correspondence' },
+ Template => 'Correspondence in HTML' },
+ { Description => 'On Correspond Notify Owner and AdminCcs',
+ ScripCondition => 'On Correspond',
+ ScripAction => 'Notify Owner and AdminCcs',
+ Template => 'Admin Correspondence in HTML' },
+# { Description => 'On Correspond Notify Other Recipients',
+# ScripCondition => 'On Correspond',
+# ScripAction => 'Notify Other Recipients',
+# Template => 'Correspondence in HTML' },
+# { Description => 'On Correspond Notify Requestors and Ccs',
+# ScripCondition => 'On Correspond',
+# ScripAction => 'Notify Requestors And Ccs',
+# Template => 'Correspondence in HTML' },
+ { Description => 'On Correspond Open Inactive Tickets',
+ ScripCondition => 'On Correspond',
+ ScripAction => 'Open Inactive Tickets',
+ Template => 'Blank' },
+ { Description => 'On Create Autoreply To Requestors',
+ ScripCondition => 'On Create',
+ ScripAction => 'AutoReply To Requestors',
+ Template => 'AutoReply in HTML' },
+ { Description => 'On Create Notify Owner and AdminCcs',
+ ScripCondition => 'On Create',
+ ScripAction => 'Notify Owner and AdminCcs',
+ Template => 'Transaction in HTML' },
+ { Description => 'On Create Notify Ccs',
+ ScripCondition => 'On Create',
+ ScripAction => 'Notify Ccs',
+ Template => 'Correspondence in HTML' },
+ { Description => 'On Create Notify Other Recipients',
+ ScripCondition => 'On Create',
+ ScripAction => 'Notify Other Recipients',
+ Template => 'Correspondence in HTML' },
+ { Description => 'On Owner Change Notify Owner',
+ ScripCondition => 'On Owner Change',
+ ScripAction => 'Notify Owner',
+ Template => 'Transaction in HTML' },
{ Description => 'On Resolve Notify Requestors',
ScripCondition => 'On Resolve',
ScripAction => 'Notify Requestors',
- Template => 'Resolved' },
+ Template => 'Resolved in HTML' },
{ Description => "On transaction, add any tags in the transaction's subject to the ticket's subject",
ScripCondition => 'On Transaction',
ScripAction => 'Extract Subject Tag',
Template => 'Blank' },
- { Description => 'On Correspond, cancel future resolve',
- ScripCondition => 'On Correspond',
- ScripAction => 'Cancel Scheduled Resolve',
- Template => 'Blank' },
+ { Description => 'On Forward Transaction Send forwarded message',
+ ScripCondition => 'On Forward Transaction',
+ ScripAction => 'Send Forward',
+ Template => 'Forward' },
+ { Description => 'On Forward Ticket Send forwarded message',
+ ScripCondition => 'On Forward Ticket',
+ ScripAction => 'Send Forward',
+ Template => 'Forward Ticket' },
);
@ACL = (
@@ -666,7 +894,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
Name => 'HomepageSettings',
Description => 'HomepageSettings',
Content => {
- 'body' => # loc
+ 'body' => # loc_left_pair
[
{
type => 'system',
@@ -685,7 +913,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
name => 'QuickCreate' # loc
},
],
- 'summary' => # loc
+ 'sidebar' => # loc_left_pair
[
{
type => 'component',
diff --git a/rt/etc/schema.Pg b/rt/etc/schema.Pg
index ccd1ee531..25455be6a 100755
--- a/rt/etc/schema.Pg
+++ b/rt/etc/schema.Pg
@@ -63,7 +63,7 @@ CREATE TABLE Queues (
PRIMARY KEY (id)
);
-CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
+CREATE UNIQUE INDEX Queues1 ON Queues (LOWER(Name)) ;
@@ -144,8 +144,9 @@ CREATE TABLE Groups (
PRIMARY KEY (id)
);
-CREATE UNIQUE INDEX Groups1 ON Groups (Domain,Instance,Type,id, Name);
-CREATE INDEX Groups2 On Groups (Type, Instance, Domain);
+CREATE INDEX Groups1 ON Groups (LOWER(Domain), LOWER(Type), Instance);
+CREATE INDEX Groups2 ON Groups (LOWER(Domain), LOWER(Name), Instance);
+CREATE INDEX Groups3 On Groups (Instance);
@@ -225,14 +226,11 @@ CREATE TABLE Scrips (
Description varchar(255),
ScripCondition integer NOT NULL DEFAULT 0 ,
ScripAction integer NOT NULL DEFAULT 0 ,
- ConditionRules text NULL ,
- ActionRules text NULL ,
CustomIsApplicableCode text NULL ,
CustomPrepareCode text NULL ,
CustomCommitCode text NULL ,
- Stage varchar(32) NULL ,
- Queue integer NOT NULL DEFAULT 0 ,
- Template integer NOT NULL DEFAULT 0 ,
+ Disabled integer NOT NULL DEFAULT 0 ,
+ Template varchar(200) NOT NULL,
Creator integer NOT NULL DEFAULT 0 ,
Created TIMESTAMP NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
@@ -242,7 +240,24 @@ CREATE TABLE Scrips (
);
+CREATE SEQUENCE objectscrips_id_seq;
+
+CREATE TABLE ObjectScrips (
+ id INTEGER DEFAULT nextval('objectscrips_id_seq'),
+ Scrip integer NOT NULL,
+ Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' ,
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created TIMESTAMP NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated TIMESTAMP NULL ,
+ PRIMARY KEY (id)
+
+);
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
@@ -320,9 +335,9 @@ CREATE TABLE CachedGroupMembers (
);
-CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId);
-CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (GroupId);
-CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled);
+CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId, GroupId, Disabled);
+CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled);
+CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId,ImmediateParentId);
@@ -368,6 +383,7 @@ CREATE TABLE Users (
Country varchar(50) NULL ,
Timezone varchar(50) NULL ,
PGPKey text NULL,
+ SMIMECertificate text NULL,
Creator integer NOT NULL DEFAULT 0 ,
Created TIMESTAMP NULL ,
@@ -378,8 +394,7 @@ CREATE TABLE Users (
);
-CREATE UNIQUE INDEX Users1 ON Users (Name) ;
-CREATE INDEX Users3 ON Users (id, EmailAddress);
+CREATE UNIQUE INDEX Users1 ON Users (LOWER(Name)) ;
CREATE INDEX Users4 ON Users (EmailAddress);
@@ -398,6 +413,7 @@ CREATE SEQUENCE tickets_id_seq;
CREATE TABLE Tickets (
id INTEGER DEFAULT nextval('tickets_id_seq'),
EffectiveId integer NOT NULL DEFAULT 0 ,
+ IsMerged smallint NULL DEFAULT NULL ,
Queue integer NOT NULL DEFAULT 0 ,
Type varchar(16) NULL ,
IssueStatement integer NOT NULL DEFAULT 0 ,
@@ -431,13 +447,6 @@ CREATE TABLE Tickets (
CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
CREATE INDEX Tickets2 ON Tickets (Owner) ;
CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
-CREATE INDEX Tickets4 ON Tickets (id, Status) ;
-CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
-
-
-
-
-
--
@@ -478,8 +487,6 @@ CREATE TABLE Templates (
Name varchar(200) NOT NULL ,
Description varchar(255) NULL ,
Type varchar(16) NULL ,
- Language varchar(16) NULL ,
- TranslationOf integer NOT NULL DEFAULT 0 ,
Content text NULL ,
LastUpdated TIMESTAMP NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
@@ -543,7 +550,6 @@ CREATE TABLE CustomFields (
Type varchar(200) NULL ,
RenderType varchar(64) NULL ,
MaxValues integer NOT NULL DEFAULT 0 ,
- Repeated integer NOT NULL DEFAULT 0 ,
ValuesClass varchar(64) NULL ,
BasedOn integer NULL,
Pattern varchar(65536) NULL ,
diff --git a/rt/etc/schema.SQLite b/rt/etc/schema.SQLite
index 6897be2d6..c50e5b122 100644
--- a/rt/etc/schema.SQLite
+++ b/rt/etc/schema.SQLite
@@ -4,13 +4,13 @@ CREATE TABLE Attachments (
id INTEGER PRIMARY KEY ,
TransactionId INTEGER ,
Parent integer NULL DEFAULT 0 ,
- MessageId varchar(160) NULL ,
- Subject varchar(255) NULL ,
- Filename varchar(255) NULL ,
- ContentType varchar(80) NULL ,
- ContentEncoding varchar(80) NULL ,
- Content LONGTEXT NULL ,
- Headers LONGTEXT NULL ,
+ MessageId varchar(160) collate NOCASE NULL ,
+ Subject varchar(255) collate NOCASE NULL ,
+ Filename varchar(255) collate NOCASE NULL ,
+ ContentType varchar(80) collate NOCASE NULL ,
+ ContentEncoding varchar(80) collate NOCASE NULL ,
+ Content LONGTEXT collate NOCASE NULL ,
+ Headers LONGTEXT collate NOCASE NULL ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL
@@ -24,12 +24,12 @@ CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
--- {{{ Queues
CREATE TABLE Queues (
id INTEGER PRIMARY KEY ,
- Name varchar(200) NOT NULL ,
- Description varchar(255) NULL ,
- CorrespondAddress varchar(120) NULL ,
- CommentAddress varchar(120) NULL ,
- Lifecycle varchar(32) NULL ,
- SubjectTag varchar(120) NULL ,
+ Name varchar(200) collate NOCASE NOT NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ CorrespondAddress varchar(120) collate NOCASE NULL ,
+ CommentAddress varchar(120) collate NOCASE NULL ,
+ Lifecycle varchar(32) collate NOCASE NULL ,
+ SubjectTag varchar(120) collate NOCASE NULL ,
InitialPriority integer NULL DEFAULT 0 ,
FinalPriority integer NULL DEFAULT 0 ,
DefaultDueIn integer NULL DEFAULT 0 ,
@@ -48,9 +48,9 @@ CREATE UNIQUE INDEX Queues1 ON Queues (Name) ;
CREATE TABLE Links (
id INTEGER PRIMARY KEY ,
- Base varchar(240) NULL ,
- Target varchar(240) NULL ,
- Type varchar(20) NOT NULL ,
+ Base varchar(240) collate NOCASE NULL ,
+ Target varchar(240) collate NOCASE NULL ,
+ Type varchar(20) collate NOCASE NOT NULL ,
LocalTarget integer NULL DEFAULT 0 ,
LocalBase integer NULL DEFAULT 0 ,
LastUpdatedBy integer NULL DEFAULT 0 ,
@@ -68,7 +68,7 @@ CREATE INDEX Links4 ON Links(Type,LocalBase);
CREATE TABLE Principals (
id INTEGER PRIMARY KEY,
- PrincipalType VARCHAR(16) not null,
+ PrincipalType VARCHAR(16) collate NOCASE not null,
ObjectId integer,
Disabled int2 NOT NULL DEFAULT 0
@@ -80,10 +80,10 @@ CREATE TABLE Principals (
CREATE TABLE Groups (
id INTEGER ,
- Name varchar(200) NULL ,
- Description varchar(255) NULL ,
- Domain varchar(64),
- Type varchar(64),
+ Name varchar(200) collate NOCASE NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ Domain varchar(64) collate NOCASE,
+ Type varchar(64) collate NOCASE,
Instance integer,
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -92,7 +92,9 @@ CREATE TABLE Groups (
) ;
-CREATE UNIQUE INDEX Groups1 ON Groups (Name,Domain,Type,Instance) ;
+CREATE INDEX Groups1 ON Groups (Domain,Type,Instance);
+CREATE INDEX Groups2 ON Groups (Domain,Name,Instance);
+CREATE INDEX Groups3 ON Groups (Instance);
--- }}}
@@ -100,11 +102,11 @@ CREATE UNIQUE INDEX Groups1 ON Groups (Name,Domain,Type,Instance) ;
CREATE TABLE ScripConditions (
id INTEGER PRIMARY KEY ,
- Name varchar(200) NULL ,
- Description varchar(255) NULL ,
- ExecModule varchar(60) NULL ,
- Argument varchar(255) NULL ,
- ApplicableTransTypes varchar(60) NULL ,
+ Name varchar(200) collate NOCASE NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ ExecModule varchar(60) collate NOCASE NULL ,
+ Argument varchar(255) collate NOCASE NULL ,
+ ApplicableTransTypes varchar(60) collate NOCASE NULL ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -118,17 +120,17 @@ CREATE TABLE ScripConditions (
--- {{{ Transactions
CREATE TABLE Transactions (
id INTEGER PRIMARY KEY ,
- ObjectType varchar(255) NULL ,
+ ObjectType varchar(255) collate NOCASE NULL ,
ObjectId integer NULL DEFAULT 0 ,
TimeTaken integer NULL DEFAULT 0 ,
- Type varchar(20) NULL ,
- Field varchar(40) NULL ,
- OldValue varchar(255) NULL ,
- NewValue varchar(255) NULL ,
- ReferenceType varchar(255) NULL ,
+ Type varchar(20) collate NOCASE NULL ,
+ Field varchar(40) collate NOCASE NULL ,
+ OldValue varchar(255) collate NOCASE NULL ,
+ NewValue varchar(255) collate NOCASE NULL ,
+ ReferenceType varchar(255) collate NOCASE NULL ,
OldReference integer NULL ,
NewReference integer NULL ,
- Data varchar(255) NULL ,
+ Data varchar(255) collate NOCASE NULL ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL
@@ -142,17 +144,14 @@ CREATE INDEX Transactions1 ON Transactions (ObjectType, ObjectId);
CREATE TABLE Scrips (
id INTEGER PRIMARY KEY ,
- Description varchar(255),
+ Description varchar(255) collate NOCASE,
ScripCondition integer NULL DEFAULT 0 ,
ScripAction integer NULL DEFAULT 0 ,
- ConditionRules text NULL ,
- ActionRules text NULL ,
- CustomIsApplicableCode text NULL ,
- CustomPrepareCode text NULL ,
- CustomCommitCode text NULL ,
- Stage varchar(32) NULL ,
- Queue integer NULL DEFAULT 0 ,
- Template integer NULL DEFAULT 0 ,
+ CustomIsApplicableCode text collate NOCASE NULL ,
+ CustomPrepareCode text collate NOCASE NULL ,
+ CustomCommitCode text collate NOCASE NULL ,
+ Disabled int2 NOT NULL DEFAULT 0 ,
+ Template varchar(200) collate NOCASE NOT NULL ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL ,
LastUpdatedBy integer NULL DEFAULT 0 ,
@@ -162,14 +161,29 @@ CREATE TABLE Scrips (
--- }}}
+CREATE TABLE ObjectScrips (
+ id INTEGER NOT NULL ,
+ Scrip int NOT NULL ,
+ Stage varchar(32) collate NOCASE NOT NULL DEFAULT 'TransactionCreate' ,
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created DATETIME NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated DATETIME NULL ,
+ PRIMARY KEY (id)
+);
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
--- {{{ ACL
CREATE TABLE ACL (
id INTEGER PRIMARY KEY ,
- PrincipalType varchar(25) NOT NULL,
+ PrincipalType varchar(25) collate NOCASE NOT NULL,
PrincipalId INTEGER DEFAULT 0,
- RightName varchar(25) NOT NULL ,
- ObjectType varchar(25) NOT NULL ,
+ RightName varchar(25) collate NOCASE NOT NULL ,
+ ObjectType varchar(25) collate NOCASE NOT NULL ,
ObjectId INTEGER default 0,
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -194,6 +208,8 @@ CREATE TABLE GroupMembers (
) ;
+CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers(GroupId, MemberId);
+
--- }}}
--- {{{ CachedGroupMembers
@@ -213,42 +229,47 @@ create table CachedGroupMembers (
) ;
+CREATE INDEX CachedGroupMembers1 ON CachedGroupMembers (GroupId, MemberId, Disabled);
+CREATE INDEX CachedGroupMembers2 ON CachedGroupMembers (MemberId, GroupId, Disabled);
+CREATE INDEX CachedGroupMembers3 ON CachedGroupMembers (MemberId, ImmediateParentId);
+
--- }}}
--- {{{ Users
CREATE TABLE Users (
id INTEGER ,
- Name varchar(200) NOT NULL ,
- Password varchar(256) NULL ,
- AuthToken varchar(16) NULL ,
+ Name varchar(200) collate NOCASE NOT NULL ,
+ Password varchar(256) collate NOCASE NULL ,
+ AuthToken varchar(16) collate NOCASE NULL ,
Comments blob NULL ,
Signature blob NULL ,
- EmailAddress varchar(120) NULL ,
+ EmailAddress varchar(120) collate NOCASE NULL ,
FreeformContactInfo blob NULL ,
- Organization varchar(200) NULL ,
- RealName varchar(120) NULL ,
- NickName varchar(16) NULL ,
- Lang varchar(16) NULL ,
- EmailEncoding varchar(16) NULL ,
- WebEncoding varchar(16) NULL ,
- ExternalContactInfoId varchar(100) NULL ,
- ContactInfoSystem varchar(30) NULL ,
- ExternalAuthId varchar(100) NULL ,
- AuthSystem varchar(30) NULL ,
- Gecos varchar(16) NULL ,
- HomePhone varchar(30) NULL ,
- WorkPhone varchar(30) NULL ,
- MobilePhone varchar(30) NULL ,
- PagerPhone varchar(30) NULL ,
- Address1 varchar(200) NULL ,
- Address2 varchar(200) NULL ,
- City varchar(100) NULL ,
- State varchar(100) NULL ,
- Zip varchar(16) NULL ,
- Country varchar(50) NULL ,
+ Organization varchar(200) collate NOCASE NULL ,
+ RealName varchar(120) collate NOCASE NULL ,
+ NickName varchar(16) collate NOCASE NULL ,
+ Lang varchar(16) collate NOCASE NULL ,
+ EmailEncoding varchar(16) collate NOCASE NULL ,
+ WebEncoding varchar(16) collate NOCASE NULL ,
+ ExternalContactInfoId varchar(100) collate NOCASE NULL ,
+ ContactInfoSystem varchar(30) collate NOCASE NULL ,
+ ExternalAuthId varchar(100) collate NOCASE NULL ,
+ AuthSystem varchar(30) collate NOCASE NULL ,
+ Gecos varchar(16) collate NOCASE NULL ,
+ HomePhone varchar(30) collate NOCASE NULL ,
+ WorkPhone varchar(30) collate NOCASE NULL ,
+ MobilePhone varchar(30) collate NOCASE NULL ,
+ PagerPhone varchar(30) collate NOCASE NULL ,
+ Address1 varchar(200) collate NOCASE NULL ,
+ Address2 varchar(200) collate NOCASE NULL ,
+ City varchar(100) collate NOCASE NULL ,
+ State varchar(100) collate NOCASE NULL ,
+ Zip varchar(16) collate NOCASE NULL ,
+ Country varchar(50) collate NOCASE NULL ,
Timezone char(50) NULL ,
- PGPKey text NULL,
+ PGPKey text collate NOCASE NULL,
+ SMIMECertificate text collate NOCASE NULL,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -259,8 +280,6 @@ CREATE TABLE Users (
CREATE UNIQUE INDEX Users1 ON Users (Name) ;
-CREATE INDEX Users2 ON Users (Name);
-CREATE INDEX Users3 ON Users (id, EmailAddress);
CREATE INDEX Users4 ON Users (EmailAddress);
@@ -271,18 +290,19 @@ CREATE INDEX Users4 ON Users (EmailAddress);
CREATE TABLE Tickets (
id INTEGER PRIMARY KEY ,
EffectiveId integer NULL DEFAULT 0 ,
+ IsMerged int2 NULL DEFAULT NULL,
Queue integer NULL DEFAULT 0 ,
- Type varchar(16) NULL ,
+ Type varchar(16) collate NOCASE NULL ,
IssueStatement integer NULL DEFAULT 0 ,
Resolution integer NULL DEFAULT 0 ,
Owner integer NULL DEFAULT 0 ,
- Subject varchar(200) NULL DEFAULT '[no subject]' ,
+ Subject varchar(200) collate NOCASE NULL DEFAULT '[no subject]' ,
InitialPriority integer NULL DEFAULT 0 ,
FinalPriority integer NULL DEFAULt 0 ,
Priority integer NULL DEFAULT 0 ,
TimeEstimated integer NULL DEFAULT 0 ,
TimeWorked integer NULL DEFAULT 0 ,
- Status varchar(64) NULL ,
+ Status varchar(64) collate NOCASE NULL ,
TimeLeft integer NULL DEFAULT 0 ,
Told DATETIME NULL ,
Starts DATETIME NULL ,
@@ -302,8 +322,6 @@ CREATE TABLE Tickets (
CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
CREATE INDEX Tickets2 ON Tickets (Owner) ;
CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
-CREATE INDEX Tickets4 ON Tickets (id, Status) ;
-CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
--- }}}
@@ -311,10 +329,10 @@ CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ;
CREATE TABLE ScripActions (
id INTEGER PRIMARY KEY ,
- Name varchar(200) NULL ,
- Description varchar(255) NULL ,
- ExecModule varchar(60) NULL ,
- Argument varchar(255) NULL ,
+ Name varchar(200) collate NOCASE NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ ExecModule varchar(60) collate NOCASE NULL ,
+ Argument varchar(255) collate NOCASE NULL ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL ,
LastUpdatedBy integer NULL DEFAULT 0 ,
@@ -329,11 +347,9 @@ CREATE TABLE ScripActions (
CREATE TABLE Templates (
id INTEGER PRIMARY KEY ,
Queue integer NOT NULL DEFAULT 0 ,
- Name varchar(200) NOT NULL ,
- Description varchar(255) NULL ,
- Type varchar(16) NULL ,
- Language varchar(16) NULL ,
- TranslationOf integer NULL DEFAULT 0 ,
+ Name varchar(200) collate NOCASE NOT NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ Type varchar(16) collate NOCASE NULL ,
Content blob NULL ,
LastUpdated DATETIME NULL ,
LastUpdatedBy integer NULL DEFAULT 0 ,
@@ -350,14 +366,14 @@ CREATE TABLE Templates (
CREATE TABLE ObjectCustomFieldValues (
id INTEGER NOT NULL ,
CustomField int NOT NULL ,
- ObjectType varchar(255) NOT NULL, # Final target of the Object
- ObjectId int NOT NULL , # New -- Replaces Ticket
+ ObjectType varchar(255) collate NOCASE NOT NULL, # Final target of the Object
+ ObjectId int NOT NULL , # New -- Replaces Ticket
SortOrder integer NOT NULL DEFAULT 0 ,
- Content varchar(255) NULL ,
- LargeContent LONGTEXT NULL, # New -- to hold 255+ strings
- ContentType varchar(80) NULL, # New -- only text/* gets searched
- ContentEncoding varchar(80) NULL , # New -- for binary Content
+ Content varchar(255) collate NOCASE NULL ,
+ LargeContent LONGTEXT collate NOCASE NULL, # New -- to hold 255+ strings
+ ContentType varchar(80) collate NOCASE NULL, # New -- only text/* gets searched
+ ContentEncoding varchar(80) collate NOCASE NULL , # New -- for binary Content
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -374,17 +390,16 @@ CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,Ob
CREATE TABLE CustomFields (
id INTEGER NOT NULL ,
- Name varchar(200) NULL ,
- Type varchar(200) NULL , # Changed -- 'Single' and 'Multiple' is moved out
- RenderType varchar(64) NULL ,
- MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0)
- Pattern varchar(65536) NULL , # New -- Must validate against this
- Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry
+ Name varchar(200) collate NOCASE NULL ,
+ Type varchar(200) collate NOCASE NULL , # Changed -- 'Single' and 'Multiple' is moved out
+ RenderType varchar(64) collate NOCASE NULL ,
+ MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0)
+ Pattern varchar(65536) collate NOCASE NULL , # New -- Must validate against this
BasedOn INTEGER NULL,
- ValuesClass varchar(64) NULL ,
- Description varchar(255) NULL ,
+ ValuesClass varchar(64) collate NOCASE NULL ,
+ Description varchar(255) collate NOCASE NULL ,
SortOrder integer NOT NULL DEFAULT 0 ,
- LookupType varchar(255) NOT NULL,
+ LookupType varchar(255) collate NOCASE NOT NULL,
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -414,10 +429,10 @@ CREATE TABLE ObjectCustomFields (
CREATE TABLE CustomFieldValues (
id INTEGER NOT NULL ,
CustomField int NOT NULL ,
- Name varchar(200) NULL ,
- Description varchar(255) NULL ,
+ Name varchar(200) collate NOCASE NULL ,
+ Description varchar(255) collate NOCASE NULL ,
SortOrder integer NOT NULL DEFAULT 0 ,
- Category varchar(255) NULL ,
+ Category varchar(255) collate NOCASE NULL ,
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -432,11 +447,11 @@ CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField);
--- {{{ Attributes
CREATE TABLE Attributes (
id INTEGER PRIMARY KEY ,
- Name varchar(255) NOT NULL ,
- Description varchar(255) NULL ,
- Content LONGTEXT NULL ,
- ContentType varchar(16),
- ObjectType varchar(25) NOT NULL ,
+ Name varchar(255) collate NOCASE NOT NULL ,
+ Description varchar(255) collate NOCASE NULL ,
+ Content LONGTEXT collate NOCASE NULL ,
+ ContentType varchar(16) collate NOCASE,
+ ObjectType varchar(25) collate NOCASE NOT NULL ,
ObjectId INTEGER ,
Creator integer NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -451,8 +466,8 @@ CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId);
CREATE TABLE Classes (
id INTEGER PRIMARY KEY,
-Name varchar(255) NOT NULL DEFAULT '',
-Description varchar(255) NOT NULL DEFAULT '',
+Name varchar(255) collate NOCASE NOT NULL DEFAULT '',
+Description varchar(255) collate NOCASE NOT NULL DEFAULT '',
SortOrder integer NOT NULL DEFAULT 0,
Disabled smallint NOT NULL DEFAULT 0,
Creator integer NOT NULL DEFAULT 0,
@@ -464,12 +479,12 @@ HotList smallint NOT NULL DEFAULT 0
CREATE TABLE Articles (
id INTEGER PRIMARY KEY,
-Name varchar(255) NOT NULL DEFAULT '',
-Summary varchar(255) NOT NULL DEFAULT '',
+Name varchar(255) collate NOCASE NOT NULL DEFAULT '',
+Summary varchar(255) collate NOCASE NOT NULL DEFAULT '',
SortOrder integer NOT NULL DEFAULT 0,
Class integer NOT NULL DEFAULT 0,
Parent integer NOT NULL DEFAULT 0,
-URI varchar(255),
+URI varchar(255) collate NOCASE,
Creator integer NOT NULL DEFAULT 0,
Created TIMESTAMP NULL,
LastUpdatedBy integer NOT NULL DEFAULT 0,
@@ -480,9 +495,9 @@ LastUpdated TIMESTAMP NULL
CREATE TABLE Topics (
id INTEGER PRIMARY KEY,
Parent integer NOT NULL DEFAULT 0,
-Name varchar(255) NOT NULL DEFAULT '',
-Description varchar(255) NOT NULL DEFAULT '',
-ObjectType varchar(64) NOT NULL DEFAULT '',
+Name varchar(255) collate NOCASE NOT NULL DEFAULT '',
+Description varchar(255) collate NOCASE NOT NULL DEFAULT '',
+ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '',
ObjectId integer NOT NULL DEFAULT 0
);
@@ -490,14 +505,14 @@ ObjectId integer NOT NULL DEFAULT 0
CREATE TABLE ObjectTopics (
id INTEGER PRIMARY KEY,
Topic integer NOT NULL DEFAULT 0,
-ObjectType varchar(64) NOT NULL DEFAULT '',
+ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '',
ObjectId integer NOT NULL DEFAULT 0
);
CREATE TABLE ObjectClasses (
id INTEGER PRIMARY KEY,
Class integer NOT NULL DEFAULT 0,
-ObjectType varchar(64) NOT NULL DEFAULT '',
+ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '',
ObjectId integer NOT NULL DEFAULT 0,
Creator integer NOT NULL DEFAULT 0,
Created TIMESTAMP NULL,
diff --git a/rt/etc/schema.mysql b/rt/etc/schema.mysql
index e0ccecb52..da14e72ed 100644
--- a/rt/etc/schema.mysql
+++ b/rt/etc/schema.mysql
@@ -46,7 +46,7 @@ CREATE TABLE Links (
id INTEGER NOT NULL AUTO_INCREMENT,
Base varchar(240) NULL,
Target varchar(240) NULL,
- Type varchar(20) NOT NULL,
+ Type varchar(20) CHARACTER SET ascii NOT NULL ,
LocalTarget integer NOT NULL DEFAULT 0 ,
LocalBase integer NOT NULL DEFAULT 0 ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
@@ -54,7 +54,7 @@ CREATE TABLE Links (
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
PRIMARY KEY (id)
-) ENGINE=InnoDB CHARACTER SET ascii;
+) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX Links2 ON Links (Base, Type) ;
CREATE INDEX Links3 ON Links (Target, Type) ;
@@ -88,10 +88,9 @@ CREATE TABLE Groups (
PRIMARY KEY (id)
) ENGINE=InnoDB CHARACTER SET utf8;
-CREATE INDEX Groups1 ON Groups (Domain,Instance,Type,id);
-CREATE INDEX Groups2 On Groups (Type, Instance);
-
-
+CREATE INDEX Groups1 ON Groups (Domain, Type, Instance);
+CREATE INDEX Groups2 ON Groups (Domain, Name, Instance);
+CREATE INDEX Groups3 On Groups (Instance);
CREATE TABLE ScripConditions (
id INTEGER NOT NULL AUTO_INCREMENT,
@@ -137,14 +136,25 @@ CREATE TABLE Scrips (
Description varchar(255),
ScripCondition integer NOT NULL DEFAULT 0 ,
ScripAction integer NOT NULL DEFAULT 0 ,
- ConditionRules text NULL ,
- ActionRules text NULL ,
CustomIsApplicableCode text NULL ,
CustomPrepareCode text NULL ,
CustomCommitCode text NULL ,
- Stage varchar(32) CHARACTER SET ascii NULL ,
- Queue integer NOT NULL DEFAULT 0 ,
- Template integer NOT NULL DEFAULT 0 ,
+ Disabled int2 NOT NULL DEFAULT 0 ,
+ Template varchar(200) NOT NULL ,
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created DATETIME NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated DATETIME NULL ,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8;
+
+CREATE TABLE ObjectScrips (
+ id INTEGER NOT NULL AUTO_INCREMENT,
+ Scrip integer NOT NULL ,
+ Stage varchar(32) CHARACTER SET ascii NOT NULL DEFAULT 'TransactionCreate',
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
@@ -152,6 +162,7 @@ CREATE TABLE Scrips (
PRIMARY KEY (id)
) ENGINE=InnoDB CHARACTER SET utf8;
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
CREATE TABLE ACL (
id INTEGER NOT NULL AUTO_INCREMENT,
@@ -204,6 +215,7 @@ create table CachedGroupMembers (
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled);
+CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId, GroupId, Disabled);
CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId);
@@ -240,6 +252,7 @@ CREATE TABLE Users (
Country varchar(50) NULL ,
Timezone varchar(50) NULL ,
PGPKey text NULL,
+ SMIMECertificate text NULL,
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -258,6 +271,7 @@ CREATE INDEX Users4 ON Users (EmailAddress);
CREATE TABLE Tickets (
id INTEGER NOT NULL AUTO_INCREMENT,
EffectiveId integer NOT NULL DEFAULT 0 ,
+ IsMerged int2 NULL DEFAULT NULL,
Queue integer NOT NULL DEFAULT 0 ,
Type varchar(16) CHARACTER SET ascii NULL ,
IssueStatement integer NOT NULL DEFAULT 0 ,
@@ -313,8 +327,6 @@ CREATE TABLE Templates (
Name varchar(200) NOT NULL ,
Description varchar(255) NULL ,
Type varchar(16) CHARACTER SET ascii NULL ,
- Language varchar(16) CHARACTER SET ascii NULL ,
- TranslationOf integer NOT NULL DEFAULT 0 ,
Content TEXT NULL ,
LastUpdated DATETIME NULL ,
LastUpdatedBy integer NOT NULL DEFAULT 0 ,
@@ -328,14 +340,14 @@ CREATE TABLE Templates (
CREATE TABLE ObjectCustomFieldValues (
id INTEGER NOT NULL AUTO_INCREMENT,
CustomField int NOT NULL ,
- ObjectType varchar(255) CHARACTER SET ascii NOT NULL, # Final target of the Object
- ObjectId int NOT NULL , # New -- Replaces Ticket
+ ObjectType varchar(255) CHARACTER SET ascii 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
Content varchar(255) NULL ,
- LargeContent LONGBLOB NULL, # New -- to hold 255+ strings
- ContentType varchar(80) CHARACTER SET ascii NULL, # New -- only text/* gets searched
- ContentEncoding varchar(80) CHARACTER SET ascii NULL , # New -- for binary Content
+ LargeContent LONGBLOB NULL, # New -- to hold 255+ strings
+ ContentType varchar(80) CHARACTER SET ascii NULL, # New -- only text/* gets searched
+ ContentEncoding varchar(80) CHARACTER SET ascii NULL , # New -- for binary Content
Creator integer NOT NULL DEFAULT 0 ,
Created DATETIME NULL ,
@@ -353,11 +365,10 @@ CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,Ob
CREATE TABLE CustomFields (
id INTEGER NOT NULL AUTO_INCREMENT,
Name varchar(200) NULL ,
- Type varchar(200) CHARACTER SET ascii NULL , # Changed -- 'Single' and 'Multiple' is moved out
+ Type varchar(200) CHARACTER SET ascii NULL , # Changed -- 'Single' and 'Multiple' is moved out
RenderType varchar(64) CHARACTER SET ascii NULL ,
- MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0)
- Pattern TEXT NULL , # New -- Must validate against this
- Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry
+ MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0)
+ Pattern TEXT NULL , # New -- Must validate against this
BasedOn INTEGER NULL,
ValuesClass varchar(64) CHARACTER SET ascii NULL ,
Description varchar(255) NULL ,
diff --git a/rt/etc/upgrade/3.1.0/content b/rt/etc/upgrade/3.1.0/content
deleted file mode 100644
index 3117dafc5..000000000
--- a/rt/etc/upgrade/3.1.0/content
+++ /dev/null
@@ -1,2 +0,0 @@
-# nothing to do
-1;
diff --git a/rt/etc/upgrade/3.1.0/schema.Oracle b/rt/etc/upgrade/3.1.0/schema.Oracle
index a8aae18b5..8a3c14241 100644
--- a/rt/etc/upgrade/3.1.0/schema.Oracle
+++ b/rt/etc/upgrade/3.1.0/schema.Oracle
@@ -1,16 +1,16 @@
CREATE SEQUENCE ATTRIBUTES_seq;
CREATE TABLE Attributes (
- id NUMBER(11,0) PRIMARY KEY,
- Name VARCHAR2(255) NOT NULL,
- Description VARCHAR2(255),
- Content CLOB,
+ id NUMBER(11,0) PRIMARY KEY,
+ Name VARCHAR2(255) NOT NULL,
+ Description VARCHAR2(255),
+ Content CLOB,
ContentType VARCHAR(16),
- ObjectType VARCHAR2(25) NOT NULL,
- ObjectId NUMBER(11,0) DEFAULT 0 NOT NULL,
- Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
- Created DATE,
- LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
- LastUpdated DATE
+ ObjectType VARCHAR2(25) NOT NULL,
+ ObjectId NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
);
CREATE INDEX Attributes1 on Attributes(Name);
diff --git a/rt/etc/upgrade/3.1.15/content b/rt/etc/upgrade/3.1.15/content
index d23125a0b..9e4b25320 100644
--- a/rt/etc/upgrade/3.1.15/content
+++ b/rt/etc/upgrade/3.1.15/content
@@ -1,4 +1,7 @@
-@Scrips = (
+use strict;
+use warnings;
+
+our @Scrips = (
{ ScripCondition => 'On Owner Change',
ScripAction => 'Notify Owner',
Template => 'Transaction' },
diff --git a/rt/etc/upgrade/3.1.17/content b/rt/etc/upgrade/3.1.17/content
index 1d648d82f..a6b5c542d 100644
--- a/rt/etc/upgrade/3.1.17/content
+++ b/rt/etc/upgrade/3.1.17/content
@@ -1,4 +1,7 @@
-@ScripActions = (
+use strict;
+use warnings;
+
+our @ScripActions = (
{ Name => 'Notify Ccs as Comment', # loc
Description => 'Sends mail to the Ccs as a comment', # loc
ExecModule => 'NotifyAsComment',
@@ -10,7 +13,7 @@
);
-@ScripConditions = (
+our @ScripConditions = (
{
Name => 'On Priority Change', # loc
Description => 'Whenever a ticket\'s priority changes', # loc
diff --git a/rt/etc/upgrade/3.3.0/content b/rt/etc/upgrade/3.3.0/content
deleted file mode 100644
index 0afc6045c..000000000
--- a/rt/etc/upgrade/3.3.0/content
+++ /dev/null
@@ -1 +0,0 @@
-1;
diff --git a/rt/etc/upgrade/3.3.11/content b/rt/etc/upgrade/3.3.11/content
deleted file mode 100644
index 0afc6045c..000000000
--- a/rt/etc/upgrade/3.3.11/content
+++ /dev/null
@@ -1 +0,0 @@
-1;
diff --git a/rt/etc/upgrade/3.5.1/content b/rt/etc/upgrade/3.5.1/content
index 02d6a0cac..59f9dfd2c 100644
--- a/rt/etc/upgrade/3.5.1/content
+++ b/rt/etc/upgrade/3.5.1/content
@@ -1,4 +1,7 @@
-@Attributes = (
+use strict;
+use warnings;
+
+our @Attributes = (
{ Name => 'Search - My Tickets',
Description => '[_1] highest priority tickets I own',
Content =>
@@ -19,16 +22,16 @@
Description => 'HomepageSettings',
Content =>
{ 'body' =>
- [ { type => 'system', name => 'My Tickets' },
- { type => 'system', name => 'Unowned Tickets' },
- { type => 'component', name => 'QuickCreate'},
- ],
+ [ { type => 'system', name => 'My Tickets' },
+ { type => 'system', name => 'Unowned Tickets' },
+ { type => 'component', name => 'QuickCreate'},
+ ],
'summary' =>
- [
- { type => 'component', name => 'MyReminders' },
+ [
+ { type => 'component', name => 'MyReminders' },
{ type => 'component', name => 'Quicksearch' },
- { type => 'component', name => 'RefreshHomepage' },
- ]
+ { type => 'component', name => 'RefreshHomepage' },
+ ]
},
}
);
diff --git a/rt/etc/upgrade/3.7.1/content b/rt/etc/upgrade/3.7.1/content
index fdd506144..e39ef8a95 100644
--- a/rt/etc/upgrade/3.7.1/content
+++ b/rt/etc/upgrade/3.7.1/content
@@ -1,4 +1,7 @@
-@ScripConditions = (
+use strict;
+use warnings;
+
+our @ScripConditions = (
{ Name => 'On Close', # loc
Description => 'Whenever a ticket is closed', # loc
ApplicableTransTypes => 'Status,Set',
diff --git a/rt/etc/upgrade/3.7.10/content b/rt/etc/upgrade/3.7.10/content
index d19f9e6fa..fd4628de9 100644
--- a/rt/etc/upgrade/3.7.10/content
+++ b/rt/etc/upgrade/3.7.10/content
@@ -1,5 +1,8 @@
+use strict;
+use warnings;
-@Templates = (
+
+our @Templates = (
{ Queue => 0,
Name => "Error: public key", # loc
Description =>
diff --git a/rt/etc/upgrade/3.7.15/content b/rt/etc/upgrade/3.7.15/content
index 9d97c356c..a3a27fdf7 100644
--- a/rt/etc/upgrade/3.7.15/content
+++ b/rt/etc/upgrade/3.7.15/content
@@ -1,5 +1,8 @@
+use strict;
+use warnings;
-@Templates = (
+
+our @Templates = (
{ Queue => 0,
Name => "Forward", # loc
Description => "Heading of a forwarded message", # loc
diff --git a/rt/etc/upgrade/3.7.19/content b/rt/etc/upgrade/3.7.19/content
index ff43dd053..34af55095 100644
--- a/rt/etc/upgrade/3.7.19/content
+++ b/rt/etc/upgrade/3.7.19/content
@@ -1,26 +1,28 @@
-
-{ use strict;
-add_description_to_all_scrips();
-
-sub add_description_to_all_scrips {
- require RT::Scrips;
- my $scrips = RT::Scrips->new( RT->SystemUser );
- $scrips->Limit( FIELD => 'Description', OPERATOR => 'IS', VALUE => 'NULL' );
- $scrips->Limit( FIELD => 'Description', VALUE => '' );
- while ( my $scrip = $scrips->Next ) {
- my $desc = $scrip->Description;
- next if defined $desc && length $desc;
-
- $desc = gen_scrip_description( $scrip );
-
- my ($status, $msg) = $scrip->SetDescription( $desc );
- unless ( $status ) {
- print STDERR "Couldn't set description of a scrip: $msg";
- } else {
- print "Added description to scrip #". $scrip->id ."\n";
+use strict;
+use warnings;
+
+our @Final = (
+ sub {
+ require RT::Scrips;
+ my $scrips = RT::Scrips->new( RT->SystemUser );
+ $scrips->{'with_disabled_column'} = 0;
+ $scrips->Limit( FIELD => 'Description', OPERATOR => 'IS', VALUE => 'NULL' );
+ $scrips->Limit( FIELD => 'Description', VALUE => '' );
+ while ( my $scrip = $scrips->Next ) {
+ my $desc = $scrip->Description;
+ next if defined $desc && length $desc;
+
+ $desc = gen_scrip_description( $scrip );
+
+ my ($status, $msg) = $scrip->SetDescription( $desc );
+ unless ( $status ) {
+ print STDERR "Couldn't set description of a scrip: $msg";
+ } else {
+ print "Added description to scrip #". $scrip->id ."\n";
+ }
}
- }
-}
+ },
+);
sub gen_scrip_description {
my $scrip = shift;
@@ -29,7 +31,7 @@ sub gen_scrip_description {
eval{
$condition = $scrip->ConditionObj->Name
|| $scrip->ConditionObj->Description
- || ('On Condition #'. $scrip->Condition);
+ || ('On Condition #'. $scrip->Condition);
};
if ($@){
@@ -42,7 +44,6 @@ sub gen_scrip_description {
|| $scrip->ActionObj->Description
|| ('Run Action #'. $scrip->Action);
return join ' ', $condition, $action;
- }
}
1;
diff --git a/rt/etc/upgrade/3.7.82/content b/rt/etc/upgrade/3.7.82/content
index a1c555f78..da406c4cf 100644
--- a/rt/etc/upgrade/3.7.82/content
+++ b/rt/etc/upgrade/3.7.82/content
@@ -1,4 +1,7 @@
-@Attributes = (
+use strict;
+use warnings;
+
+our @Attributes = (
{ Name => 'Search - Bookmarked Tickets',
Description => 'Bookmarked Tickets', #loc
Content =>
diff --git a/rt/etc/upgrade/3.7.85/content b/rt/etc/upgrade/3.7.85/content
index 49ab2860f..e9ec15c10 100644
--- a/rt/etc/upgrade/3.7.85/content
+++ b/rt/etc/upgrade/3.7.85/content
@@ -1,9 +1,12 @@
-@Templates = (
-
- { Queue => '0',
- Name => 'Email Digest', # loc
- Description => 'Email template for periodic notification digests', # loc
- Content => q[Subject: RT Email Digest
+use strict;
+use warnings;
+
+our @Templates = (
+
+ { Queue => '0',
+ Name => 'Email Digest', # loc
+ Description => 'Email template for periodic notification digests', # loc
+ Content => q[Subject: RT Email Digest
{ $Argument }
],
diff --git a/rt/etc/upgrade/3.7.86/content b/rt/etc/upgrade/3.7.86/content
index 94912d626..029939db5 100644
--- a/rt/etc/upgrade/3.7.86/content
+++ b/rt/etc/upgrade/3.7.86/content
@@ -1,13 +1,16 @@
-@Final = (
+use strict;
+use warnings;
+
+our @Final = (
sub {
- $RT::Logger->debug("Adding search for bookmarked tickets to defaults");
+ RT->Logger->debug("Adding search for bookmarked tickets to defaults");
my $sys = RT::System->new(RT->SystemUser);
my $attrs = RT::Attributes->new( RT->SystemUser );
$attrs->LimitToObject( $sys );
my ($attr) = $attrs->Named( 'HomepageSettings' );
unless ($attr) {
- $RT::Logger->error("You have no global home page settings");
+ RT->Logger->error("You have no global home page settings");
return;
}
my $content = $attr->Content;
@@ -15,9 +18,9 @@
{ type => 'system', name => 'Bookmarked Tickets' };
my ($status, $msg) = $attr->SetContent( $content );
- $RT::Logger->error($msg) unless $status;
+ RT->Logger->error($msg) unless $status;
- $RT::Logger->debug("done.");
+ RT->Logger->debug("done.");
return 1;
},
);
diff --git a/rt/etc/upgrade/3.7.87/content b/rt/etc/upgrade/3.7.87/content
index 0c677c4a1..c67feb406 100644
--- a/rt/etc/upgrade/3.7.87/content
+++ b/rt/etc/upgrade/3.7.87/content
@@ -1,4 +1,7 @@
-@Templates = (
+use strict;
+use warnings;
+
+our @Templates = (
{
Queue => 0,
Name => "Error: Missing dashboard", # loc
diff --git a/rt/etc/upgrade/3.8-ical-extension.in b/rt/etc/upgrade/3.8-ical-extension.in
index 89e5191e7..928888fa2 100644
--- a/rt/etc/upgrade/3.8-ical-extension.in
+++ b/rt/etc/upgrade/3.8-ical-extension.in
@@ -46,16 +46,16 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
+use RT -init;
-use RT;
-RT::LoadConfig();
-RT::Init();
+$| = 1;
use RT::Attributes;
my $attrs = RT::Attributes->new( RT->SystemUser );
diff --git a/rt/etc/upgrade/3.8.0/content b/rt/etc/upgrade/3.8.0/content
index 4fa5ac7d8..ae3a9fc0b 100644
--- a/rt/etc/upgrade/3.8.0/content
+++ b/rt/etc/upgrade/3.8.0/content
@@ -1,21 +1,24 @@
-@Final = (
+use strict;
+use warnings;
+
+our @Final = (
# by incident we've changed 'My Bookmarks' to 'Bookmarked Tickets' when
# 3.7.82 upgrade script still was creating 'My Bookmarks', try to fix it
sub {
- $RT::Logger->debug("Going to rename 'My Bookmarks' to 'Bookmarked Tickets'");
+ RT->Logger->debug("Going to rename 'My Bookmarks' to 'Bookmarked Tickets'");
my $sys = RT::System->new(RT->SystemUser);
my $attrs = RT::Attributes->new( RT->SystemUser );
$attrs->LimitToObject( $sys );
my ($attr) = $attrs->Named( 'Search - My Bookmarks' );
unless ($attr) {
- $RT::Logger->debug("You have no global search 'My Bookmarks'. Skipped.");
+ RT->Logger->debug("You have no global search 'My Bookmarks'. Skipped.");
return 1;
}
my ($status, $msg) = $attr->SetName( 'Search - Bookmarked Tickets' );
- $RT::Logger->error($msg) and return undef unless $status;
+ RT->Logger->error($msg) and return undef unless $status;
- $RT::Logger->debug("Renamed.");
+ RT->Logger->debug("Renamed.");
return 1;
},
);
diff --git a/rt/etc/upgrade/3.8.1/content b/rt/etc/upgrade/3.8.1/content
index 1667efa78..08c64306f 100644
--- a/rt/etc/upgrade/3.8.1/content
+++ b/rt/etc/upgrade/3.8.1/content
@@ -1,22 +1,25 @@
-@Final = (
+use strict;
+use warnings;
+
+our @Final = (
sub {
- $RT::Logger->debug("Going to adjust 'Bookmarked Tickets'");
+ RT->Logger->debug("Going to adjust 'Bookmarked Tickets'");
my $sys = RT::System->new(RT->SystemUser);
my $attrs = RT::Attributes->new( RT->SystemUser );
$attrs->LimitToObject( $sys );
my ($attr) = $attrs->Named( 'Search - Bookmarked Tickets' );
unless ($attr) {
- $RT::Logger->debug("You have no global search 'Bookmarked Tickets'. Skipped.");
+ RT->Logger->debug("You have no global search 'Bookmarked Tickets'. Skipped.");
return 1;
}
my $props = $attr->Content;
$props->{'Query'} =~ s/__Bookmarks__/id = '__Bookmarked__'/g;
my ($status, $msg) = $attr->SetContent( $props );
- $RT::Logger->error($msg) and return undef unless $status;
+ RT->Logger->error($msg) and return undef unless $status;
- $RT::Logger->debug("Fixed.");
+ RT->Logger->debug("Fixed.");
return 1;
},
);
diff --git a/rt/etc/upgrade/3.8.2/content b/rt/etc/upgrade/3.8.2/content
index 0eef401b8..dc68c9273 100644
--- a/rt/etc/upgrade/3.8.2/content
+++ b/rt/etc/upgrade/3.8.2/content
@@ -1,6 +1,19 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ # We do the delete in pure SQL because Attribute collections
+ # otherwise attempt to hash everything in memory. As this may
+ # be a large list, do it directly.
+ RT->DatabaseHandle->dbh->do(<<EOSQL);
+ DELETE FROM Attributes
+ WHERE Name = 'DeferredRecipients'
+ AND Content IS NULL;
+EOSQL
+ },
sub {
- $RT::Logger->warning(
+ RT->Logger->warning(
"Going to add [OLD] prefix to all templates in approvals queue."
." If you have never used approvals, you can safely delete all the"
." templates with the [OLD] prefix. Leave the new Approval templates because"
@@ -10,7 +23,7 @@
my $approvals_q = RT::Queue->new( RT->SystemUser );
$approvals_q->Load('___Approvals');
unless ( $approvals_q->id ) {
- $RT::Logger->error("You have no approvals queue.");
+ RT->Logger->error("You have no approvals queue.");
return 1;
}
@@ -19,19 +32,32 @@
while ( my $tmpl = $templates->Next ) {
my ($status, $msg) = $tmpl->SetName( "[OLD] ". $tmpl->Name );
unless ( $status ) {
- $RT::Logger->error("Couldn't rename template #". $tmpl->id .": $msg");
+ RT->Logger->error("Couldn't rename template #". $tmpl->id .": $msg");
}
}
return 1;
},
-);
-@ACL = (
- { GroupDomain => 'SystemInternal',
- GroupType => 'privileged',
- Right => 'ShowApprovalsTab', },
+
+ sub {
+ my $group = RT::Group->new( RT->SystemUser );
+ $group->DBIx::SearchBuilder::Record::LoadByCols(
+ Domain => 'SystemInternal',
+ Type => 'Privileged',
+ );
+ unless ($group->id) {
+ RT->Logger->warn("Failed to load Privilged group");
+ return;
+ }
+ my ( $return, $msg ) = $group->PrincipalObj->GrantRight(
+ Right => 'ShowApprovalsTab',
+ Object => RT->System,
+ );
+ RT->Logger->warn("Failed to grant ShowApprovalsTab right: $msg")
+ unless $return;
+ },
);
-@Templates = (
+our @Templates = (
{ Queue => '___Approvals',
Name => "New Pending Approval", # loc
Description =>
@@ -106,17 +132,17 @@ The ticket has been approved, you may now start to act on it.
},
);
-@Final = (
+our @Final = (
sub {
- $RT::Logger->debug("Going to adjust dashboards");
+ RT->Logger->debug("Going to adjust dashboards");
my $sys = RT::System->new(RT->SystemUser);
my $attrs = RT::Attributes->new( RT->SystemUser );
- $attrs->UnLimit;
+ $attrs->Limit( FIELD => "Name", VALUE => "Dashboard");
my @dashboards = $attrs->Named('Dashboard');
if (@dashboards == 0) {
- $RT::Logger->debug("You have no dashboards. Skipped.");
+ RT->Logger->debug("You have no dashboards. Skipped.");
return 1;
}
@@ -140,28 +166,28 @@ The ticket has been approved, you may now start to act on it.
};
}
my ($status, $msg) = $attr->SetContent( $props );
- $RT::Logger->error($msg) unless $status;
+ RT->Logger->error($msg) unless $status;
}
- $RT::Logger->debug("Fixed.");
+ RT->Logger->debug("Fixed.");
return 1;
},
sub {
my $approvals_q = RT::Queue->new( RT->SystemUser );
$approvals_q->Load('___Approvals');
unless ( $approvals_q->id ) {
- $RT::Logger->error("You have no approvals queue.");
+ RT->Logger->error("You have no approvals queue.");
return 1;
}
require File::Temp;
my ($tmp_fh, $tmp_fn) = File::Temp::tempfile( 'rt-approvals-scrips-XXXX', CLEANUP => 0 );
unless ( $tmp_fh ) {
- $RT::Logger->error("Couldn't create temporary file.");
+ RT->Logger->error("Couldn't create temporary file.");
return 0;
}
- $RT::Logger->warning(
+ RT->Logger->warning(
"IMPORTANT: We're going to delete all scrips in Approvals queue"
." and save them in '$tmp_fn' file."
);
@@ -169,17 +195,20 @@ The ticket has been approved, you may now start to act on it.
require Data::Dumper;
my $scrips = RT::Scrips->new( RT->SystemUser );
- $scrips->LimitToQueue( $approvals_q->id );
+ $scrips->{'with_disabled_column'} = 0;
+ $scrips->Limit( FIELD => 'Queue', VALUE => $approvals_q->id );
while ( my $scrip = $scrips->Next ) {
my %tmp =
- map { $tmp->{ $_ } = $scrip->_Value( $_ ) }
- $scrip->ReadableAttributes;
+ map { $_ => $scrip->_Value( $_ ) }
+ qw/id Description ScripCondition ScripAction
+ CustomIsApplicableCode CustomPrepareCode CustomCommitCode
+ Stage Queue Template Creator Created LastUpdatedBy LastUpdated/;
print $tmp_fh Data::Dumper::Dumper( \%tmp );
- my ($status, $msg) = $scrip->Delete;
+ my ($status, $msg) = $scrip->DBIx::SearchBuilder::Record::Delete;
unless ( $status ) {
- $RT::Logger->error( "Couldn't delete scrip: $msg");
+ RT->Logger->error( "Couldn't delete scrip: $msg");
}
}
},
diff --git a/rt/etc/upgrade/3.8.3/content b/rt/etc/upgrade/3.8.3/content
index b8052acde..3147c87e2 100644
--- a/rt/etc/upgrade/3.8.3/content
+++ b/rt/etc/upgrade/3.8.3/content
@@ -1,4 +1,7 @@
-@ScripConditions = (
+use strict;
+use warnings;
+
+our @ScripConditions = (
{ Name => 'On Reject', # loc
Description => 'Whenever a ticket is rejected', # loc
ApplicableTransTypes => 'Status',
@@ -8,9 +11,9 @@
},
);
-@Final = (
+our @Final = (
sub {
- $RT::Logger->debug("Going to correct descriptions of notify actions in the DB");
+ RT->Logger->debug("Going to correct descriptions of notify actions in the DB");
my $actions = RT::ScripActions->new( RT->SystemUser );
$actions->Limit(
@@ -23,11 +26,11 @@
);
while ( my $action = $actions->Next ) {
my ($status, $msg) = $action->__Set( Field => 'Name', Value => 'Notify Owner, Requestors, Ccs and AdminCcs' );
- $RT::Logger->warning( "Couldn't change action name: $msg" )
+ RT->Logger->warning( "Couldn't change action name: $msg" )
unless $status;
($status, $msg) = $action->__Set( Field => 'Description', Value => 'Send mail to owner and all watchers' );
- $RT::Logger->warning( "Couldn't change action description: $msg" )
+ RT->Logger->warning( "Couldn't change action description: $msg" )
unless $status;
}
@@ -42,24 +45,24 @@
);
while ( my $action = $actions->Next ) {
my ($status, $msg) = $action->__Set( Field => 'Name', Value => 'Notify Owner, Requestors, Ccs and AdminCcs as Comment' );
- $RT::Logger->warning( "Couldn't change action name: $msg" )
+ RT->Logger->warning( "Couldn't change action name: $msg" )
unless $status;
($status, $msg) = $action->__Set( Field => 'Description', Value => 'Send mail to owner and all watchers as a "comment"' );
- $RT::Logger->warning( "Couldn't change action description: $msg" )
+ RT->Logger->warning( "Couldn't change action description: $msg" )
unless $status;
}
- $RT::Logger->debug("Corrected descriptions of notify actions in the DB.");
+ RT->Logger->debug("Corrected descriptions of notify actions in the DB.");
return 1;
},
);
-
+our (@ScripActions, @Scrips);
{
-$RT::Logger->debug("Going to add in Extract Subject Tag actions if they were missed during a previous upgrade");
+RT->Logger->debug("Going to add in Extract Subject Tag actions if they were missed during a previous upgrade");
-$actions = RT::ScripActions->new( RT->SystemUser );
+my $actions = RT::ScripActions->new( RT->SystemUser );
$actions->Limit(
FIELD => 'ExecModule',
VALUE => 'ExtractSubjectTag',
@@ -67,10 +70,10 @@ $actions->Limit(
my $extract_action = $actions->First;
if ( $extract_action && $extract_action->Id ) {
- $RT::Logger->debug("You appear to already have an Extract Subject Tag action, skipping");
+ RT->Logger->debug("You appear to already have an Extract Subject Tag action, skipping");
return 1;
} else {
- $RT::Logger->debug("Didn't find an existing Extract Subject Tag action, adding it");
+ RT->Logger->debug("Didn't find an existing Extract Subject Tag action, adding it");
push @ScripActions, (
{ Name => 'Extract Subject Tag', # loc
Description => 'Extract tags from a Transaction\'s subject and add them to the Ticket\'s subject.', # loc
@@ -78,14 +81,24 @@ if ( $extract_action && $extract_action->Id ) {
},
);
- $RT::Logger->debug("Adding Extract Subject Tag Scrip");
- push @Scrips, (
- { Description => "On transaction, add any tags in the transaction's subject to the ticket's subject",
- ScripCondition => 'On Transaction',
- ScripAction => 'Extract Subject Tag',
- Template => 'Blank'
- },
- );
+ RT->Logger->debug("Adding Extract Subject Tag Scrip");
+ push @Final, sub {
+ my $action = RT::ScripAction->new( RT->SystemUser );
+ $action->Load( 'Extract Subject Tag' );
+ my $condition = RT::ScripCondition->new( RT->SystemUser );
+ $condition->Load( 'On Transaction' );
+ my $template = RT::Template->new( RT->SystemUser );
+ $template->LoadByName( Name => 'Blank', Queue => 0 );
+ my $scrip = RT::Scrip->new( RT->SystemUser );
+ $scrip->RT::Record::Create(
+ Description => "On transaction, add any tags in the transaction's subject to the ticket's subject",
+ ScripCondition => $condition->id,
+ ScripAction => $action->id,
+ Template => $template->id,
+ Stage => 'TransactionCreate',
+ Queue => 0,
+ );
+ };
}
}
diff --git a/rt/etc/upgrade/3.8.4/content b/rt/etc/upgrade/3.8.4/content
index 14ecba461..ac490d3e1 100644
--- a/rt/etc/upgrade/3.8.4/content
+++ b/rt/etc/upgrade/3.8.4/content
@@ -1,8 +1,10 @@
+use strict;
+use warnings;
-@Final = (
+
+our @Final = (
sub {
- $RT::Logger->debug("Going to correct arguments of NotifyGroup actions if you have any");
- use strict;
+ RT->Logger->debug("Going to correct arguments of NotifyGroup actions if you have any");
my $actions = RT::ScripActions->new( RT->SystemUser );
$actions->Limit(
@@ -50,7 +52,7 @@
next if $new eq $argument;
my ($status, $msg) = $action->__Set( Field => 'Argument', Value => $new );
- $RT::Logger->warning( "Couldn't change argument value of the action: $msg" )
+ RT->Logger->warning( "Couldn't change argument value of the action: $msg" )
unless $status;
}
},
diff --git a/rt/etc/upgrade/3.8.6/content b/rt/etc/upgrade/3.8.6/content
index a9793c6e1..3651a663c 100644
--- a/rt/etc/upgrade/3.8.6/content
+++ b/rt/etc/upgrade/3.8.6/content
@@ -1,4 +1,7 @@
-@Templates = (
+use strict;
+use warnings;
+
+our @Templates = (
{ Queue => 0,
Name => "Forward Ticket", # loc
Description => "Heading of a forwarded Ticket", # loc
diff --git a/rt/etc/upgrade/3.8.8/content b/rt/etc/upgrade/3.8.8/content
index cad77e948..50b331441 100644
--- a/rt/etc/upgrade/3.8.8/content
+++ b/rt/etc/upgrade/3.8.8/content
@@ -1,4 +1,7 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
# make sure global CFs are not applied to local objects
my $ocfs = RT::ObjectCustomFields->new( RT->SystemUser );
@@ -15,7 +18,7 @@
},
sub {
# sort SortOrder
- my $sth = $RT::Handle->dbh->prepare(
+ my $sth = RT->DatabaseHandle->dbh->prepare(
"SELECT cfs.LookupType, ocfs.id"
." FROM ObjectCustomFields ocfs, CustomFields cfs"
." WHERE cfs.id = ocfs.CustomField"
@@ -29,7 +32,7 @@
my $ocf = RT::ObjectCustomField->new( RT->SystemUser );
$ocf->Load( $id );
my ($status, $msg) = $ocf->SetSortOrder( $i++ );
- $RT::Logger->warning("Couldn't set SortOrder: $msg")
+ RT->Logger->warning("Couldn't set SortOrder: $msg")
unless $status;
$prev_type = $lt;
}
diff --git a/rt/etc/upgrade/3.8.9/content b/rt/etc/upgrade/3.8.9/content
index d7d64f599..d0a251648 100644
--- a/rt/etc/upgrade/3.8.9/content
+++ b/rt/etc/upgrade/3.8.9/content
@@ -1,7 +1,9 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- use strict;
- $RT::Logger->debug('Make sure local links are local');
+ RT->Logger->debug('Make sure local links are local');
use RT::URI::fsck_com_rt;
my $prefix = RT::URI::fsck_com_rt->LocalURIPrefix . '/ticket/';
@@ -53,7 +55,7 @@
# there is only one OwnerObj->Name normally, so no need /g
if ( $content =~
-s!(?<=Your ticket has been (?:approved|rejected) by { eval { )\$Approval->OwnerObj->Name!\$Approver->Name!
+s!(?<=Your ticket has been (?:approved|rejected) by \{ eval \{ )\$Approval->OwnerObj->Name!\$Approver->Name!
)
{
$template->SetType('Perl');
diff --git a/rt/etc/upgrade/3.9.1/content b/rt/etc/upgrade/3.9.1/content
index acdc0adb7..3e35f47cf 100644
--- a/rt/etc/upgrade/3.9.1/content
+++ b/rt/etc/upgrade/3.9.1/content
@@ -1,7 +1,9 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- use strict;
- $RT::Logger->debug('Make sure templates all have known types');
+ RT->Logger->debug('Make sure templates all have known types');
# We update all NULL rows, below. We want to find non-NULL
# rows, which weren't created by the current codebase running
@@ -26,12 +28,11 @@
);
while (my $template = $templates->Next) {
my ($status, $msg) = $template->SetType('Perl');
- $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status;
+ RT->Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status;
}
},
sub {
- use strict;
- $RT::Logger->debug('Adding ExecuteCode right to principals that currently have ModifyTemplate or ModifyScrips');
+ RT->Logger->debug('Adding ExecuteCode right to principals that currently have ModifyTemplate or ModifyScrips');
my $acl = RT::ACL->new(RT->SystemUser);
$acl->Limit(
@@ -60,7 +61,7 @@
);
if (!$ok) {
- $RT::Logger->warn("Unable to grant ExecuteCode on principal " . $principal->id . ": $msg");
+ RT->Logger->warn("Unable to grant ExecuteCode on principal " . $principal->id . ": $msg");
}
}
},
diff --git a/rt/etc/upgrade/3.9.2/content b/rt/etc/upgrade/3.9.2/content
index d0dbbfd0a..1851a9e99 100644
--- a/rt/etc/upgrade/3.9.2/content
+++ b/rt/etc/upgrade/3.9.2/content
@@ -1,7 +1,9 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- use strict;
- $RT::Logger->debug('Removing all delegated rights');
+ RT->Logger->debug('Removing all delegated rights');
my $acl = RT::ACL->new(RT->SystemUser);
$acl->Limit( CLAUSE => 'search',
@@ -20,7 +22,7 @@
my ( $ok, $msg ) = $ace->Delete();
if ( !$ok ) {
- $RT::Logger->warn(
+ RT->Logger->warn(
"Unable to delete ACE " . $ace->id . ": " . $msg );
}
}
@@ -28,14 +30,15 @@
my $groups = RT::Groups->new(RT->SystemUser);
$groups->Limit( FIELD => 'Domain',
OPERATOR => '=',
- VALUE => 'Personal'
+ VALUE => 'Personal',
+ CASESENSITIVE => 0,
);
while ( my $group = $groups->Next ) {
my $members = $group->MembersObj();
while ( my $member = $members->Next ) {
my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId );
if ( !$ok ) {
- $RT::Logger->warn( "Unable to remove group member "
+ RT->Logger->warn( "Unable to remove group member "
. $member->id . ": "
. $msg );
}
diff --git a/rt/etc/upgrade/3.9.3/schema.Oracle b/rt/etc/upgrade/3.9.3/schema.Oracle
index 4ee50c446..6ca1bdf58 100644
--- a/rt/etc/upgrade/3.9.3/schema.Oracle
+++ b/rt/etc/upgrade/3.9.3/schema.Oracle
@@ -1,2 +1 @@
-ALTER TABLE ACL DROP COLUMN DelegatedBy;
-ALTER TABLE ACL DROP COLUMN DelegatedFrom;
+ALTER TABLE ACL DROP( DelegatedBy, DelegatedFrom );
diff --git a/rt/etc/upgrade/3.9.3/schema.Pg b/rt/etc/upgrade/3.9.3/schema.Pg
index 4ee50c446..9b34ac78e 100644
--- a/rt/etc/upgrade/3.9.3/schema.Pg
+++ b/rt/etc/upgrade/3.9.3/schema.Pg
@@ -1,2 +1,3 @@
-ALTER TABLE ACL DROP COLUMN DelegatedBy;
-ALTER TABLE ACL DROP COLUMN DelegatedFrom;
+ALTER TABLE ACL
+ DROP COLUMN DelegatedBy,
+ DROP COLUMN DelegatedFrom;
diff --git a/rt/etc/upgrade/3.9.3/schema.mysql b/rt/etc/upgrade/3.9.3/schema.mysql
index 4ee50c446..9b34ac78e 100644
--- a/rt/etc/upgrade/3.9.3/schema.mysql
+++ b/rt/etc/upgrade/3.9.3/schema.mysql
@@ -1,2 +1,3 @@
-ALTER TABLE ACL DROP COLUMN DelegatedBy;
-ALTER TABLE ACL DROP COLUMN DelegatedFrom;
+ALTER TABLE ACL
+ DROP COLUMN DelegatedBy,
+ DROP COLUMN DelegatedFrom;
diff --git a/rt/etc/upgrade/3.9.5/backcompat b/rt/etc/upgrade/3.9.5/backcompat
index 611ab5186..ca0b289c9 100644
--- a/rt/etc/upgrade/3.9.5/backcompat
+++ b/rt/etc/upgrade/3.9.5/backcompat
@@ -1 +1,15 @@
-RT::ACE LastUpdated LastUpdatedBy Creator Created
+my ($upgrade) = @_;
+
+my %removed;
+my @fields = qw/LastUpdated LastUpdatedBy Creator Created/;
+
+RT::ACE->_BuildTableAttributes;
+$RT::Logger->debug("Temporarily removing @fields from RT::ACE");
+$removed{$_} = delete $RT::Record::_TABLE_ATTR->{"RT::ACE"}{$_}
+ for @fields;
+
+$upgrade->();
+
+# Put back the fields we chopped off
+$RT::Record::_TABLE_ATTR->{"RT::ACE"}{$_} = $removed{$_}
+ for @fields;
diff --git a/rt/etc/upgrade/3.9.5/schema.Oracle b/rt/etc/upgrade/3.9.5/schema.Oracle
index 065776dfb..bcf5b1f08 100644
--- a/rt/etc/upgrade/3.9.5/schema.Oracle
+++ b/rt/etc/upgrade/3.9.5/schema.Oracle
@@ -6,15 +6,21 @@ AND CustomFieldValues.id = Attributes.ObjectId);
DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue';
-ALTER TABLE Groups ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE Groups ADD Created DATE;
-ALTER TABLE Groups ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE Groups ADD LastUpdated DATE;
-ALTER TABLE GroupMembers ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE GroupMembers ADD Created DATE;
-ALTER TABLE GroupMembers ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE GroupMembers ADD LastUpdated DATE;
-ALTER TABLE ACL ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE ACL ADD Created DATE;
-ALTER TABLE ACL ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL;
-ALTER TABLE ACL ADD LastUpdated DATE;
+ALTER TABLE Groups ADD(
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
+ALTER TABLE GroupMembers ADD(
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
+ALTER TABLE ACL ADD(
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
diff --git a/rt/etc/upgrade/3.9.5/schema.Pg b/rt/etc/upgrade/3.9.5/schema.Pg
index cea2c4410..cd9190113 100644
--- a/rt/etc/upgrade/3.9.5/schema.Pg
+++ b/rt/etc/upgrade/3.9.5/schema.Pg
@@ -6,15 +6,18 @@ AND CustomFieldValues.id = Attributes.ObjectId);
DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue';
-ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0;
-ALTER TABLE Groups ADD COLUMN Created TIMESTAMP NULL;
-ALTER TABLE Groups ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0;
-ALTER TABLE Groups ADD COLUMN LastUpdated TIMESTAMP NULL;
-ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0;
-ALTER TABLE GroupMembers ADD COLUMN Created TIMESTAMP NULL;
-ALTER TABLE GroupMembers ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0;
-ALTER TABLE GroupMembers ADD COLUMN LastUpdated TIMESTAMP NULL;
-ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0;
-ALTER TABLE ACL ADD COLUMN Created TIMESTAMP NULL;
-ALTER TABLE ACL ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0;
-ALTER TABLE ACL ADD COLUMN LastUpdated TIMESTAMP NULL;
+ALTER TABLE Groups
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ ADD COLUMN Created TIMESTAMP NULL,
+ ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
+ ADD COLUMN LastUpdated TIMESTAMP NULL;
+ALTER TABLE GroupMembers
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ ADD COLUMN Created TIMESTAMP NULL,
+ ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
+ ADD COLUMN LastUpdated TIMESTAMP NULL;
+ALTER TABLE ACL
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ ADD COLUMN Created TIMESTAMP NULL,
+ ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
+ ADD COLUMN LastUpdated TIMESTAMP NULL;
diff --git a/rt/etc/upgrade/3.9.5/schema.mysql b/rt/etc/upgrade/3.9.5/schema.mysql
index fe5018c78..83f2f4087 100644
--- a/rt/etc/upgrade/3.9.5/schema.mysql
+++ b/rt/etc/upgrade/3.9.5/schema.mysql
@@ -6,15 +6,18 @@ AND CustomFieldValues.id = Attributes.ObjectId);
DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue';
-ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ALTER TABLE Groups
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
ADD COLUMN Created DATETIME NULL,
ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
ADD COLUMN LastUpdated DATETIME NULL;
-ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ALTER TABLE GroupMembers
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
ADD COLUMN Created DATETIME NULL,
ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
ADD COLUMN LastUpdated DATETIME NULL;
-ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0,
+ALTER TABLE ACL
+ ADD COLUMN Creator integer NOT NULL DEFAULT 0,
ADD COLUMN Created DATETIME NULL,
ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0,
ADD COLUMN LastUpdated DATETIME NULL;
diff --git a/rt/etc/upgrade/3.9.7/content b/rt/etc/upgrade/3.9.7/content
index 504ddf18f..9b48b4b51 100644
--- a/rt/etc/upgrade/3.9.7/content
+++ b/rt/etc/upgrade/3.9.7/content
@@ -1,24 +1,27 @@
+use strict;
+use warnings;
+
my $move_attributes = sub {
my ($table, $type, $column) = @_;
my $query = "UPDATE $table SET $column = (SELECT Content FROM Attributes WHERE"
." Name = ? AND ObjectType = ? AND $table.id = Attributes.ObjectId)";
- my $res = $RT::Handle->SimpleQuery( $query, $column, $type );
+ my $res = RT->DatabaseHandle->SimpleQuery( $query, $column, $type );
unless ( $res ) {
- $RT::Logger->error("Failed to move $column on $type from Attributes into $table table");
+ RT->Logger->error("Failed to move $column on $type from Attributes into $table table");
return;
}
$query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?';
- $res = $RT::Handle->SimpleQuery( $query, $column, $type );
+ $res = RT->DatabaseHandle->SimpleQuery( $query, $column, $type );
unless ( $res ) {
- $RT::Logger->error("Failed to delete $column on $type from Attributes");
+ RT->Logger->error("Failed to delete $column on $type from Attributes");
return;
}
return 1;
};
-@Initial = (
+our @Initial = (
sub {
return $move_attributes->( 'Users', 'RT::User', 'AuthToken');
},
@@ -26,7 +29,7 @@ my $move_attributes = sub {
return $move_attributes->( 'CustomFields', 'RT::CustomField', 'RenderType');
},
sub {
- my $cfs = RT::CustomFields->new($RT::SystemUser);
+ my $cfs = RT::CustomFields->new( RT->SystemUser );
$cfs->UnLimit;
$cfs->FindAllRows;
while ( my $cf = $cfs->Next ) {
@@ -39,10 +42,10 @@ my $move_attributes = sub {
next unless $attr;
$cf->SetBasedOn($attr->Content);
}
- $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?';
- $res = $RT::Handle->SimpleQuery( $query, 'BasedOn', 'RT::CustomField' );
+ my $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?';
+ my $res = RT->DatabaseHandle->SimpleQuery( $query, 'BasedOn', 'RT::CustomField' );
unless ( $res ) {
- $RT::Logger->error("Failed to delete BasedOn CustomFields from Attributes");
+ RT->Logger->error("Failed to delete BasedOn CustomFields from Attributes");
return;
}
return 1;
@@ -52,9 +55,9 @@ my $move_attributes = sub {
or return;
my $query = "UPDATE CustomFields SET ValuesClass = NULL WHERE ValuesClass = ?";
- my $res = $RT::Handle->SimpleQuery( $query, 'RT::CustomFieldValues' );
+ my $res = RT->DatabaseHandle->SimpleQuery( $query, 'RT::CustomFieldValues' );
unless ( $res ) {
- $RT::Logger->error("Failed to replace default with NULLs");
+ RT->Logger->error("Failed to replace default with NULLs");
return;
}
return 1;
@@ -68,13 +71,13 @@ my $move_attributes = sub {
my $queue = RT::Queue->new( RT->SystemUser );
$queue->Load( $qid );
unless ( $queue->id ) {
- $RT::Logger->warning("Couldn't load queue #$qid. Skipping...");
+ RT->Logger->warning("Couldn't load queue #$qid. Skipping...");
next;
}
my ($status, $msg) = $queue->SetSubjectTag($tag);
unless ( $status ) {
- $RT::Logger->error("Couldn't set subject tag for queue #$qid: $msg");
+ RT->Logger->error("Couldn't set subject tag for queue #$qid: $msg");
next;
}
}
diff --git a/rt/etc/upgrade/3.9.7/schema.Oracle b/rt/etc/upgrade/3.9.7/schema.Oracle
index 3c75c917d..70b4a12f9 100644
--- a/rt/etc/upgrade/3.9.7/schema.Oracle
+++ b/rt/etc/upgrade/3.9.7/schema.Oracle
@@ -1,6 +1,12 @@
ALTER TABLE Users ADD AuthToken VARCHAR2(16) NULL;
-ALTER TABLE CustomFields ADD BasedOn NUMBER(11,0) NULL;
-ALTER TABLE CustomFields ADD RenderType VARCHAR2(64) NULL;
-ALTER TABLE CustomFields ADD ValuesClass VARCHAR2(64) NULL;
-ALTER TABLE Queues ADD SubjectTag VARCHAR2(120) NULL;
-ALTER TABLE Queues ADD Lifecycle VARCHAR2(32) NULL;
+
+ALTER TABLE CustomFields ADD(
+ BasedOn NUMBER(11,0) NULL,
+ RenderType VARCHAR2(64) NULL,
+ ValuesClass VARCHAR2(64) NULL
+);
+
+ALTER TABLE Queues ADD(
+ SubjectTag VARCHAR2(120) NULL,
+ Lifecycle VARCHAR2(32) NULL
+);
diff --git a/rt/etc/upgrade/3.9.7/schema.Pg b/rt/etc/upgrade/3.9.7/schema.Pg
index 1704fa673..d6fe7cca6 100644
--- a/rt/etc/upgrade/3.9.7/schema.Pg
+++ b/rt/etc/upgrade/3.9.7/schema.Pg
@@ -1,6 +1,10 @@
ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) NULL;
-ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL;
-ALTER TABLE CustomFields ADD COLUMN RenderType VARCHAR(64) NULL;
-ALTER TABLE CustomFields ADD COLUMN ValuesClass VARCHAR(64) NULL;
-ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL;
-ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL;
+
+ALTER TABLE CustomFields
+ ADD COLUMN BasedOn INTEGER NULL,
+ ADD COLUMN RenderType VARCHAR(64) NULL,
+ ADD COLUMN ValuesClass VARCHAR(64) NULL;
+
+ALTER TABLE Queues
+ ADD COLUMN SubjectTag VARCHAR(120) NULL,
+ ADD COLUMN Lifecycle VARCHAR(32) NULL;
diff --git a/rt/etc/upgrade/3.9.7/schema.mysql b/rt/etc/upgrade/3.9.7/schema.mysql
index 4cbed6cc7..0e61d6422 100644
--- a/rt/etc/upgrade/3.9.7/schema.mysql
+++ b/rt/etc/upgrade/3.9.7/schema.mysql
@@ -1,6 +1,10 @@
ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) CHARACTER SET ascii NULL;
-ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL,
+
+ALTER TABLE CustomFields
+ ADD COLUMN BasedOn INTEGER NULL,
ADD COLUMN RenderType VARCHAR(64) NULL,
ADD COLUMN ValuesClass VARCHAR(64) CHARACTER SET ascii NULL;
-ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL,
+
+ALTER TABLE Queues
+ ADD COLUMN SubjectTag VARCHAR(120) NULL,
ADD COLUMN Lifecycle VARCHAR(32) NULL;
diff --git a/rt/etc/upgrade/3.9.8/content b/rt/etc/upgrade/3.9.8/content
index 24242fda2..e9a1a324d 100644
--- a/rt/etc/upgrade/3.9.8/content
+++ b/rt/etc/upgrade/3.9.8/content
@@ -1,4 +1,7 @@
-@Initial = sub {
+use strict;
+use warnings;
+
+our @Initial = sub {
my $found_fm_tables = {};
foreach my $name ( $RT::Handle->_TableNames ) {
next unless $name =~ /^fm_/i;
@@ -8,15 +11,15 @@
return unless %$found_fm_tables;
unless ( $found_fm_tables->{fm_topics} && $found_fm_tables->{fm_objecttopics} ) {
- $RT::Logger->error("You appear to be upgrading from RTFM 2.0 - We don't support upgrading this old of an RTFM yet");
+ RT->Logger->error("You appear to be upgrading from RTFM 2.0 - We don't support upgrading this old of an RTFM yet");
}
- $RT::Logger->error("We found RTFM tables in your database. Checking for content.");
+ RT->Logger->error("We found RTFM tables in your database. Checking for content.");
my $dbh = $RT::Handle->dbh;
my $result = $dbh->selectall_arrayref("SELECT count(*) AS articlecount FROM FM_Articles", { Slice => {} } );
if ($result->[0]{articlecount} > 0) {
- $RT::Logger->error("You appear to have RTFM Articles. You can upgrade using the etc/upgrade/upgrade-articles script. Read more about it in docs/UPGRADING-4.0");
+ RT->Logger->error("You appear to have RTFM Articles. You can upgrade using the /opt/rt4/etc/upgrade/upgrade-articles script. Read more about it in docs/UPGRADING-4.0");
}
};
diff --git a/rt/etc/upgrade/3.9.8/schema.Pg b/rt/etc/upgrade/3.9.8/schema.Pg
index d12e27a73..1f56d3b41 100644
--- a/rt/etc/upgrade/3.9.8/schema.Pg
+++ b/rt/etc/upgrade/3.9.8/schema.Pg
@@ -1,3 +1,4 @@
+DROP TABLE IF EXISTS Classes;
CREATE TABLE Classes (
id SERIAL,
Name varchar(255) NOT NULL DEFAULT '',
@@ -12,6 +13,7 @@ HotList smallint NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
+DROP TABLE IF EXISTS Articles;
CREATE TABLE Articles (
id SERIAL,
Name varchar(255) NOT NULL DEFAULT '',
@@ -28,6 +30,7 @@ PRIMARY KEY (id)
);
+DROP TABLE IF EXISTS Topics;
CREATE TABLE Topics (
id SERIAL,
Parent integer NOT NULL DEFAULT 0,
@@ -39,6 +42,7 @@ PRIMARY KEY (id)
);
+DROP TABLE IF EXISTS ObjectTopics;
CREATE TABLE ObjectTopics (
id SERIAL,
Topic integer NOT NULL,
@@ -48,6 +52,7 @@ PRIMARY KEY (id)
);
+DROP TABLE IF EXISTS ObjectClasses;
CREATE TABLE ObjectClasses (
id SERIAL,
Class integer NOT NULL,
diff --git a/rt/etc/upgrade/3.9.8/schema.SQLite b/rt/etc/upgrade/3.9.8/schema.SQLite
index 29ed7e87a..b5af93686 100644
--- a/rt/etc/upgrade/3.9.8/schema.SQLite
+++ b/rt/etc/upgrade/3.9.8/schema.SQLite
@@ -1,3 +1,4 @@
+DROP TABLE IF EXISTS Classes;
CREATE TABLE Classes (
id INTEGER PRIMARY KEY,
Name varchar(255) NOT NULL DEFAULT '',
@@ -11,6 +12,7 @@ LastUpdated TIMESTAMP NULL,
HotList smallint NOT NULL DEFAULT 0
);
+DROP TABLE IF EXISTS Articles;
CREATE TABLE Articles (
id INTEGER PRIMARY KEY,
Name varchar(255) NOT NULL DEFAULT '',
@@ -25,7 +27,7 @@ LastUpdatedBy integer NOT NULL DEFAULT 0,
LastUpdated TIMESTAMP NULL
);
-
+DROP TABLE IF EXISTS Topics;
CREATE TABLE Topics (
id INTEGER PRIMARY KEY,
Parent integer NOT NULL DEFAULT 0,
@@ -36,6 +38,7 @@ ObjectId integer NOT NULL
);
+DROP TABLE IF EXISTS ObjectTopics;
CREATE TABLE ObjectTopics (
id INTEGER PRIMARY KEY,
Topic integer NOT NULL,
@@ -43,6 +46,7 @@ ObjectType varchar(64) NOT NULL DEFAULT '',
ObjectId integer NOT NULL
);
+DROP TABLE IF EXISTS ObjectClasses;
CREATE TABLE ObjectClasses (
id INTEGER PRIMARY KEY,
Class integer NOT NULL,
diff --git a/rt/etc/upgrade/3.9.8/schema.mysql b/rt/etc/upgrade/3.9.8/schema.mysql
index e7ed84de7..4eaa3a127 100644
--- a/rt/etc/upgrade/3.9.8/schema.mysql
+++ b/rt/etc/upgrade/3.9.8/schema.mysql
@@ -1,3 +1,4 @@
+DROP TABLE IF EXISTS Classes;
CREATE TABLE Classes (
id int(11) NOT NULL auto_increment,
Name varchar(255) NOT NULL default '',
@@ -12,6 +13,7 @@ CREATE TABLE Classes (
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS Articles;
CREATE TABLE Articles (
id int(11) NOT NULL auto_increment,
Name varchar(255) NOT NULL default '',
@@ -27,6 +29,7 @@ CREATE TABLE Articles (
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS Topics;
CREATE TABLE Topics (
id int(11) NOT NULL auto_increment,
Parent int(11) NOT NULL default '0',
@@ -37,6 +40,7 @@ CREATE TABLE Topics (
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS ObjectTopics;
CREATE TABLE ObjectTopics (
id int(11) NOT NULL auto_increment,
Topic int(11) NOT NULL default '0',
@@ -45,6 +49,7 @@ CREATE TABLE ObjectTopics (
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS ObjectClasses;
CREATE TABLE ObjectClasses (
id int(11) NOT NULL auto_increment,
Class int(11) NOT NULL default '0',
diff --git a/rt/etc/upgrade/4.0-customfield-checkbox-extension b/rt/etc/upgrade/4.0-customfield-checkbox-extension
index 5f04cb1f0..dc8904e43 100755
--- a/rt/etc/upgrade/4.0-customfield-checkbox-extension
+++ b/rt/etc/upgrade/4.0-customfield-checkbox-extension
@@ -46,15 +46,16 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "/opt/rt3/local/lib";
use lib "/opt/rt3/lib";
-use RT;
-RT::LoadConfig();
-RT::Init();
+use RT -init
+
+$| = 1;
use RT::CustomFields;
my $cfs = RT::CustomFields->new( RT->SystemUser );
diff --git a/rt/etc/upgrade/4.0-customfield-checkbox-extension.in b/rt/etc/upgrade/4.0-customfield-checkbox-extension.in
index 8cc0ec7be..b3d466e73 100644
--- a/rt/etc/upgrade/4.0-customfield-checkbox-extension.in
+++ b/rt/etc/upgrade/4.0-customfield-checkbox-extension.in
@@ -46,15 +46,16 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
-use RT;
-RT::LoadConfig();
-RT::Init();
+use RT -init;
+
+$| = 1;
use RT::CustomFields;
my $cfs = RT::CustomFields->new( RT->SystemUser );
diff --git a/rt/etc/upgrade/4.0.0rc7/content b/rt/etc/upgrade/4.0.0rc7/content
index d0d210b7b..4fd63e71c 100644
--- a/rt/etc/upgrade/4.0.0rc7/content
+++ b/rt/etc/upgrade/4.0.0rc7/content
@@ -1,19 +1,22 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- $RT::Logger->debug("Going to set lifecycle for approvals");
+ RT->Logger->debug("Going to set lifecycle for approvals");
my $queue = RT::Queue->new( RT->SystemUser );
$queue->Load('___Approvals');
unless ( $queue->id ) {
- $RT::Logger->warning("There is no ___Approvals queue in the DB");
+ RT->Logger->warning("There is no ___Approvals queue in the DB");
return 1;
}
- return 1 if $queue->Lifecycle->Name eq 'approvals';
+ return 1 if $queue->Lifecycle && $queue->Lifecycle eq 'approvals';
my ($status, $msg) = $queue->SetLifecycle('approvals');
unless ( $status ) {
- $RT::Logger->error("Couldn't set lifecycle for '___Approvals' queue: $msg");
+ RT->Logger->error("Couldn't set lifecycle for '___Approvals' queue: $msg");
return 0;
}
return 1;
diff --git a/rt/etc/upgrade/4.0.1/content b/rt/etc/upgrade/4.0.1/content
index 9b74ff1a8..cc3b5f14a 100644
--- a/rt/etc/upgrade/4.0.1/content
+++ b/rt/etc/upgrade/4.0.1/content
@@ -1,40 +1,44 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- use strict;
- $RT::Logger->debug('Removing all delegated rights');
+ RT->Logger->debug('Removing all delegated rights');
my $acl = RT::ACL->new(RT->SystemUser);
- my $groupjoin = $acl->NewAlias('Groups');
- $acl->Join( ALIAS1 => 'main',
- FIELD1 => 'PrincipalId',
- ALIAS2 => $groupjoin,
- FIELD2 => 'id'
- );
+ my $groupjoin = $acl->Join(
+ ALIAS1 => 'main',
+ FIELD1 => 'PrincipalId',
+ TABLE2 => 'Groups',
+ FIELD2 => 'id',
+ );
$acl->Limit( ALIAS => $groupjoin,
FIELD => 'Domain',
OPERATOR => '=',
VALUE => 'Personal',
+ CASESENSITIVE => 0,
);
while ( my $ace = $acl->Next ) {
my ( $ok, $msg ) = $ace->Delete();
if ( !$ok ) {
- $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
+ RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
}
}
my $groups = RT::Groups->new(RT->SystemUser);
$groups->Limit( FIELD => 'Domain',
OPERATOR => '=',
- VALUE => 'Personal'
+ VALUE => 'Personal',
+ CASESENSITIVE => 0,
);
while ( my $group = $groups->Next ) {
my $members = $group->MembersObj();
while ( my $member = $members->Next ) {
my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId );
if ( !$ok ) {
- $RT::Logger->warn( "Unable to remove group member "
+ RT->Logger->warn( "Unable to remove group member "
. $member->id . ": "
. $msg );
}
@@ -44,8 +48,7 @@
}
},
sub {
- use strict;
- $RT::Logger->debug('Removing all Delegate and PersonalGroup rights');
+ RT->Logger->debug('Removing all Delegate and PersonalGroup rights');
my $acl = RT::ACL->new(RT->SystemUser);
for my $right (qw/AdminOwnPersonalGroups AdminAllPersonalGroups DelegateRights/) {
@@ -54,16 +57,15 @@
while ( my $ace = $acl->Next ) {
my ( $ok, $msg ) = $ace->Delete();
- $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName'));
+ RT->Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName'));
if ( !$ok ) {
- $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
+ RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
}
}
},
sub {
- use strict;
- $RT::Logger->debug('Removing unimplemented RejectTicket and ModifyTicketStatus rights');
+ RT->Logger->debug('Removing unimplemented RejectTicket and ModifyTicketStatus rights');
my $acl = RT::ACL->new(RT->SystemUser);
for my $right (qw/RejectTicket ModifyTicketStatus/) {
@@ -72,10 +74,10 @@
while ( my $ace = $acl->Next ) {
my ( $ok, $msg ) = $ace->Delete();
- $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName'));
+ RT->Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName'));
if ( !$ok ) {
- $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
+ RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg );
}
}
},
diff --git a/rt/etc/upgrade/4.0.18/content b/rt/etc/upgrade/4.0.18/content
new file mode 100644
index 000000000..64eea9af4
--- /dev/null
+++ b/rt/etc/upgrade/4.0.18/content
@@ -0,0 +1,14 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ my $attr = RT->System->FirstAttribute('BrandedSubjectTag');
+ return 1 unless $attr;
+ my ( $status, $msg ) = $attr->Delete;
+ unless ( $status ) {
+ RT->Logger->error("Couldn't delete System BrandedSubjectTag: $msg");
+ }
+ return 1;
+ },
+);
diff --git a/rt/etc/upgrade/4.0.19/content b/rt/etc/upgrade/4.0.19/content
new file mode 100644
index 000000000..31e4d9fb6
--- /dev/null
+++ b/rt/etc/upgrade/4.0.19/content
@@ -0,0 +1,29 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ use RT::CustomFields;
+ my $cfs = RT::CustomFields->new(RT->SystemUser);
+ $cfs->{'find_disabled_rows'} = 1;
+ $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' );
+ while ( my $cf = $cfs->Next ) {
+ my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' );
+ RT->Logger->warning("Update Custom Field LookupType for CF.".$cf->Id." $msg");
+ }
+ return 1;
+ },
+
+ sub {
+ use RT::ObjectCustomFieldValues;
+ my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System);
+ $ocfvs->{'find_expired_rows'} = 1;
+ $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' );
+ while ( my $ocfv = $ocfvs->Next ) {
+ my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' );
+ RT->Logger->warning("Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId'));
+ }
+ return 1;
+ },
+);
+
diff --git a/rt/etc/upgrade/4.0.19/schema.mysql b/rt/etc/upgrade/4.0.19/schema.mysql
new file mode 100644
index 000000000..de28cc9e7
--- /dev/null
+++ b/rt/etc/upgrade/4.0.19/schema.mysql
@@ -0,0 +1,5 @@
+ALTER TABLE Users MODIFY EmailAddress varchar(120) CHARACTER SET utf8;
+ALTER TABLE Queues
+ MODIFY Lifecycle varchar(32) CHARACTER SET utf8,
+ MODIFY CorrespondAddress varchar(120) CHARACTER SET utf8,
+ MODIFY CommentAddress varchar(120) CHARACTER SET utf8;
diff --git a/rt/etc/upgrade/4.0.3/content b/rt/etc/upgrade/4.0.3/content
index 3e06c89d0..74870aa7b 100644
--- a/rt/etc/upgrade/4.0.3/content
+++ b/rt/etc/upgrade/4.0.3/content
@@ -1,4 +1,7 @@
-@ScripConditions = (
+use strict;
+use warnings;
+
+our @ScripConditions = (
{
Name => 'On Forward', # loc
diff --git a/rt/etc/upgrade/4.0.4/content b/rt/etc/upgrade/4.0.4/content
index fdfcb3e27..477028995 100644
--- a/rt/etc/upgrade/4.0.4/content
+++ b/rt/etc/upgrade/4.0.4/content
@@ -1,4 +1,7 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
use strict;
my $templates = RT::Templates->new(RT->SystemUser);
@@ -9,7 +12,7 @@
);
while (my $template = $templates->Next) {
my ($status, $msg) = $template->SetType('Perl');
- $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status;
+ RT->Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status;
}
},
);
diff --git a/rt/etc/upgrade/4.0.6/content b/rt/etc/upgrade/4.0.6/content
index dc1a00951..ef01f4eaa 100644
--- a/rt/etc/upgrade/4.0.6/content
+++ b/rt/etc/upgrade/4.0.6/content
@@ -1,6 +1,9 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- my $txns = RT::Transactions->new( $RT::SystemUser );
+ my $txns = RT::Transactions->new( RT->SystemUser );
$txns->Limit(
FIELD => "ObjectType",
VALUE => "RT::User",
diff --git a/rt/etc/upgrade/4.0.9/content b/rt/etc/upgrade/4.0.9/content
index f2abf623b..6f526ce56 100644
--- a/rt/etc/upgrade/4.0.9/content
+++ b/rt/etc/upgrade/4.0.9/content
@@ -1,6 +1,9 @@
-@Initial = (
+use strict;
+use warnings;
+
+our @Initial = (
sub {
- $RT::Logger->debug(
+ RT->Logger->debug(
'Going to update empty Queue Lifecycle column to "default"');
my $queues = RT::Queues->new( RT->SystemUser );
@@ -32,7 +35,8 @@
my $groups = RT::Groups->new(RT->SystemUser);
$groups->Limit( FIELD => 'Domain',
OPERATOR => '=',
- VALUE => 'Personal'
+ VALUE => 'Personal',
+ CASESENSITIVE => 0,
);
$groups->LimitToDeleted;
while ( my $group = $groups->Next ) {
@@ -40,7 +44,7 @@
while ( my $member = $members->Next ) {
my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId );
if ( !$ok ) {
- $RT::Logger->warn( "Unable to remove group member "
+ RT->Logger->warn( "Unable to remove group member "
. $member->id . ": "
. $msg );
}
diff --git a/rt/etc/upgrade/4.1.0/content b/rt/etc/upgrade/4.1.0/content
new file mode 100644
index 000000000..2a02c6823
--- /dev/null
+++ b/rt/etc/upgrade/4.1.0/content
@@ -0,0 +1,43 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ my $users = RT::Users->new(RT->SystemUser);
+ my $attributes = $users->Join(
+ ALIAS1 => "main",
+ FIELD1 => "id",
+ TABLE2 => "Attributes",
+ FIELD2 => "ObjectId",
+ );
+ $users->Limit(
+ ALIAS => $attributes,
+ FIELD => "ObjectType",
+ VALUE => "RT::User",
+ );
+ $users->Limit(
+ ALIAS => $attributes,
+ FIELD => "Name",
+ VALUE => RT::User::_PrefName('HomepageSettings'),
+ );
+
+ while (my $user = $users->Next) {
+ my $settings = $user->Preferences('HomepageSettings')
+ or next;
+ next if exists $settings->{sidebar};
+
+ $settings->{sidebar} = delete $settings->{summary};
+ $user->SetPreferences('HomepageSettings', $settings);
+ }
+ },
+ sub {
+ my ($default_portlets) = RT->System->Attributes->Named('HomepageSettings');
+ my $settings = $default_portlets->Content;
+ return if exists $settings->{sidebar};
+
+ $settings->{sidebar} = delete $settings->{summary};
+ $default_portlets->SetContent($settings);
+ },
+);
+
+
diff --git a/rt/etc/upgrade/4.1.1/acl.Pg b/rt/etc/upgrade/4.1.1/acl.Pg
new file mode 100644
index 000000000..9e8fc0af0
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/acl.Pg
@@ -0,0 +1,31 @@
+
+sub acl {
+ my $dbh = shift;
+
+ my @acls;
+
+ my @tables = qw (
+ objectscrips_id_seq
+ ObjectScrips
+ );
+
+ my $db_user = RT->Config->Get('DatabaseUser');
+
+ my $sequence_right
+ = ( $dbh->{pg_server_version} >= 80200 )
+ ? "USAGE, SELECT, UPDATE"
+ : "SELECT, UPDATE";
+
+ foreach my $table (@tables) {
+ # Tables are upper-case, sequences are lowercase in @tables
+ if ( $table =~ /^[a-z]/ ) {
+ push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";"
+ }
+ else {
+ push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";"
+ }
+ }
+ return (@acls);
+}
+
+1;
diff --git a/rt/etc/upgrade/4.1.1/content b/rt/etc/upgrade/4.1.1/content
new file mode 100644
index 000000000..f3580bdc0
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/content
@@ -0,0 +1,36 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ require RT::ObjectScrips;
+ foreach my $stage ('TransactionCreate', 'TransactionBatch') {
+ my $applications = RT::ObjectScrips->new( RT->SystemUser );
+ $applications->Limit( FIELD => 'Stage', VALUE => $stage );
+ my $alias = $applications->Join(
+ FIELD1 => 'Scrip',
+ TABLE2 => 'Scrips', FIELD2 => 'id'
+ );
+ $applications->OrderByCols(
+ { ALIAS => $alias, FIELD => 'Description', ORDER => 'ASC' },
+ );
+ my %h; my $top_so = $h{0} = 0;
+ while ( my $record = $applications->Next ) {
+ my $oid = $record->ObjectId || 0;
+
+ my $so;
+ unless ( $oid ) {
+ %h = (); $h{0} = $so = ++$top_so;
+ }
+ else {
+ $so = $h{ $oid } = ($h{$oid}||$h{0}) + 1;
+ }
+ next if $record->SortOrder == $so;
+
+ my ($status, $msg) = $record->SetSortOrder($so);
+ RT->Logger->error("Couldn't set sort order: $msg")
+ unless $status;
+ }
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.1.1/schema.Oracle b/rt/etc/upgrade/4.1.1/schema.Oracle
new file mode 100644
index 000000000..33ea73806
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/schema.Oracle
@@ -0,0 +1,29 @@
+CREATE SEQUENCE OBJECTSCRIPS_seq;
+CREATE TABLE ObjectScrips (
+ id NUMBER(11,0)
+ CONSTRAINT ObjectScrips_Key PRIMARY KEY,
+ Scrip NUMBER(11,0) NOT NULL,
+ Stage VARCHAR2(32) DEFAULT 'TransactionCreate' NOT NULL,
+ ObjectId NUMBER(11,0) NOT NULL,
+ SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
+ALTER TABLE Scrips ADD Disabled NUMBER(11,0) DEFAULT 0 NOT NULL;
+
+INSERT INTO ObjectScrips(
+ id, Scrip, Stage, ObjectId,
+ Creator, Created, LastUpdatedBy, LastUpdated
+)
+(SELECT OBJECTSCRIPS_seq.nextval, id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated
+FROM Scrips)
+;
+
+UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled';
+UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled';
+
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
+ALTER TABLE Scrips DROP( Stage, Queue );
diff --git a/rt/etc/upgrade/4.1.1/schema.Pg b/rt/etc/upgrade/4.1.1/schema.Pg
new file mode 100644
index 000000000..91ba5a688
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/schema.Pg
@@ -0,0 +1,36 @@
+DROP TABLE IF EXISTS ObjectScrips;
+DROP SEQUENCE IF EXISTS objectscrips_id_seq;
+
+CREATE SEQUENCE objectscrips_id_seq;
+CREATE TABLE ObjectScrips (
+ id INTEGER DEFAULT nextval('objectscrips_id_seq'),
+ Scrip integer NOT NULL,
+ Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' ,
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created TIMESTAMP NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated TIMESTAMP NULL ,
+ PRIMARY KEY (id)
+
+);
+ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0;
+
+INSERT INTO ObjectScrips(
+ Scrip, Stage, ObjectId,
+ Creator, Created, LastUpdatedBy, LastUpdated
+)
+SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated
+FROM Scrips
+;
+
+UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled';
+UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled';
+
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
+ALTER TABLE Scrips
+ DROP COLUMN Stage,
+ DROP COLUMN Queue;
diff --git a/rt/etc/upgrade/4.1.1/schema.SQLite b/rt/etc/upgrade/4.1.1/schema.SQLite
new file mode 100644
index 000000000..2a6a2c4a4
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/schema.SQLite
@@ -0,0 +1,31 @@
+DROP TABLE IF EXISTS ObjectScrips;
+CREATE TABLE ObjectScrips (
+ id INTEGER NOT NULL ,
+ Scrip int NOT NULL ,
+ Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' ,
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created DATETIME NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated DATETIME NULL ,
+ PRIMARY KEY (id)
+);
+ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0;
+
+INSERT INTO ObjectScrips(
+ Scrip, Stage, ObjectId,
+ Creator, Created, LastUpdatedBy, LastUpdated
+)
+SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated
+FROM Scrips
+;
+
+UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled';
+UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled';
+
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
+# TODO: ALTER TABLE Scrips DROP COLUMN Stage;
+# TODO: ALTER TABLE Scrips DROP COLUMN Queue;
diff --git a/rt/etc/upgrade/4.1.1/schema.mysql b/rt/etc/upgrade/4.1.1/schema.mysql
new file mode 100644
index 000000000..82f3f8452
--- /dev/null
+++ b/rt/etc/upgrade/4.1.1/schema.mysql
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS ObjectScrips;
+CREATE TABLE ObjectScrips (
+ id INTEGER NOT NULL AUTO_INCREMENT,
+ Scrip integer NOT NULL ,
+ Stage varchar(32) CHARACTER SET ascii NOT NULL DEFAULT 'TransactionCreate',
+ ObjectId integer NOT NULL,
+ SortOrder integer NOT NULL DEFAULT 0 ,
+
+ Creator integer NOT NULL DEFAULT 0 ,
+ Created DATETIME NULL ,
+ LastUpdatedBy integer NOT NULL DEFAULT 0 ,
+ LastUpdated DATETIME NULL ,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB CHARACTER SET utf8;
+ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0;
+
+INSERT INTO ObjectScrips(
+ Scrip, Stage, ObjectId,
+ Creator, Created, LastUpdatedBy, LastUpdated
+)
+SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated
+FROM Scrips
+;
+
+UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled';
+UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled';
+
+CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip);
+
+ALTER TABLE Scrips
+ DROP COLUMN Stage,
+ DROP COLUMN Queue;
diff --git a/rt/etc/upgrade/4.1.10/schema.Oracle b/rt/etc/upgrade/4.1.10/schema.Oracle
new file mode 100644
index 000000000..93f036f6c
--- /dev/null
+++ b/rt/etc/upgrade/4.1.10/schema.Oracle
@@ -0,0 +1 @@
+-- No update is necessary, given that '' == NULL on Oracle
diff --git a/rt/etc/upgrade/4.1.10/schema.Pg b/rt/etc/upgrade/4.1.10/schema.Pg
new file mode 100644
index 000000000..af862b6fe
--- /dev/null
+++ b/rt/etc/upgrade/4.1.10/schema.Pg
@@ -0,0 +1 @@
+UPDATE ObjectCustomFieldValues SET Content = NULL WHERE LargeContent IS NOT NULL AND Content = '';
diff --git a/rt/etc/upgrade/4.1.10/schema.mysql b/rt/etc/upgrade/4.1.10/schema.mysql
new file mode 100644
index 000000000..af862b6fe
--- /dev/null
+++ b/rt/etc/upgrade/4.1.10/schema.mysql
@@ -0,0 +1 @@
+UPDATE ObjectCustomFieldValues SET Content = NULL WHERE LargeContent IS NOT NULL AND Content = '';
diff --git a/rt/etc/upgrade/4.1.11/schema.Oracle b/rt/etc/upgrade/4.1.11/schema.Oracle
new file mode 100644
index 000000000..6ae68bdf8
--- /dev/null
+++ b/rt/etc/upgrade/4.1.11/schema.Oracle
@@ -0,0 +1 @@
+ALTER TABLE CustomFields DROP COLUMN Repeated;
diff --git a/rt/etc/upgrade/4.1.11/schema.Pg b/rt/etc/upgrade/4.1.11/schema.Pg
new file mode 100644
index 000000000..6ae68bdf8
--- /dev/null
+++ b/rt/etc/upgrade/4.1.11/schema.Pg
@@ -0,0 +1 @@
+ALTER TABLE CustomFields DROP COLUMN Repeated;
diff --git a/rt/etc/upgrade/4.1.11/schema.mysql b/rt/etc/upgrade/4.1.11/schema.mysql
new file mode 100644
index 000000000..6ae68bdf8
--- /dev/null
+++ b/rt/etc/upgrade/4.1.11/schema.mysql
@@ -0,0 +1 @@
+ALTER TABLE CustomFields DROP COLUMN Repeated;
diff --git a/rt/etc/upgrade/4.1.12/content b/rt/etc/upgrade/4.1.12/content
new file mode 100644
index 000000000..1f0473d24
--- /dev/null
+++ b/rt/etc/upgrade/4.1.12/content
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+our @ACL = ( {
+ Right => 'ShowArticlesMenu',
+ GroupDomain => 'SystemInternal',
+ GroupType => 'Privileged',
+} );
+
+1;
diff --git a/rt/etc/upgrade/4.1.13/backcompat b/rt/etc/upgrade/4.1.13/backcompat
new file mode 100644
index 000000000..0dc53d224
--- /dev/null
+++ b/rt/etc/upgrade/4.1.13/backcompat
@@ -0,0 +1,34 @@
+my $upgrade = shift;
+
+my $groups = RT::Groups->new( RT->SystemUser );
+$groups->Limit(
+ FIELD => 'Name', OPERATOR => '!=', VALUE => 'main.Type', QUOTEVALUE => 0
+);
+$groups->Limit(
+ FIELD => 'Name', OPERATOR => 'IS', VALUE => 'NULL',
+);
+$groups->Limit(
+ FIELD => 'Domain',
+ VALUE => 'SystemInternal',
+ CASESENSITIVE => 0,
+);
+$groups->RowsPerPage(1);
+if ( $groups->Next ) {
+ my $dbh = $RT::Handle->dbh;
+ my $db_type = RT->Config->Get('DatabaseType');
+ if ( $db_type eq 'Oracle' || $db_type eq 'Pg' ) {
+ $dbh->do(
+ "UPDATE Groups SET Name = Type
+ WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal')
+ OR LOWER(Domain) LIKE '%-role'"
+ );
+ } else {
+ $dbh->do(
+ "UPDATE Groups SET Name = Type
+ WHERE Domain IN ('ACLEquivalence', 'SystemInternal')
+ OR Domain LIKE '%-Role'"
+ );
+ }
+}
+
+$upgrade->();
diff --git a/rt/etc/upgrade/4.1.13/schema.Oracle b/rt/etc/upgrade/4.1.13/schema.Oracle
new file mode 100644
index 000000000..96869c64f
--- /dev/null
+++ b/rt/etc/upgrade/4.1.13/schema.Oracle
@@ -0,0 +1,3 @@
+UPDATE Groups SET Name = Type
+WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal') OR LOWER(Domain) LIKE '%-role';
+
diff --git a/rt/etc/upgrade/4.1.13/schema.Pg b/rt/etc/upgrade/4.1.13/schema.Pg
new file mode 100644
index 000000000..96869c64f
--- /dev/null
+++ b/rt/etc/upgrade/4.1.13/schema.Pg
@@ -0,0 +1,3 @@
+UPDATE Groups SET Name = Type
+WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal') OR LOWER(Domain) LIKE '%-role';
+
diff --git a/rt/etc/upgrade/4.1.13/schema.SQLite b/rt/etc/upgrade/4.1.13/schema.SQLite
new file mode 100644
index 000000000..9ea6a9121
--- /dev/null
+++ b/rt/etc/upgrade/4.1.13/schema.SQLite
@@ -0,0 +1,3 @@
+UPDATE Groups SET Name = Type
+WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role';
+
diff --git a/rt/etc/upgrade/4.1.13/schema.mysql b/rt/etc/upgrade/4.1.13/schema.mysql
new file mode 100644
index 000000000..a429007e3
--- /dev/null
+++ b/rt/etc/upgrade/4.1.13/schema.mysql
@@ -0,0 +1,2 @@
+UPDATE Groups SET Name = Type
+WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role'; \ No newline at end of file
diff --git a/rt/etc/upgrade/4.1.14/schema.Oracle b/rt/etc/upgrade/4.1.14/schema.Oracle
new file mode 100644
index 000000000..f626093a0
--- /dev/null
+++ b/rt/etc/upgrade/4.1.14/schema.Oracle
@@ -0,0 +1 @@
+ALTER TABLE Scrips DROP( ConditionRules, ActionRules );
diff --git a/rt/etc/upgrade/4.1.14/schema.Pg b/rt/etc/upgrade/4.1.14/schema.Pg
new file mode 100644
index 000000000..0b45d5178
--- /dev/null
+++ b/rt/etc/upgrade/4.1.14/schema.Pg
@@ -0,0 +1,3 @@
+ALTER TABLE Scrips
+ DROP COLUMN ConditionRules,
+ DROP COLUMN ActionRules;
diff --git a/rt/etc/upgrade/4.1.14/schema.mysql b/rt/etc/upgrade/4.1.14/schema.mysql
new file mode 100644
index 000000000..0b45d5178
--- /dev/null
+++ b/rt/etc/upgrade/4.1.14/schema.mysql
@@ -0,0 +1,3 @@
+ALTER TABLE Scrips
+ DROP COLUMN ConditionRules,
+ DROP COLUMN ActionRules;
diff --git a/rt/etc/upgrade/4.1.15/content b/rt/etc/upgrade/4.1.15/content
new file mode 100644
index 000000000..3e1f1d55a
--- /dev/null
+++ b/rt/etc/upgrade/4.1.15/content
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+our @ScripActions = (
+ { Name => 'Notify Owner and AdminCcs', # loc
+ Description => 'Sends mail to the Owner and administrative Ccs', # loc
+ ExecModule => 'Notify',
+ Argument => 'Owner,AdminCc' },
+);
+
+our @Templates = (
+ # Shadow the global templates of the same name to suppress duplicate
+ # notifications until rules is ripped out.
+ { Queue => "___Approvals",
+ Name => "Transaction in HTML",
+ Content => "",
+ },
+ { Queue => "___Approvals",
+ Name => "Transaction",
+ Content => "",
+ },
+);
diff --git a/rt/etc/upgrade/4.1.16/content b/rt/etc/upgrade/4.1.16/content
new file mode 100644
index 000000000..44f212977
--- /dev/null
+++ b/rt/etc/upgrade/4.1.16/content
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+
+our @Templates = (
+ { Queue => '0',
+ Name => 'Reminder', # loc
+ Description => 'Default reminder template', # loc
+ Content =>
+'Subject:{$Ticket->Subject} is due {$Ticket->DueObj->AsString}
+
+This reminder is for ticket #{$Target = $Ticket->RefersTo->First->TargetObj;$Target->Id}.
+
+{RT->Config->Get(\'WebURL\')}Ticket/Display.html?id={$Target->Id}
+'
+ },
+);
diff --git a/rt/etc/upgrade/4.1.17/content b/rt/etc/upgrade/4.1.17/content
new file mode 100644
index 000000000..2e6a78cda
--- /dev/null
+++ b/rt/etc/upgrade/4.1.17/content
@@ -0,0 +1,26 @@
+use strict;
+use warnings;
+
+our @Initial = (sub {
+ my $searches = RT::Attributes->new(RT->SystemUser);
+ $searches->Limit( FIELD => 'Name', VALUE => 'SavedSearch' );
+ $searches->OrderBy( FIELD => 'id' );
+
+ while (my $search = $searches->Next) {
+ my $content = $search->Content;
+ next unless ref $content eq 'HASH';
+ next unless ($content->{SearchType} || '') eq 'Chart';
+
+ # Switch from PrimaryGroupBy to GroupBy name
+ # Switch from "CreatedMonthly" to "Created.Monthly"
+ $content->{GroupBy} ||= [delete $content->{PrimaryGroupBy}];
+ for (@{$content->{GroupBy}}) {
+ next if !defined || /\./;
+ s/(?<=[a-z])(?=[A-Z])/./;
+ }
+
+ my ($ok, $msg) = $search->SetContent($content);
+ RT->Logger->error("Unable to upgrade saved chart #@{[$search->id]}: $msg")
+ unless $ok;
+ }
+});
diff --git a/rt/etc/upgrade/4.1.18/content b/rt/etc/upgrade/4.1.18/content
new file mode 100644
index 000000000..818351bfa
--- /dev/null
+++ b/rt/etc/upgrade/4.1.18/content
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+
+# Ticket-level notifications
+our @ScripActions = ({
+ Name => 'On SetStarted Open Ticket',
+ Description => 'When Started is Updated Set Ticket Status to Open',
+ ExecModule => 'OpenOnStarted',
+});
+
+our @Scrips = ({
+ Description => "On transaction and SetStarted Open Ticket",
+ ScripCondition => 'On Transaction',
+ ScripAction => 'On SetStarted Open Ticket',
+ Template => 'Blank'
+});
diff --git a/rt/etc/upgrade/4.1.19/schema.Oracle b/rt/etc/upgrade/4.1.19/schema.Oracle
new file mode 100644
index 000000000..2371a5d2b
--- /dev/null
+++ b/rt/etc/upgrade/4.1.19/schema.Oracle
@@ -0,0 +1 @@
+ALTER TABLE Templates DROP( Language, TranslationOf );
diff --git a/rt/etc/upgrade/4.1.19/schema.Pg b/rt/etc/upgrade/4.1.19/schema.Pg
new file mode 100644
index 000000000..cfaa9a72f
--- /dev/null
+++ b/rt/etc/upgrade/4.1.19/schema.Pg
@@ -0,0 +1,3 @@
+ALTER TABLE Templates
+ DROP COLUMN Language,
+ DROP COLUMN TranslationOf;
diff --git a/rt/etc/upgrade/4.1.19/schema.mysql b/rt/etc/upgrade/4.1.19/schema.mysql
new file mode 100644
index 000000000..cfaa9a72f
--- /dev/null
+++ b/rt/etc/upgrade/4.1.19/schema.mysql
@@ -0,0 +1,3 @@
+ALTER TABLE Templates
+ DROP COLUMN Language,
+ DROP COLUMN TranslationOf;
diff --git a/rt/etc/upgrade/4.1.20/content b/rt/etc/upgrade/4.1.20/content
new file mode 100644
index 000000000..edde022c9
--- /dev/null
+++ b/rt/etc/upgrade/4.1.20/content
@@ -0,0 +1,56 @@
+use strict;
+use warnings;
+
+our @ScripActions = (
+ { Name => 'Send Forward',
+ Description => 'Send forwarded message',
+ ExecModule => 'SendForward', },
+);
+
+our @Scrips = (
+ { Description => 'On Forward Transaction Send forwarded message',
+ ScripCondition => 'On Forward Transaction',
+ ScripAction => 'Send Forward',
+ Template => 'Forward' },
+ { Description => 'On Forward Ticket Send forwarded message',
+ ScripCondition => 'On Forward Ticket',
+ ScripAction => 'Send Forward',
+ Template => 'Forward Ticket' },
+);
+
+our @Initial = (
+ sub {
+ my $forward_template = RT::Template->new(RT->SystemUser);
+ $forward_template->Load('Forward');
+ $forward_template->SetDescription('Forwarded message');
+
+ if ( $forward_template->Content =~
+ m/^\n*This is (a )?forward of transaction #\{\s*\$Transaction->id\s*\} of (a )?ticket #\{\s*\$Ticket->id\s*\}\n*$/
+ ) {
+ $forward_template->SetContent(q{
+
+{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of transaction #".$Transaction->id." of ticket #". $Ticket->id }
+});
+ }
+ else {
+ RT->Logger->error('Current "Forward" template is not the default version, please check docs/UPGRADING-4.2');
+ }
+
+ my $forward_ticket_template = RT::Template->new(RT->SystemUser);
+ $forward_ticket_template->Load('Forward Ticket');
+ $forward_ticket_template->SetDescription('Forwarded ticket message');
+ if ( $forward_ticket_template->Content eq q{
+
+This is a forward of ticket #{ $Ticket->id }
+} ) {
+ $forward_ticket_template->SetContent(q{
+
+{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of ticket #". $Ticket->id }
+});
+
+ }
+ else {
+ RT->Logger->error('Current "Forward Ticket" template is not the default version, please check docs/UPGRADING-4.2');
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.1.21/content b/rt/etc/upgrade/4.1.21/content
new file mode 100644
index 000000000..dbf75c7cd
--- /dev/null
+++ b/rt/etc/upgrade/4.1.21/content
@@ -0,0 +1,64 @@
+use strict;
+use warnings;
+
+sub dashboards_for_object {
+ my $object = shift;
+ my $user = shift;
+ my %dashboards;
+ my $privacy = RT::Dashboard->_build_privacy($object);
+
+ while ( my $attr = $object->Attributes->Next ) {
+ if ( $attr->Name =~ /^Dashboard\b/ ) {
+ my $dashboard = RT::Dashboard->new($user);
+ my ( $ok, $msg ) = $dashboard->Load( $privacy, $attr->id );
+ next unless $ok;
+
+ if ( $object->isa('RT::System') ) {
+ push @{ $dashboards{system} }, $dashboard;
+ }
+ elsif ( $object->isa('RT::User') ) {
+ push @{ $dashboards{personal} }, $dashboard;
+ }
+ elsif ( $object->isa('RT::Group') ) {
+ push @{ $dashboards{group}{ $object->Name } }, $dashboard;
+ }
+ }
+ }
+ return \%dashboards;
+}
+
+our @Final = (
+ sub {
+ my $users = RT::Users->new( RT->SystemUser );
+ $users->LimitToPrivileged();
+ while ( my $user = $users->Next ) {
+ my @objs = RT::Dashboard->new($user)->ObjectsForLoading( IncludeSuperuserGroups => 0 );
+
+ my %dashboard_map;
+
+ for my $object (@objs) {
+ my $dashboards = dashboards_for_object( $object, $user );
+ push @{ $dashboard_map{$_} }, @{ $dashboards->{$_} || [] } for qw/personal system/;
+
+ push @{ $dashboard_map{group}{$_} }, @{ $dashboards->{group}{$_} }
+ for keys %{ $dashboards->{group} || {} };
+ }
+
+ my @dashboards = (
+ ( sort { $a->Id <=> $b->Id } @{ $dashboard_map{personal} || [] } ),
+ ( sort { $a->Id <=> $b->Id } @{ $dashboard_map{system} || [] } ),
+
+ map {
+ sort { $a->Id <=> $b->Id }
+ @{ $dashboard_map{group}{$_} }
+ }
+ keys %{ $dashboard_map{group} || {} },
+ );
+
+ splice @dashboards, 7 if @dashboards > 7;
+ @dashboards = map { $_->id } @dashboards;
+ my ( $ret, $msg ) = $user->SetPreferences( 'DashboardsInMenu', { dashboards => \@dashboards } );
+ RT->Logger->error( $msg ) unless $ret;
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.1.22/content b/rt/etc/upgrade/4.1.22/content
new file mode 100644
index 000000000..c9f18ff40
--- /dev/null
+++ b/rt/etc/upgrade/4.1.22/content
@@ -0,0 +1,85 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ my $template = RT::Template->new( RT->SystemUser );
+ $template->Load("Error: bad GnuPG data");
+ unless ($template->id) {
+ RT->Logger->error( "Couldn't find 'Error: bad GnuPG data' template to rename" );
+ return;
+ }
+
+ my ($ok, $msg) = $template->SetName("Error: bad encrypted data");
+ RT->Logger->error( "Couldn't rename 'Error: bad GnuPG data' template: $msg")
+ unless $ok;
+
+ ($ok, $msg) = $template->SetDescription("Inform user that a message he sent has invalid encryption data");
+ RT->Logger->error( "Couldn't update 'Error: bad encrypted data' template description: $msg")
+ unless $ok;
+
+ my $content = $template->Content;
+ $content =~ s/GnuPG signature/signature/g;
+ ($ok, $msg) = $template->SetContent( $content );
+ RT->Logger->error( "Couldn't update 'Error: bad encrypted data' template content: $msg")
+ unless $ok;
+ },
+ sub {
+ my $type = RT::User->new( $RT::SystemUser )->CustomFieldLookupType;
+ my $cf = RT::CustomField->new( $RT::SystemUser );
+ $cf->LoadByCols( Name => 'SMIME Key', LookupType => $type );
+ $cf->LoadByCols( Name => 'PublicKey', LookupType => $type ) unless $cf->id;
+ unless ( $cf->id ) {
+ $RT::Logger->debug("You don't have an 'SMIME Key' or 'PublicKey' user CF -- nothing to do.");
+ return;
+ }
+
+ my $users = RT::Users->new( RT->SystemUser );
+ $users->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => "IS NOT",
+ VALUE => "NULL",
+ );
+ while (my $u = $users->Next) {
+ $u->SetSMIMECertificate(
+ $u->FirstCustomFieldValue( $cf->id ),
+ );
+ }
+
+ my $ocfs = $cf->AddedTo;
+ while (my $ocf = $ocfs->Next) {
+ my ($ok, $msg) = $ocf->Delete;
+ RT->Logger->error( "Couldn't delete OCF ".$ocf->id." while deleting ".$cf->Name." CF: $msg")
+ unless $ok;
+ }
+
+ my ($ok, $msg) = $cf->Delete;
+ RT->Logger->error( "Couldn't delete ".$cf->Name." CF: $msg")
+ unless $ok;
+ },
+ sub {
+ $RT::Logger->info("Going to delete all SMIMEKeyNotAfter attributes");
+ my $attrs = RT::Attributes->new( $RT::SystemUser );
+ $attrs->Limit( FIELD => 'ObjectType', VALUE => 'RT::User' );
+ $attrs->Limit( FIELD => 'Name', VALUE => 'SMIMEKeyNotAfter' );
+ while ( my $attr = $attrs->Next ) {
+ my ($status, $msg) = $attr->Delete;
+ unless ( $status ) {
+ $RT::Logger->error("Couldn't delete attribute: $msg");
+ }
+ }
+ return 1;
+ },
+);
+
+our @Templates = (
+ { Queue => 0,
+ Name => "Error: unencrypted message", # loc
+ Description =>
+ "Inform user that their unencrypted mail has been rejected", # loc
+ Content => q{Subject: RT requires that all incoming mail be encrypted
+
+You received this message because RT received mail from you that was not encrypted. As such, it has been rejected.
+}
+ },
+);
diff --git a/rt/etc/upgrade/4.1.22/schema.Oracle b/rt/etc/upgrade/4.1.22/schema.Oracle
new file mode 100644
index 000000000..273779b45
--- /dev/null
+++ b/rt/etc/upgrade/4.1.22/schema.Oracle
@@ -0,0 +1 @@
+ALTER TABLE Users ADD SMIMECertificate CLOB;
diff --git a/rt/etc/upgrade/4.1.22/schema.Pg b/rt/etc/upgrade/4.1.22/schema.Pg
new file mode 100644
index 000000000..7da9d2c89
--- /dev/null
+++ b/rt/etc/upgrade/4.1.22/schema.Pg
@@ -0,0 +1 @@
+ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT NULL;
diff --git a/rt/etc/upgrade/4.1.22/schema.SQLite b/rt/etc/upgrade/4.1.22/schema.SQLite
new file mode 100644
index 000000000..3b7d6cedb
--- /dev/null
+++ b/rt/etc/upgrade/4.1.22/schema.SQLite
@@ -0,0 +1 @@
+ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT COLLATE NOCASE NULL;
diff --git a/rt/etc/upgrade/4.1.22/schema.mysql b/rt/etc/upgrade/4.1.22/schema.mysql
new file mode 100644
index 000000000..7da9d2c89
--- /dev/null
+++ b/rt/etc/upgrade/4.1.22/schema.mysql
@@ -0,0 +1 @@
+ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT NULL;
diff --git a/rt/etc/upgrade/4.1.23/indexes b/rt/etc/upgrade/4.1.23/indexes
new file mode 100644
index 000000000..78db4aee6
--- /dev/null
+++ b/rt/etc/upgrade/4.1.23/indexes
@@ -0,0 +1,168 @@
+use strict;
+use warnings;
+
+# groups table
+{
+ foreach my $name ( qw(Groups1 Groups2 Groups3) ) {
+ my ($status, $msg) = $RT::Handle->DropIndexIfExists(
+ Table => 'Groups', Name => $name,
+ );
+ my $method = $status ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+ }
+
+ my ($name, $msg) = $RT::Handle->CreateIndex(
+ Table => 'Groups',
+ Columns => [qw(Domain Type Instance)],
+ CaseInsensitive => { domain => 1, type => 1 },
+ );
+ my $method = $name ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+
+ ($name, $msg) = $RT::Handle->CreateIndex(
+ Table => 'Groups',
+ Columns => [qw(Domain Name Instance)],
+ CaseInsensitive => { domain => 1, name => 1 },
+ );
+ $method = $name ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+
+ ($name, $msg) = $RT::Handle->CreateIndex(
+ Table => 'Groups',
+ Columns => [qw(Instance)],
+ );
+ $method = $name ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+}
+
+my $dedup = sub {
+ my ($table, $column) = (@_);
+
+ my $collection_class = "RT::$table";
+ my $record_class = $collection_class;
+ $record_class =~ s/s$//;
+
+ my $sql;
+
+ my $cs = $RT::Handle->CaseSensitive;
+ if ($cs) {
+ $sql = "SELECT DISTINCT LOWER(t1.$column) FROM $table t1, $table t2"
+ ." WHERE LOWER(t1.$column) = LOWER(t2.$column)"
+ .' AND t1.id != t2.id';
+ } else {
+ $sql = "SELECT DISTINCT t1.$column FROM $table t1, $table t2"
+ ." WHERE t1.$column = t2.$column"
+ .' AND t1.id != t2.id';
+ }
+
+ my $dbh = $RT::Handle->dbh;
+ my $sth = $dbh->prepare($sql);
+ $sth->execute;
+
+ my $found = 0;
+ while ( my ($value) = $sth->fetchrow_array ) {
+ $found = 1;
+
+ my $ids = $dbh->selectcol_arrayref(
+ "SELECT id FROM $table WHERE ". ($cs? "LOWER($column)" : $column) ." = LOWER(?)",
+ undef,
+ $value
+ );
+
+ # skip first
+ shift @$ids;
+
+ foreach my $id ( @$ids ) {
+ RT->Logger->debug("Changing $column of $record_class #". $id );
+ $dbh->do("UPDATE $table SET $column = ? WHERE id = ?", undef, $value . '-dup-'.$id, $id);
+ }
+ }
+
+ if ( $found ) {
+ RT->Logger->warning(
+ "Records in $table table had non-unique values in $column column."
+ ." $column has been changed for such records, and now matches '%-dup-%'"
+ );
+ }
+};
+
+# a few case insensitive and unique indexes
+{
+ my @list = (
+ { Table => 'Queues', Column => 'Name' },
+ { Table => 'Users', Column => 'Name' },
+ );
+ foreach my $e (@list) {
+ RT->Logger->debug("Checking index on ". $e->{'Column'} ." in ". $e->{'Table'} );
+ my (@indexes) = $RT::Handle->IndexesThatBeginWith(
+ Table => $e->{'Table'}, Columns => [$e->{'Column'}]
+ );
+ @indexes = grep {@{$_->{'Columns'}} == 1} @indexes;
+ if (grep {$_->{Unique} && ($RT::Handle->CaseSensitive? $_->{'CaseInsensitive'}{ lc $e->{'Column'} } : 1 ) } @indexes
+ ) {
+ RT->Logger->debug("Required index exists. Skipping.");
+ next;
+ }
+
+ $dedup->( $e->{'Table'}, $e->{'Column'} );
+
+ for my $index ( @indexes ) {
+ my ($status, $msg) = $RT::Handle->DropIndex(
+ Table => $e->{'Table'}, Name => $index->{'Name'},
+ );
+ my $method = $status ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+ }
+
+ my ($status, $msg) = $RT::Handle->CreateIndex(
+ Table => $e->{'Table'}, Columns => [$e->{'Column'}],
+ Unique => 1, CaseInsensitive => { lc $e->{'Column'} => 1 },
+ );
+ my $method = $status ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+ }
+}
+
+# cached group members
+{
+ $RT::Handle->MakeSureIndexExists(
+ Table => 'CachedGroupMembers',
+ Columns => ['MemberId', 'ImmediateParentId'],
+ );
+ $RT::Handle->MakeSureIndexExists(
+ Table => 'CachedGroupMembers',
+ Columns => ['MemberId', 'GroupId'],
+ Optional => ['Disabled'],
+ );
+ $RT::Handle->DropIndexesThatArePrefix(
+ Table => 'CachedGroupMembers',
+ Columns => ['MemberId', 'GroupId', 'Disabled'],
+ );
+ $RT::Handle->MakeSureIndexExists(
+ Table => 'CachedGroupMembers',
+ Columns => ['GroupId', 'MemberId'],
+ Optional => ['Disabled'],
+ );
+ $RT::Handle->DropIndexesThatArePrefix(
+ Table => 'CachedGroupMembers',
+ Columns => ['GroupId', 'MemberId', 'Disabled'],
+ );
+}
+
+# drop indexes that start with 'id' column
+foreach my $table ('Users', 'Tickets') {
+ my @list = $RT::Handle->IndexesThatBeginWith(
+ Table => $table, Columns => ['id'],
+ );
+ @list = grep @{ $_->{'Columns'} } > 1, @list;
+
+ foreach my $index (@list) {
+ my ($status, $msg) = $RT::Handle->DropIndex(
+ Table => $table, Name => $index->{'Name'},
+ );
+ my $method = $status ? 'debug' : 'warning';
+ RT->Logger->$method($msg);
+ }
+}
+
+1;
diff --git a/rt/etc/upgrade/4.1.4/content b/rt/etc/upgrade/4.1.4/content
new file mode 100644
index 000000000..b320695cb
--- /dev/null
+++ b/rt/etc/upgrade/4.1.4/content
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+our (@Final);
+
+push @Final, sub {
+ my %global = %{ RT->System->AvailableRights };
+ my $handle = RT->DatabaseHandle;
+
+ for my $role (RT::System->Roles) {
+ my $group = RT::Group->new( RT->SystemUser );
+ my ($ok, $msg) = $group->LoadRoleGroup(
+ Object => RT->System,
+ Name => $role,
+ );
+
+ unless ($group->id) {
+ RT->Logger->error("Can't load role group $role: $msg");
+ next;
+ }
+
+ my %rights = %{ RT->System->AvailableRights( $group->PrincipalObj ) };
+
+ # Global rights which aren't available on the role anymore
+ my @remove = grep { not $rights{$_} }
+ keys %global;
+ my $placeholders = join ",", map { "?" } 1 .. scalar @remove;
+
+ my $query = <<" SQL";
+ DELETE FROM ACL
+ WHERE PrincipalType = ?
+ AND PrincipalId = ?
+ AND ObjectType = 'RT::System'
+ AND RightName IN ($placeholders)
+ SQL
+
+ my $res = $handle->SimpleQuery(
+ $query,
+ $role, # Type
+ $group->PrincipalId, # Id
+ @remove, # Right names
+ );
+
+ unless ($res) {
+ RT->Logger->error("Failed to delete invalid rights on system role $role!");
+ next;
+ }
+ }
+};
diff --git a/rt/etc/upgrade/4.1.4/schema.Oracle b/rt/etc/upgrade/4.1.4/schema.Oracle
new file mode 100644
index 000000000..e530ede81
--- /dev/null
+++ b/rt/etc/upgrade/4.1.4/schema.Oracle
@@ -0,0 +1 @@
+UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
diff --git a/rt/etc/upgrade/4.1.4/schema.Pg b/rt/etc/upgrade/4.1.4/schema.Pg
new file mode 100644
index 000000000..e530ede81
--- /dev/null
+++ b/rt/etc/upgrade/4.1.4/schema.Pg
@@ -0,0 +1 @@
+UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
diff --git a/rt/etc/upgrade/4.1.4/schema.SQLite b/rt/etc/upgrade/4.1.4/schema.SQLite
new file mode 100644
index 000000000..e530ede81
--- /dev/null
+++ b/rt/etc/upgrade/4.1.4/schema.SQLite
@@ -0,0 +1 @@
+UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
diff --git a/rt/etc/upgrade/4.1.4/schema.mysql b/rt/etc/upgrade/4.1.4/schema.mysql
new file mode 100644
index 000000000..e530ede81
--- /dev/null
+++ b/rt/etc/upgrade/4.1.4/schema.mysql
@@ -0,0 +1 @@
+UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0;
diff --git a/rt/etc/upgrade/4.1.5/content b/rt/etc/upgrade/4.1.5/content
new file mode 100644
index 000000000..0ed1dda39
--- /dev/null
+++ b/rt/etc/upgrade/4.1.5/content
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ # upgrade Template from id to name
+ sub {
+ require RT::Scrips;
+ my $scrips = RT::Scrips->new( RT->SystemUser );
+ $scrips->UnLimit;
+ while ( my $scrip = $scrips->Next ) {
+ my $id = $scrip->Template;
+ if ( $id =~ /\D/ ) {
+ $RT::Logger->info('Template column for scrip #'. $scrip->id .' already contains characters');
+ next;
+ }
+
+ my $name;
+
+ my $template = RT::Template->new( RT->SystemUser );
+ $template->Load( $id );
+ unless ( $template->id ) {
+ $RT::Logger->error("Scrip #". $scrip->id ." has template set to #$id, but it's not in DB, setting it 'Blank'");
+ $name = 'Blank';
+ } else {
+ $name = $template->Name;
+ }
+
+ my ($status, $msg) = $scrip->_Set( Field => 'Template', Value => $name );
+ unless ( $status ) {
+ $RT::Logger->error("Couldn't set template: $msg");
+ }
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.1.5/schema.Oracle b/rt/etc/upgrade/4.1.5/schema.Oracle
new file mode 100644
index 000000000..648784dca
--- /dev/null
+++ b/rt/etc/upgrade/4.1.5/schema.Oracle
@@ -0,0 +1,6 @@
+# Template column
+ALTER TABLE Scrips RENAME COLUMN Template TO TemplateOld;
+ALTER TABLE Scrips ADD Template VARCHAR2(200);
+UPDATE Scrips SET Template = CAST(TemplateOld AS varchar2(200));
+ALTER TABLE Scrips MODIFY Template VARCHAR2(200) NOT NULL;
+ALTER TABLE Scrips DROP COLUMN TemplateOld;
diff --git a/rt/etc/upgrade/4.1.5/schema.Pg b/rt/etc/upgrade/4.1.5/schema.Pg
new file mode 100644
index 000000000..3a12d4d88
--- /dev/null
+++ b/rt/etc/upgrade/4.1.5/schema.Pg
@@ -0,0 +1,2 @@
+# Template colum
+ALTER TABLE Scrips ALTER COLUMN Template TYPE varchar(200);
diff --git a/rt/etc/upgrade/4.1.5/schema.mysql b/rt/etc/upgrade/4.1.5/schema.mysql
new file mode 100644
index 000000000..d35d73071
--- /dev/null
+++ b/rt/etc/upgrade/4.1.5/schema.mysql
@@ -0,0 +1,2 @@
+# Template column
+ALTER TABLE Scrips CHANGE Template Template varchar(200) NOT NULL;
diff --git a/rt/etc/upgrade/4.1.6/content b/rt/etc/upgrade/4.1.6/content
new file mode 100644
index 000000000..d27014c94
--- /dev/null
+++ b/rt/etc/upgrade/4.1.6/content
@@ -0,0 +1,43 @@
+use strict;
+use warnings;
+
+our @Initial = (sub {
+ my $users = RT::Users->new(RT->SystemUser);
+ $users->FindAllRows;
+
+ my $attributes = $users->Join(
+ ALIAS1 => "main",
+ FIELD1 => "id",
+ TABLE2 => RT::Attributes->Table,
+ FIELD2 => "ObjectId",
+ );
+ $users->Limit(
+ ALIAS => $attributes,
+ FIELD => "ObjectType",
+ VALUE => "RT::User",
+ );
+ $users->Limit(
+ ALIAS => $attributes,
+ FIELD => "Name",
+ VALUE => RT::User::_PrefName( RT->System ),
+ );
+
+ # Iterate all users (including disabled), with config preferences set.
+ # Avoids running a query for every user in the system by only selecting
+ # those known to have preferences.
+ while (my $user = $users->Next) {
+ RT->Logger->debug(sprintf "User #%d has config preferences", $user->id);
+
+ my $config = $user->Preferences( RT->System )
+ or next;
+ next unless exists $config->{DeferTransactionLoading};
+
+ $config->{ShowHistory} = delete $config->{DeferTransactionLoading}
+ ? "click" : "delay";
+
+ $user->SetPreferences( RT->System, $config );
+ RT->Logger->debug(sprintf "Updated config Preferences for user %s (#%d)", $user->Name, $user->id);
+ }
+});
+
+1;
diff --git a/rt/etc/upgrade/4.1.7/schema.Oracle b/rt/etc/upgrade/4.1.7/schema.Oracle
new file mode 100644
index 000000000..b53dceb02
--- /dev/null
+++ b/rt/etc/upgrade/4.1.7/schema.Oracle
@@ -0,0 +1,5 @@
+UPDATE Transactions
+SET TimeTaken
+ = COALESCE(TO_NUMBER(REGEXP_SUBSTR(NewValue, '^-?\d+$')), 0)
+ - COALESCE(TO_NUMBER(OldValue),0)
+WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked'; \ No newline at end of file
diff --git a/rt/etc/upgrade/4.1.7/schema.Pg b/rt/etc/upgrade/4.1.7/schema.Pg
new file mode 100644
index 000000000..2949e32e4
--- /dev/null
+++ b/rt/etc/upgrade/4.1.7/schema.Pg
@@ -0,0 +1,5 @@
+UPDATE Transactions
+SET TimeTaken
+ = (CASE WHEN NewValue~E'^-?\\d+$' THEN NewValue::integer ELSE 0 END)
+ - COALESCE(OldValue::integer, 0)
+WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked'; \ No newline at end of file
diff --git a/rt/etc/upgrade/4.1.7/schema.SQLite b/rt/etc/upgrade/4.1.7/schema.SQLite
new file mode 100644
index 000000000..8d6680d65
--- /dev/null
+++ b/rt/etc/upgrade/4.1.7/schema.SQLite
@@ -0,0 +1,2 @@
+UPDATE Transactions SET TimeTaken = NewValue - OldValue
+WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked'; \ No newline at end of file
diff --git a/rt/etc/upgrade/4.1.7/schema.mysql b/rt/etc/upgrade/4.1.7/schema.mysql
new file mode 100644
index 000000000..95013f333
--- /dev/null
+++ b/rt/etc/upgrade/4.1.7/schema.mysql
@@ -0,0 +1,5 @@
+UPDATE Transactions
+SET TimeTaken
+ = COALESCE(NewValue,0)
+ - COALESCE(OldValue,0)
+WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked'; \ No newline at end of file
diff --git a/rt/etc/upgrade/4.1.8/schema.Oracle b/rt/etc/upgrade/4.1.8/schema.Oracle
new file mode 100644
index 000000000..07cd14834
--- /dev/null
+++ b/rt/etc/upgrade/4.1.8/schema.Oracle
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD IsMerged NUMBER(11,0) DEFAULT NULL NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/rt/etc/upgrade/4.1.8/schema.Pg b/rt/etc/upgrade/4.1.8/schema.Pg
new file mode 100644
index 000000000..a35287e05
--- /dev/null
+++ b/rt/etc/upgrade/4.1.8/schema.Pg
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged smallint NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/rt/etc/upgrade/4.1.8/schema.SQLite b/rt/etc/upgrade/4.1.8/schema.SQLite
new file mode 100644
index 000000000..4e28e3b0d
--- /dev/null
+++ b/rt/etc/upgrade/4.1.8/schema.SQLite
@@ -0,0 +1,3 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
+
diff --git a/rt/etc/upgrade/4.1.8/schema.mysql b/rt/etc/upgrade/4.1.8/schema.mysql
new file mode 100644
index 000000000..8977c10a8
--- /dev/null
+++ b/rt/etc/upgrade/4.1.8/schema.mysql
@@ -0,0 +1,2 @@
+ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL;
+UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId;
diff --git a/rt/etc/upgrade/4.1.9/content b/rt/etc/upgrade/4.1.9/content
new file mode 100644
index 000000000..3c68b6915
--- /dev/null
+++ b/rt/etc/upgrade/4.1.9/content
@@ -0,0 +1,190 @@
+use strict;
+use warnings;
+
+# New HTML templates
+
+our @Templates = (
+ { Queue => '0',
+ Name => 'Autoreply in HTML', # loc
+ Description => 'HTML Autoresponse template', # loc
+ Content => q[Subject: AutoReply: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>This message has been automatically generated in response to the
+creation of a trouble ticket regarding <b>{$Ticket->Subject()}</b>,
+a summary of which appears below.</p>
+
+<p>There is no need to reply to this message right now. Your ticket has been
+assigned an ID of <b>{$Ticket->SubjectTag}</b>.</p>
+
+<p>Please include the string <b>{$Ticket->SubjectTag}</b>
+in the subject line of all future correspondence about this issue. To do so,
+you may reply to this message.</p>
+
+<p>Thank you,<br/>
+{$Ticket->QueueObj->CorrespondAddress()}</p>
+
+<hr/>
+{$Transaction->Content(Type => 'text/html')}
+],
+ },
+ { Queue => '0',
+ Name => 'Transaction in HTML', # loc
+ Description => 'HTML transaction template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+
+<b>{$Transaction->CreatedAsString}: Request <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{$Ticket->id}</a> was acted upon by {$Transaction->CreatorObj->Name}.</b>
+<br>
+<table border="0">
+<tr><td align="right"><b>Transaction:</b></td><td>{$Transaction->Description}</td></tr>
+<tr><td align="right"><b>Queue:</b></td><td>{$Ticket->QueueObj->Name}</td></tr>
+<tr><td align="right"><b>Subject:</b></td><td>{$Transaction->Subject || $Ticket->Subject || "(No subject given)"} </td></tr>
+<tr><td align="right"><b>Owner:</b></td><td>{$Ticket->OwnerObj->Name}</td></tr>
+<tr><td align="right"><b>Requestors:</b></td><td>{$Ticket->RequestorAddresses}</td></tr>
+<tr><td align="right"><b>Status:</b></td><td>{$Ticket->Status}</td></tr>
+<tr><td align="right"><b>Ticket URL:</b></td><td><a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a></td></tr>
+</table>
+<br/>
+<br/>
+{$Transaction->Content( Type => "text/html")}
+'
+ },
+ { Queue => '0',
+ Name => 'Admin Correspondence in HTML', # loc
+ Description => 'HTML admin correspondence template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+
+Ticket URL: <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a>
+<br />
+<br />
+{$Transaction->Content(Type => "text/html");}
+'
+ },
+ { Queue => '0',
+ Name => 'Correspondence in HTML', # loc
+ Description => 'HTML correspondence template', # loc
+ Content => 'RT-Attach-Message: yes
+Content-Type: text/html
+
+{$Transaction->Content( Type => "text/html")}
+'
+ },
+ { Queue => '0',
+ Name => 'Admin Comment in HTML', # loc
+ Description => 'HTML admin comment template', # loc
+ Content =>
+'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;}
+RT-Attach-Message: yes
+Content-Type: text/html
+
+<p>This is a comment about <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">ticket {$Ticket->id}</a>. It is not sent to the Requestor(s):</p>
+
+{$Transaction->Content(Type => "text/html")}
+'
+ },
+ { Queue => '0',
+ Name => 'Status Change in HTML', # loc
+ Description => 'HTML Ticket status changed', # loc
+ Content => 'Subject: Status Changed to: {$Transaction->NewValue}
+Content-Type: text/html
+
+<a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a>
+<br/>
+<br/>
+{$Transaction->Content(Type => "text/html")}
+'
+ },
+ { Queue => '0',
+ Name => 'Resolved in HTML', # loc
+ Description => 'HTML Ticket Resolved', # loc
+ Content => 'Subject: Resolved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message.</p>
+'
+ },
+ { Queue => '___Approvals',
+ Name => "New Pending Approval in HTML", # loc
+ Description => "Notify Owners and AdminCcs of new items pending their approval", # loc
+ Content => 'Subject: New Pending Approval: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>There is a new item pending your approval: <b>{$Ticket->Subject()}</b>,
+a summary of which appears below.</p>
+
+<p>Please <a href="{RT->Config->Get(\'WebURL\')}Approvals/Display.html?id={$Ticket->id}">approve
+or reject this ticket</a>, or visit the <a href="{RT->Config->Get(\'WebURL\')}Approvals/">approvals
+overview</a> to batch-process all your pending approvals.</p>
+
+<hr />
+{$Transaction->Content()}
+'
+ },
+ { Queue => '___Approvals',
+ Name => "Approval Passed in HTML", # loc
+ Description =>
+ "Notify Requestor of their ticket has been approved by some approver", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>.
+Other approvals may be pending.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
+ Name => "All Approvals Passed in HTML", # loc
+ Description =>
+ "Notify Requestor of their ticket has been approved by all approvers", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>.
+Its Owner may now start to act on it.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
+ Name => "Approval Rejected in HTML", # loc
+ Description =>
+ "Notify Owner of their rejected ticket", # loc
+ Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>Your ticket has been rejected by <b>{ eval { $Approver->Name } }</b>.</p>
+
+<p>Approver\'s notes:</p>
+<blockquote>{ $Notes }</blockquote>
+'
+ },
+ { Queue => '___Approvals',
+ Name => "Approval Ready for Owner in HTML", # loc
+ Description =>
+ "Notify Owner of their ticket has been approved and is ready to be acted on", # loc
+ Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+Content-Type: text/html
+
+<p>Greetings,</p>
+
+<p>The ticket has been approved, you may now start to act on it.</p>
+
+'
+ },
+);
+
diff --git a/rt/etc/upgrade/4.2.1/content b/rt/etc/upgrade/4.2.1/content
new file mode 100644
index 000000000..64eea9af4
--- /dev/null
+++ b/rt/etc/upgrade/4.2.1/content
@@ -0,0 +1,14 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ my $attr = RT->System->FirstAttribute('BrandedSubjectTag');
+ return 1 unless $attr;
+ my ( $status, $msg ) = $attr->Delete;
+ unless ( $status ) {
+ RT->Logger->error("Couldn't delete System BrandedSubjectTag: $msg");
+ }
+ return 1;
+ },
+);
diff --git a/rt/etc/upgrade/4.2.10/content b/rt/etc/upgrade/4.2.10/content
new file mode 100644
index 000000000..d9aadccd5
--- /dev/null
+++ b/rt/etc/upgrade/4.2.10/content
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ my $attrs = RT::Attributes->new(RT->SystemUser);
+ $attrs->Limit( FIELD => 'Name', VALUE => 'SavedSearch' );
+ while ( my $attr = $attrs->Next ) {
+ my $content = $attr->Content;
+ if ( $content->{ChartStyle} && $content->{ChartStyle} =~ /^(?:pie|bar)$/ ) {
+ $content->{ChartStyle} .= '+table+sql';
+ my ($ret, $msg) = $attr->SetContent($content);
+ unless ( $ret ) {
+ RT->Logger->error("Failed to update ChartStyle for SavedSearch #" . $attr->id . ": $msg");
+ }
+ }
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.2.11/content b/rt/etc/upgrade/4.2.11/content
new file mode 100644
index 000000000..5e43db739
--- /dev/null
+++ b/rt/etc/upgrade/4.2.11/content
@@ -0,0 +1,60 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ # We do the delete in pure SQL because Attribute collections
+ # otherwise attempt to hash everything in memory. As this may
+ # be a large list, do it directly.
+ RT->DatabaseHandle->dbh->do(<<EOSQL);
+ DELETE FROM Attributes
+ WHERE Name = 'DeferredRecipients'
+ AND Content IS NULL
+EOSQL
+ },
+ sub {
+ # Remove globally-granted role rights which couldn't also apply
+ # to some other object. That is, globally granting that
+ # AdminCcs have SuperUser makes no sense.
+
+ # Find rights which apply globally
+ no warnings 'once';
+ my @rights = sort map {$_->{Name}} values %{$RT::ACE::RIGHTS{'RT::System'}};
+
+ # Those are not allowed to be granted on global role groups
+ my $invalid = RT::ACL->new( RT->SystemUser );
+ $invalid->LimitToObject( 'RT::System' );
+ $invalid->LimitToPrincipal( Id => RT::System->RoleGroup($_)->PrincipalId )
+ for RT::System->Roles;
+ $invalid->Limit( FIELD => 'RightName', OPERATOR => 'IN', VALUE => \@rights );
+
+ return unless $invalid->Count;
+
+ # Remove them, warning in the process
+ $RT::Logger->warning("There are invalid global role rights; removing:");
+ while (my $right = $invalid->Next) {
+ $RT::Logger->warning(" ".$right->RightName." granted globally to ".$right->PrincipalObj->Object->Name);
+ my ($ok, $msg) = $right->Delete;
+ $RT::Logger->error("Failed to remove right ".$right->id.": $msg") unless $ok;
+ }
+ },
+ sub {
+ my $txns = RT::Transactions->new(RT->SystemUser);
+ $txns->Limit( FIELD => 'Type', VALUE => 'Forward Transaction' );
+ $txns->Limit( FIELD => 'Type', VALUE => 'Forward Ticket' );
+ while ( my $txn = $txns->Next ) {
+ my $att = $txn->Attachments->First;
+ next unless $att;
+
+ # we only need to process ascii-only strings
+ unless ( $att->Subject =~ /[^\x00-\x7F]/ ) {
+ $att->__Set( Field => 'Subject', Value => Encode::decode("UTF-8", RT::I18N::DecodeMIMEWordsToUTF8($att->Subject, 'Subject')) );
+ }
+ for my $field ( qw/Subject From To Cc Bcc/ ) {
+ next if !$att->GetHeader($field) || $att->GetHeader($field) =~ /[^\x00-\x7F]/;
+ # Subject here is not a typo, because we don't really want to parse email addresses here
+ $att->SetHeader( $field, Encode::decode("UTF-8", RT::I18N::DecodeMIMEWordsToUTF8($att->GetHeader($field), 'Subject')) );
+ }
+ }
+ },
+);
diff --git a/rt/etc/upgrade/4.2.2/content b/rt/etc/upgrade/4.2.2/content
new file mode 100644
index 000000000..762289a0c
--- /dev/null
+++ b/rt/etc/upgrade/4.2.2/content
@@ -0,0 +1,59 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ use RT::CustomFields;
+ my $cfs = RT::CustomFields->new(RT->SystemUser);
+ $cfs->{'find_disabled_rows'} = 1;
+ $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' );
+ while ( my $cf = $cfs->Next ) {
+ my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' );
+ RT->Logger->warning("Update Custom Field LookupType for CF.".$cf->Id." $msg");
+ }
+ return 1;
+ },
+
+ sub {
+ use RT::ObjectCustomFieldValues;
+ my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System);
+ $ocfvs->{'find_expired_rows'} = 1;
+ $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' );
+ while ( my $ocfv = $ocfvs->Next ) {
+ my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' );
+ RT->Logger->warning("Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId'));
+ }
+ return 1;
+ },
+
+ sub {
+ require RT::Scrips;
+ my $scrips = RT::Scrips->new( RT->SystemUser );
+ $scrips->{'find_disabled_rows'} = 1;
+ $scrips->Limit( FIELD => 'Disabled', VALUE => 1 );;
+ while ( my $scrip = $scrips->Next ) {
+ my $id = $scrip->Template;
+ if ( $id =~ /\D/ ) {
+ $RT::Logger->info('Template column for scrip #'. $scrip->id .' already contains characters');
+ next;
+ }
+
+ my $name;
+
+ my $template = RT::Template->new( RT->SystemUser );
+ $template->Load( $id );
+ unless ( $template->id ) {
+ $RT::Logger->error("Scrip #". $scrip->id ." has template set to #$id, but it's not in DB, setting it 'Blank'");
+ $name = 'Blank';
+ } else {
+ $name = $template->Name;
+ }
+
+ my ($status, $msg) = $scrip->_Set( Field => 'Template', Value => $name );
+ unless ( $status ) {
+ $RT::Logger->error("Couldn't set template: $msg");
+ }
+ }
+ },
+);
+
diff --git a/rt/etc/upgrade/4.2.2/schema.mysql b/rt/etc/upgrade/4.2.2/schema.mysql
new file mode 100644
index 000000000..de28cc9e7
--- /dev/null
+++ b/rt/etc/upgrade/4.2.2/schema.mysql
@@ -0,0 +1,5 @@
+ALTER TABLE Users MODIFY EmailAddress varchar(120) CHARACTER SET utf8;
+ALTER TABLE Queues
+ MODIFY Lifecycle varchar(32) CHARACTER SET utf8,
+ MODIFY CorrespondAddress varchar(120) CHARACTER SET utf8,
+ MODIFY CommentAddress varchar(120) CHARACTER SET utf8;
diff --git a/rt/etc/upgrade/4.2.4/content b/rt/etc/upgrade/4.2.4/content
new file mode 100644
index 000000000..c56e36911
--- /dev/null
+++ b/rt/etc/upgrade/4.2.4/content
@@ -0,0 +1,47 @@
+use strict;
+use warnings;
+
+our @ScripActions = (
+ { Name => 'Open Inactive Tickets', # loc
+ Description => 'Open inactive tickets', # loc
+ ExecModule => 'AutoOpenInactive' },
+);
+
+# Ignore the above if there is already an AutoOpenInactive in the
+# database -- i.e. originally a 4.2 install, or someone added one
+# themselves.
+our @Initial;
+push @Initial, sub {
+ my $exist = RT::ScripAction->new( RT->SystemUser );
+ $exist->LoadByCols( ExecModule => 'AutoOpenInactive' );
+ @ScripActions = () if $exist->Id;
+};
+
+push @Initial, sub {
+ my $queue = RT::Queue->new( RT->SystemUser );
+ my ($ok, $msg) = $queue->Load('___Approvals');
+ unless ($ok) {
+ RT->Logger->warning("Unable to load ___Approvals: $msg");
+ return;
+ }
+ unless ($queue->Disabled == 2) {
+ RT->Logger->warning("Going to force ___Approvals queue to be Disabled = 2");
+ ($ok, $msg) = $queue->SetDisabled( 2 );
+ unless ($ok) {
+ RT->Logger->error("Unable to set ___Approvals.Disabled = 2: $msg");
+ return;
+ }
+ }
+
+ unless ($queue->Lifecycle eq "approvals") {
+ RT->Logger->warning("Going to force ___Approvals queue to the approvals lifecycle");
+ ($ok, $msg) = $queue->SetLifecycle( "approvals" );
+ unless ($ok) {
+ RT->Logger->error("Unable to set ___Approvals lifecycle: $msg");
+ return;
+ }
+ }
+
+ return 1;
+
+};
diff --git a/rt/etc/upgrade/4.2.6/content b/rt/etc/upgrade/4.2.6/content
new file mode 100644
index 000000000..e17c5ea24
--- /dev/null
+++ b/rt/etc/upgrade/4.2.6/content
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+our @ScripActions = (
+ { Name => 'Notify Owner or AdminCcs', # loc
+ Description => 'Sends mail to the Owner if set, otherwise administrative Ccs', # loc
+ ExecModule => 'NotifyOwnerOrAdminCc',
+ },
+);
diff --git a/rt/etc/upgrade/4.2.6/schema.mysql b/rt/etc/upgrade/4.2.6/schema.mysql
new file mode 100644
index 000000000..71f8f6440
--- /dev/null
+++ b/rt/etc/upgrade/4.2.6/schema.mysql
@@ -0,0 +1,4 @@
+ALTER TABLE Links
+ DEFAULT CHARACTER SET utf8,
+ MODIFY Base varchar(240) CHARACTER SET utf8 NULL,
+ MODIFY Target varchar(240) CHARACTER SET utf8 NULL;
diff --git a/rt/etc/upgrade/4.2.7/content b/rt/etc/upgrade/4.2.7/content
new file mode 100644
index 000000000..e828cc72c
--- /dev/null
+++ b/rt/etc/upgrade/4.2.7/content
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ # We do the delete in pure SQL because Attribute collections
+ # otherwise attempt to hash everything in memory. As this may
+ # be a large list, do it directly.
+ RT->DatabaseHandle->dbh->do(<<EOSQL);
+ DELETE FROM Attributes
+ WHERE (Name = 'LinkValueTo' OR Name = 'IncludeContentForValue')
+ AND (LENGTH(Content) = 0 OR Content IS NULL)
+EOSQL
+ },
+);
diff --git a/rt/etc/upgrade/4.2.8/content b/rt/etc/upgrade/4.2.8/content
new file mode 100644
index 000000000..64b61def7
--- /dev/null
+++ b/rt/etc/upgrade/4.2.8/content
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+
+our @Initial = (
+ sub {
+ # This upgrade step is identical to the 4.2.7 upgrade, but only
+ # runs on Oracle because 4.2.7 was originally released with
+ # flawed SQL which did not run on Oracle.
+ return unless RT->Config->Get('DatabaseType') eq 'Oracle';
+ RT->DatabaseHandle->dbh->do(<<EOSQL);
+ DELETE FROM Attributes
+ WHERE (Name = 'LinkValueTo' OR Name = 'IncludeContentForValue')
+ AND (LENGTH(Content) = 0 OR Content IS NULL)
+EOSQL
+ },
+);
diff --git a/rt/etc/upgrade/generate-rtaddressregexp.in b/rt/etc/upgrade/generate-rtaddressregexp.in
index a6262dffe..3cdd5a60e 100644
--- a/rt/etc/upgrade/generate-rtaddressregexp.in
+++ b/rt/etc/upgrade/generate-rtaddressregexp.in
@@ -46,18 +46,15 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
-
-$| = 1;
+use RT::Interface::CLI qw(Init);
+Init();
if (my $re = RT->Config->Get('RTAddressRegexp')) {
print "No need to use this script, you already have RTAddressRegexp set to $re\n";
@@ -86,7 +83,7 @@ for my $domain (sort keys %merged) {
}
}
if (@addresses > 1) {
- push @domains, "(?:".join("|", @addresses).")\Q\@".$domain."\E";
+ push @domains, "(?:".join("|", @addresses).")\Q\@$domain\E";
} else {
push @domains, "$addresses[0]\Q\@$domain\E";
}
diff --git a/rt/etc/upgrade/sanity-check-stylesheets.pl b/rt/etc/upgrade/sanity-check-stylesheets.in
index cdc5588df..510abf7db 100644
--- a/rt/etc/upgrade/sanity-check-stylesheets.pl
+++ b/rt/etc/upgrade/sanity-check-stylesheets.in
@@ -1,3 +1,4 @@
+#!@PERL@
# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
@@ -45,34 +46,34 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
-$| = 1;
+use RT::Interface::CLI qw(Init);
+Init();
use RT::Users;
my $users = RT::Users->new( $RT::SystemUser );
$users->UnLimit();
-my @comp_roots = RT::Interface::Web->ComponentRoots;
-my %comp_root_check_cache;
+my @static_roots = RT::Interface::Web->StaticRoots;
+my %static_root_check_cache;
sub stylesheet_exists {
my $stylesheet = shift;
- return $comp_root_check_cache{$stylesheet}
- if exists $comp_root_check_cache{$stylesheet};
+ return $static_root_check_cache{$stylesheet}
+ if exists $static_root_check_cache{$stylesheet};
- for my $comp_root (@comp_roots) {
- return ++$comp_root_check_cache{$stylesheet}
- if -d "$comp_root/NoAuth/css/$stylesheet";
+ for my $static_root (@static_roots) {
+ return ++$static_root_check_cache{$stylesheet}
+ if -d "$static_root/css/$stylesheet";
}
- return $comp_root_check_cache{$stylesheet} = 0;
+ return $static_root_check_cache{$stylesheet} = 0;
}
my $system_stylesheet = RT->Config->Get('WebDefaultStylesheet');
diff --git a/rt/etc/upgrade/shrink_cgm_table.pl b/rt/etc/upgrade/shrink-cgm-table.in
index 85aa30747..8654271b9 100644
--- a/rt/etc/upgrade/shrink_cgm_table.pl
+++ b/rt/etc/upgrade/shrink-cgm-table.in
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!@PERL@
# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
@@ -46,14 +46,15 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
-use 5.8.3;
+use 5.10.1;
use strict;
use warnings;
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
+
+use RT::Interface::CLI qw(Init);
+Init();
use RT::CachedGroupMembers;
my $cgms = RT::CachedGroupMembers->new( RT->SystemUser );
@@ -89,7 +90,6 @@ $cgms->Limit(
ENTRYAGGREGATOR => 'AND',
);
-$| = 1;
my $total = $cgms->Count;
my $i = 0;
@@ -100,7 +100,7 @@ while ( my $rec = FetchNext( $cgms ) ) {
$RT::Handle->BeginTransaction;
my ($status) = $rec->Delete;
unless ($status) {
- print STDERR "Couldn't delete CGM #". $rec->id;
+ $RT::Logger->error( "Couldn't delete CGM #". $rec->id );
exit 1;
}
$RT::Handle->Commit;
diff --git a/rt/etc/upgrade/shrink_transactions_table.pl b/rt/etc/upgrade/shrink-transactions-table.in
index 0d0287f34..8eea6edcd 100644
--- a/rt/etc/upgrade/shrink_transactions_table.pl
+++ b/rt/etc/upgrade/shrink-transactions-table.in
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!@PERL@
# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
@@ -46,14 +46,15 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
-use 5.8.3;
+use 5.10.1;
use strict;
use warnings;
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
+
+use RT::Interface::CLI qw(Init);
+Init();
use RT::Transactions;
my $txns = RT::Transactions->new( RT->SystemUser );
@@ -76,20 +77,21 @@ $txns->Limit(
FIELD => 'Domain',
OPERATOR => '=',
VALUE => 'ACLEquivalence',
+ CASESENSITIVE => 0,
QUOTEVALUE => 1,
ENTRYAGGREGATOR => 'AND',
);
$txns->Limit(
ALIAS => $alias,
- FIELD => 'Type',
+ FIELD => 'Name',
OPERATOR => '=',
VALUE => 'UserEquiv',
QUOTEVALUE => 1,
+ CASESENSITIVE => 0,
ENTRYAGGREGATOR => 'AND',
);
-$| = 1;
my $total = $txns->Count;
my $i = 0;
@@ -100,7 +102,7 @@ while ( my $rec = FetchNext( $txns ) ) {
$RT::Handle->BeginTransaction;
my ($status) = $rec->Delete;
unless ($status) {
- print STDERR "Couldn't delete TXN #". $rec->id;
+ $RT::Logger->error( "Couldn't delete TXN #". $rec->id );
exit 1;
}
$RT::Handle->Commit;
diff --git a/rt/etc/upgrade/split-out-cf-categories.in b/rt/etc/upgrade/split-out-cf-categories.in
index d7dd117a9..6faf29c9e 100644
--- a/rt/etc/upgrade/split-out-cf-categories.in
+++ b/rt/etc/upgrade/split-out-cf-categories.in
@@ -46,18 +46,15 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
-
-$| = 1;
+use RT::Interface::CLI qw(Init);
+Init();
$RT::Handle->BeginTransaction();
@@ -168,4 +165,4 @@ while (my $cf = $CFs->Next ) {
}
$RT::Handle->Commit;
-print "No custom fields with categories found\n" unless $seen; \ No newline at end of file
+print "No custom fields with categories found\n" unless $seen;
diff --git a/rt/etc/upgrade/switch-templates-to.in b/rt/etc/upgrade/switch-templates-to.in
new file mode 100644
index 000000000..384d8f710
--- /dev/null
+++ b/rt/etc/upgrade/switch-templates-to.in
@@ -0,0 +1,145 @@
+#!@PERL@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# 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 }}}
+use 5.10.1;
+use strict;
+use warnings;
+
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
+
+use RT::Interface::CLI qw(Init);
+Init();
+
+my $to = shift || '';
+my $from;
+
+if ($to =~ /html|text/i) {
+ $to = $to =~ /html/i ? 'html' : 'text';
+ $from = $to eq 'html' ? 'text' : 'html';
+} else {
+ print "Usage: $0 [html|text]\n";
+ warn "Please specify if you'd like to switch to HTML or text templates.\n";
+ exit 1;
+}
+
+
+my @templates = (
+ "Autoreply",
+ "Transaction",
+ "Admin Correspondence",
+ "Correspondence",
+ "Admin Comment",
+ "Status Change",
+ "Resolved",
+ "New Pending Approval",
+ "Approval Passed",
+ "All Approvals Passed",
+ "Approval Rejected",
+ "Approval Ready for Owner",
+);
+
+$RT::Handle->BeginTransaction();
+
+use RT::Scrips;
+my $scrips = RT::Scrips->new( RT->SystemUser );
+$scrips->UnLimit;
+
+for (@templates) {
+ $scrips->Limit(
+ FIELD => 'Template',
+ VALUE => ($to eq 'html' ? $_ : "$_ in HTML"),
+ ENTRYAGGREGATOR => 'OR'
+ );
+}
+
+my $switched = 0;
+while ( my $s = $scrips->Next ) {
+ my $new = $s->TemplateObj->Name;
+
+ if ($to eq 'html') {
+ $new .= ' in HTML';
+ } else {
+ $new =~ s/ in HTML$//;
+ }
+
+ print $s->id, ": ", $s->Description, "\n";
+ print " ", $s->TemplateObj->Name, " -> $new\n\n";
+
+ my ($ok, $msg) = $s->SetTemplate($new);
+
+ if ($ok) {
+ $switched++;
+ } else {
+ warn " Couldn't switch templates: $msg\n";
+ }
+}
+
+$RT::Handle->Commit;
+
+if ($switched) {
+ print <<" EOT";
+Switched $switched scrips to $to templates. You should now manually port any
+customizations from the old templates to the new templates.
+ EOT
+ exit 1 if $switched != $scrips->Count;
+}
+elsif ($scrips->Count) {
+ print <<" EOT";
+@{[$scrips->Count]} scrips using $from templates were found, but none were
+successfully switched to $to. See the errors above.
+ EOT
+ exit 1;
+}
+else {
+ print <<" EOT";
+No scrips were found using the $from templates, so none were switched to
+$to templates.
+ EOT
+}
+
diff --git a/rt/etc/upgrade/time-worked-history.in b/rt/etc/upgrade/time-worked-history.in
new file mode 100644
index 000000000..fe216fa22
--- /dev/null
+++ b/rt/etc/upgrade/time-worked-history.in
@@ -0,0 +1,111 @@
+#!@PERL@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# 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 }}}
+use 5.10.1;
+use strict;
+use warnings;
+
+use lib "@LOCAL_LIB_PATH@";
+use lib "@RT_LIB_PATH@";
+
+use RT::Interface::CLI qw(Init);
+Init();
+
+my $dbh = RT->DatabaseHandle->dbh;
+my $ids = $dbh->selectcol_arrayref(
+ "SELECT t1.id FROM Tickets t1, Tickets t2 WHERE t1.id = t2.EffectiveId"
+ ." AND t2.id != t2.EffectiveId AND t2.EffectiveId = t1.id"
+);
+foreach my $id ( @$ids ) {
+ my $t = RT::Ticket->new( RT->SystemUser );
+ $t->Load( $id );
+ unless ( $t->id ) {
+ $RT::Logger->error("Couldn't load ticket #$id");
+ next;
+ }
+
+ fix_time_worked_history($t);
+}
+
+sub fix_time_worked_history {
+ my ($t) = (@_);
+
+ my $history = 0;
+ my $candidate = undef;
+ my @delete = ();
+ my $delete_time = 0;
+
+ my $txns = $t->Transactions;
+ while ( my $txn = $txns->Next ) {
+ if ( $txn->Type =~ /^(Create|Correspond|Comment)$/ ) {
+ $history += $txn->TimeTaken || 0;
+ } elsif ( $txn->Type eq 'Set' && $txn->Field eq 'TimeWorked' ) {
+ $history += $txn->NewValue - $txn->OldValue;
+ $candidate = $txn;
+ } elsif ( $candidate && ($txn->Field||'') eq 'MergedInto' ) {
+ if ($candidate->Creator eq $txn->Creator ) {
+ push @delete, $candidate;
+ $delete_time += $candidate->NewValue - $candidate->OldValue;
+ }
+
+ $candidate = undef;
+ }
+ }
+
+ if ( $history == $t->TimeWorked ) {
+ $RT::Logger->info("Ticket #". $t->id . " has TimeWorked matching history. Skipping");
+ } elsif ( $history - $delete_time == $t->TimeWorked ) {
+ $RT::Logger->warn( "Ticket #". $t->id ." has TimeWorked mismatch. Deleting transactions" );
+ foreach my $dtxn ( @delete ) {
+ my ($status, $msg) = $dtxn->Delete;
+ $RT::Logger->error("Couldn't delete transaction: $msg") unless $status;
+ }
+ } else {
+ $RT::Logger->error( "Ticket #". $t->id ." has TimeWorked mismatch, but we couldn't find correct transactions to delete. Skipping" );
+ }
+}
diff --git a/rt/etc/upgrade/upgrade-articles b/rt/etc/upgrade/upgrade-articles
index ec1b5f450..6ff4a2a13 100755
--- a/rt/etc/upgrade/upgrade-articles
+++ b/rt/etc/upgrade/upgrade-articles
@@ -46,21 +46,18 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "/opt/rt3/local/lib";
use lib "/opt/rt3/lib";
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
+use RT::Interface::CLI qw(Init);
+Init();
-$| = 1;
-
-my $db_name = RT->Config->Get('DatabaseName');
-my $db_type = RT->Config->Get('DatabaseType');
+ my $db_name = RT->Config->Get('DatabaseName');
+ my $db_type = RT->Config->Get('DatabaseType');
my $dbh = $RT::Handle->dbh;
diff --git a/rt/etc/upgrade/upgrade-articles.in b/rt/etc/upgrade/upgrade-articles.in
index 21cba4b8a..742fd17dc 100644
--- a/rt/etc/upgrade/upgrade-articles.in
+++ b/rt/etc/upgrade/upgrade-articles.in
@@ -46,18 +46,15 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
-use RT;
-RT::LoadConfig();
-RT->Config->Set('LogToScreen' => 'debug');
-RT::Init();
-
-$| = 1;
+use RT::Interface::CLI qw(Init);
+Init();
my $db_name = RT->Config->Get('DatabaseName');
my $db_type = RT->Config->Get('DatabaseType');
diff --git a/rt/etc/upgrade/vulnerable-passwords.in b/rt/etc/upgrade/vulnerable-passwords.in
index b00625c7e..1ccf0a180 100755
--- a/rt/etc/upgrade/vulnerable-passwords.in
+++ b/rt/etc/upgrade/vulnerable-passwords.in
@@ -46,15 +46,14 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
+use 5.10.1;
use strict;
use warnings;
use lib "@LOCAL_LIB_PATH@";
use lib "@RT_LIB_PATH@";
-use RT;
-RT::LoadConfig;
-RT::Init;
+use RT -init;
$| = 1;