From 320f00929001b075300be1ef185a04ce030223fd Mon Sep 17 00:00:00 2001 From: Mikal Kolbein Gule Date: Thu, 16 Jan 2014 09:22:36 +0100 Subject: [PATCH] Upgrade to 4.2.2 --- bin/rt | 77 +- bin/rt-crontool | 2 +- bin/rt-mailgate | 2 +- docs/README | 2 +- docs/UPGRADING-3.8 | 6 +- docs/UPGRADING-4.2 | 8 + docs/automating_rt.pod | 234 + docs/customizing/lifecycles.pod | 12 +- etc/RT_Config.pm | 13 +- etc/acl.mysql | 5 +- etc/initialdata | 4 +- etc/schema.mysql | 6 +- etc/upgrade/3.7.19/content | 13 +- etc/upgrade/3.8-ical-extension | 2 +- etc/upgrade/4.0.18/content | 14 + etc/upgrade/4.0.19/content | 29 + etc/upgrade/4.0.19/schema.mysql | 5 + etc/upgrade/4.1.1/schema.Oracle | 2 +- etc/upgrade/4.1.13/backcompat | 3 + etc/upgrade/4.1.22/schema.Oracle | 2 +- etc/upgrade/4.1.23/indexes | 13 +- etc/upgrade/4.1.5/content | 1 + etc/upgrade/4.1.5/schema.Oracle | 7 +- etc/upgrade/4.2.1/content | 14 + etc/upgrade/4.2.2/content | 59 + etc/upgrade/4.2.2/schema.mysql | 5 + etc/upgrade/generate-rtaddressregexp | 2 +- etc/upgrade/sanity-check-stylesheets.pl | 2 +- etc/upgrade/shrink_cgm_table.pl | 2 +- etc/upgrade/shrink_transactions_table.pl | 2 +- etc/upgrade/split-out-cf-categories | 2 +- etc/upgrade/switch-templates-to | 2 +- etc/upgrade/time-worked-history.pl | 2 +- etc/upgrade/upgrade-articles | 4 +- etc/upgrade/upgrade-mysql-schema.pl | 8 +- etc/upgrade/vulnerable-passwords | 2 +- lib/RT.pm | 6 +- lib/RT/ACE.pm | 2 +- lib/RT/ACL.pm | 2 +- lib/RT/Action.pm | 2 +- lib/RT/Action/AutoOpen.pm | 2 +- lib/RT/Action/AutoOpenInactive.pm | 2 +- lib/RT/Action/Autoreply.pm | 2 +- lib/RT/Action/CreateTickets.pm | 2 +- lib/RT/Action/EscalatePriority.pm | 2 +- lib/RT/Action/ExtractSubjectTag.pm | 2 +- lib/RT/Action/LinearEscalate.pm | 2 +- lib/RT/Action/Notify.pm | 2 +- lib/RT/Action/NotifyAsComment.pm | 2 +- lib/RT/Action/NotifyGroup.pm | 2 +- lib/RT/Action/NotifyGroupAsComment.pm | 2 +- lib/RT/Action/OpenOnStarted.pm | 2 +- lib/RT/Action/RecordComment.pm | 2 +- lib/RT/Action/RecordCorrespondence.pm | 2 +- lib/RT/Action/SendEmail.pm | 2 +- lib/RT/Action/SendForward.pm | 2 +- lib/RT/Action/SetPriority.pm | 2 +- lib/RT/Action/SetStatus.pm | 2 +- lib/RT/Action/UserDefined.pm | 2 +- lib/RT/Approval.pm | 2 +- lib/RT/Approval/Rule.pm | 2 +- lib/RT/Approval/Rule/Created.pm | 2 +- lib/RT/Approval/Rule/NewPending.pm | 2 +- lib/RT/Approval/Rule/Passed.pm | 2 +- lib/RT/Approval/Rule/Rejected.pm | 2 +- lib/RT/Article.pm | 2 +- lib/RT/Articles.pm | 2 +- lib/RT/Attachment.pm | 2 +- lib/RT/Attachments.pm | 2 +- lib/RT/Attribute.pm | 2 +- lib/RT/Attributes.pm | 2 +- lib/RT/Base.pm | 2 +- lib/RT/CachedGroupMember.pm | 2 +- lib/RT/CachedGroupMembers.pm | 2 +- lib/RT/Class.pm | 28 +- lib/RT/Classes.pm | 2 +- lib/RT/Condition.pm | 2 +- lib/RT/Condition/AnyTransaction.pm | 2 +- lib/RT/Condition/BeforeDue.pm | 2 +- lib/RT/Condition/CloseTicket.pm | 2 +- lib/RT/Condition/Overdue.pm | 2 +- lib/RT/Condition/OwnerChange.pm | 2 +- lib/RT/Condition/PriorityChange.pm | 2 +- lib/RT/Condition/PriorityExceeds.pm | 2 +- lib/RT/Condition/QueueChange.pm | 2 +- lib/RT/Condition/ReopenTicket.pm | 2 +- lib/RT/Condition/StatusChange.pm | 2 +- lib/RT/Condition/UserDefined.pm | 2 +- lib/RT/Config.pm | 2 +- lib/RT/Crypt.pm | 2 +- lib/RT/Crypt/GnuPG.pm | 8 +- lib/RT/Crypt/GnuPG/CRLFHandle.pm | 2 +- lib/RT/Crypt/Role.pm | 2 +- lib/RT/Crypt/SMIME.pm | 8 +- lib/RT/CurrentUser.pm | 2 +- lib/RT/CustomField.pm | 15 +- lib/RT/CustomFieldValue.pm | 2 +- lib/RT/CustomFieldValues.pm | 2 +- lib/RT/CustomFieldValues/External.pm | 2 +- lib/RT/CustomFieldValues/Groups.pm | 2 +- lib/RT/CustomFields.pm | 2 +- lib/RT/Dashboard.pm | 20 +- lib/RT/Dashboard/Mailer.pm | 9 +- lib/RT/Dashboards.pm | 2 +- lib/RT/Date.pm | 33 +- lib/RT/DependencyWalker.pm | 4 +- lib/RT/DependencyWalker/FindDependencies.pm | 65 + lib/RT/EmailParser.pm | 31 +- lib/RT/Generated.pm | 4 +- lib/RT/Generated.pm.in | 2 +- lib/RT/Graph/Tickets.pm | 2 +- lib/RT/Group.pm | 32 +- lib/RT/GroupMember.pm | 2 +- lib/RT/GroupMembers.pm | 2 +- lib/RT/Groups.pm | 2 +- lib/RT/Handle.pm | 58 +- lib/RT/I18N.pm | 2 +- lib/RT/I18N/cs.pm | 2 +- lib/RT/I18N/de.pm | 2 +- lib/RT/I18N/fr.pm | 2 +- lib/RT/I18N/i_default.pm | 2 +- lib/RT/I18N/ru.pm | 2 +- lib/RT/Installer.pm | 2 +- lib/RT/Interface/CLI.pm | 2 +- lib/RT/Interface/Email.pm | 40 +- lib/RT/Interface/Email/Auth/Crypt.pm | 2 +- lib/RT/Interface/Email/Auth/MailFrom.pm | 2 +- lib/RT/Interface/REST.pm | 3 +- lib/RT/Interface/Web.pm | 85 +- lib/RT/Interface/Web/Handler.pm | 2 +- lib/RT/Interface/Web/Menu.pm | 2 +- lib/RT/Interface/Web/QueryBuilder.pm | 2 +- lib/RT/Interface/Web/QueryBuilder/Tree.pm | 2 +- lib/RT/Interface/Web/Request.pm | 2 +- lib/RT/Interface/Web/Session.pm | 4 +- lib/RT/Lifecycle.pm | 2 +- lib/RT/Lifecycle/Ticket.pm | 2 +- lib/RT/Link.pm | 2 +- lib/RT/Links.pm | 2 +- lib/RT/Migrate.pm | 13 +- lib/RT/Migrate/Importer.pm | 4 +- lib/RT/Migrate/Importer/File.pm | 2 +- lib/RT/Migrate/Incremental.pm | 39 +- lib/RT/Migrate/Serializer.pm | 7 +- lib/RT/Migrate/Serializer/File.pm | 2 +- .../Migrate/Serializer/IncrementalRecord.pm | 2 +- .../Migrate/Serializer/IncrementalRecords.pm | 2 +- lib/RT/ObjectClass.pm | 2 +- lib/RT/ObjectClasses.pm | 2 +- lib/RT/ObjectCustomField.pm | 2 +- lib/RT/ObjectCustomFieldValue.pm | 2 +- lib/RT/ObjectCustomFieldValues.pm | 2 +- lib/RT/ObjectCustomFields.pm | 2 +- lib/RT/ObjectScrip.pm | 2 +- lib/RT/ObjectScrips.pm | 2 +- lib/RT/ObjectTopic.pm | 2 +- lib/RT/ObjectTopics.pm | 2 +- lib/RT/PlackRunner.pm | 2 +- lib/RT/Plugin.pm | 2 +- lib/RT/Pod/HTML.pm | 8 +- lib/RT/Pod/HTMLBatch.pm | 2 +- lib/RT/Pod/Search.pm | 2 +- lib/RT/Principal.pm | 2 +- lib/RT/Principals.pm | 2 +- lib/RT/Queue.pm | 68 +- lib/RT/Queues.pm | 2 +- lib/RT/Record.pm | 42 +- lib/RT/Record/AddAndSort.pm | 2 +- lib/RT/Record/Role.pm | 2 +- lib/RT/Record/Role/Lifecycle.pm | 2 +- lib/RT/Record/Role/Links.pm | 2 +- lib/RT/Record/Role/Rights.pm | 2 +- lib/RT/Record/Role/Roles.pm | 2 +- lib/RT/Record/Role/Status.pm | 2 +- lib/RT/Reminders.pm | 2 +- lib/RT/Report/Tickets.pm | 8 +- lib/RT/Report/Tickets/Entry.pm | 2 +- lib/RT/Rule.pm | 2 +- lib/RT/Ruleset.pm | 2 +- lib/RT/SQL.pm | 2 +- lib/RT/SavedSearch.pm | 2 +- lib/RT/SavedSearches.pm | 2 +- lib/RT/Scrip.pm | 2 +- lib/RT/ScripAction.pm | 4 +- lib/RT/ScripActions.pm | 2 +- lib/RT/ScripCondition.pm | 2 +- lib/RT/ScripConditions.pm | 2 +- lib/RT/Scrips.pm | 2 +- lib/RT/Search.pm | 2 +- lib/RT/Search/ActiveTicketsInQueue.pm | 2 +- lib/RT/Search/FromSQL.pm | 2 +- lib/RT/Search/Simple.pm | 2 +- lib/RT/SearchBuilder.pm | 2 +- lib/RT/SearchBuilder/AddAndSort.pm | 2 +- lib/RT/SearchBuilder/Role.pm | 2 +- lib/RT/SearchBuilder/Role/Roles.pm | 2 +- lib/RT/SharedSetting.pm | 2 +- lib/RT/SharedSettings.pm | 2 +- lib/RT/Shredder.pm | 17 +- lib/RT/Shredder/ACE.pm | 2 +- lib/RT/Shredder/Attachment.pm | 2 +- lib/RT/Shredder/CachedGroupMember.pm | 2 +- lib/RT/Shredder/Constants.pm | 2 +- lib/RT/Shredder/CustomField.pm | 2 +- lib/RT/Shredder/CustomFieldValue.pm | 2 +- lib/RT/Shredder/Dependencies.pm | 2 +- lib/RT/Shredder/Dependency.pm | 2 +- lib/RT/Shredder/Exceptions.pm | 20 +- lib/RT/Shredder/Group.pm | 2 +- lib/RT/Shredder/GroupMember.pm | 2 +- lib/RT/Shredder/Link.pm | 2 +- lib/RT/Shredder/ObjectCustomFieldValue.pm | 2 +- lib/RT/Shredder/POD.pm | 2 +- lib/RT/Shredder/Plugin.pm | 2 +- lib/RT/Shredder/Plugin/Attachments.pm | 2 +- lib/RT/Shredder/Plugin/Base.pm | 2 +- lib/RT/Shredder/Plugin/Base/Dump.pm | 2 +- lib/RT/Shredder/Plugin/Base/Search.pm | 2 +- lib/RT/Shredder/Plugin/Objects.pm | 2 +- lib/RT/Shredder/Plugin/SQLDump.pm | 2 +- lib/RT/Shredder/Plugin/Summary.pm | 2 +- lib/RT/Shredder/Plugin/Tickets.pm | 2 +- lib/RT/Shredder/Plugin/Users.pm | 2 +- lib/RT/Shredder/Principal.pm | 2 +- lib/RT/Shredder/Queue.pm | 2 +- lib/RT/Shredder/Record.pm | 2 +- lib/RT/Shredder/Scrip.pm | 2 +- lib/RT/Shredder/ScripAction.pm | 2 +- lib/RT/Shredder/ScripCondition.pm | 2 +- lib/RT/Shredder/Template.pm | 2 +- lib/RT/Shredder/Ticket.pm | 2 +- lib/RT/Shredder/Transaction.pm | 2 +- lib/RT/Shredder/User.pm | 2 +- lib/RT/Squish.pm | 2 +- lib/RT/Squish/CSS.pm | 2 +- lib/RT/Squish/JS.pm | 2 +- lib/RT/System.pm | 24 +- lib/RT/Template.pm | 23 +- lib/RT/Templates.pm | 2 +- lib/RT/Test.pm | 10 +- lib/RT/Test/Apache.pm | 2 +- lib/RT/Test/Email.pm | 2 +- lib/RT/Test/GnuPG.pm | 2 +- lib/RT/Test/SMIME.pm | 2 +- lib/RT/Test/Shredder.pm | 2 +- lib/RT/Test/Web.pm | 2 +- lib/RT/Ticket.pm | 44 +- lib/RT/Tickets.pm | 38 +- lib/RT/Topic.pm | 2 +- lib/RT/Topics.pm | 2 +- lib/RT/Transaction.pm | 159 +- lib/RT/Transactions.pm | 2 +- lib/RT/URI.pm | 2 +- lib/RT/URI/a.pm | 2 +- lib/RT/URI/base.pm | 2 +- lib/RT/URI/fsck_com_article.pm | 2 +- lib/RT/URI/fsck_com_rt.pm | 2 +- lib/RT/URI/t.pm | 2 +- lib/RT/User.pm | 33 +- lib/RT/Users.pm | 2 +- lib/RT/Util.pm | 2 +- local/bin/rt-count | 0 sbin/rt-attributes-viewer | 2 +- sbin/rt-clean-sessions | 2 +- sbin/rt-dump-metadata | 183 +- sbin/rt-email-dashboards | 2 +- sbin/rt-email-digest | 2 +- sbin/rt-email-group-admin | 2 +- sbin/rt-fulltext-indexer | 2 +- sbin/rt-importer | 282 + sbin/rt-preferences-viewer | 2 +- sbin/rt-serializer | 397 + sbin/rt-server | 4 +- sbin/rt-server.fcgi | 4 +- sbin/rt-session-viewer | 2 +- sbin/rt-setup-database | 17 +- sbin/rt-setup-fulltext-index | 2 +- sbin/rt-shredder | 2 +- sbin/rt-test-dependencies | 2 +- sbin/rt-validate-aliases | 4 +- sbin/rt-validator | 2 +- sbin/standalone_httpd | 4 +- .../Admin/Articles/Classes/CustomFields.html | 2 +- .../Admin/Articles/Classes/GroupRights.html | 2 +- share/html/Admin/Articles/Classes/Modify.html | 2 +- .../html/Admin/Articles/Classes/Objects.html | 2 +- share/html/Admin/Articles/Classes/Topics.html | 2 +- .../Admin/Articles/Classes/UserRights.html | 2 +- share/html/Admin/Articles/Classes/index.html | 2 +- share/html/Admin/Articles/Elements/Topics | 2 +- share/html/Admin/Articles/index.html | 2 +- .../html/Admin/CustomFields/GroupRights.html | 2 +- share/html/Admin/CustomFields/Modify.html | 2 +- share/html/Admin/CustomFields/Objects.html | 2 +- share/html/Admin/CustomFields/UserRights.html | 2 +- share/html/Admin/CustomFields/index.html | 2 +- share/html/Admin/Elements/AddCustomFieldValue | 2 +- .../Admin/Elements/ConfigureDashboardsInMenu | 2 +- share/html/Admin/Elements/ConfigureMyRT | 2 +- share/html/Admin/Elements/EditCustomField | 2 +- .../html/Admin/Elements/EditCustomFieldValues | 2 +- .../Elements/EditCustomFieldValuesSource | 2 +- share/html/Admin/Elements/EditCustomFields | 2 +- .../html/Admin/Elements/EditQueueWatcherGroup | 2 +- share/html/Admin/Elements/EditQueueWatchers | 2 +- share/html/Admin/Elements/EditRights | 2 +- .../Admin/Elements/EditRightsCategoryTabs | 22 +- share/html/Admin/Elements/EditScrips | 6 +- share/html/Admin/Elements/EditTemplates | 2 +- share/html/Admin/Elements/Header | 2 +- share/html/Admin/Elements/LoggingSummary | 2 +- share/html/Admin/Elements/MembershipsPage | 2 +- share/html/Admin/Elements/ModifyTemplate | 2 +- share/html/Admin/Elements/Portal | 2 +- share/html/Admin/Elements/SelectCustomField | 2 +- .../Elements/SelectCustomFieldLookupType | 2 +- .../Elements/SelectCustomFieldRenderType | 7 +- .../html/Admin/Elements/SelectCustomFieldType | 2 +- share/html/Admin/Elements/SelectGroups | 2 +- .../html/Admin/Elements/SelectNewGroupMembers | 2 +- share/html/Admin/Elements/SelectScripAction | 2 +- .../html/Admin/Elements/SelectScripCondition | 2 +- share/html/Admin/Elements/SelectStage | 2 +- share/html/Admin/Elements/SelectStageForAdded | 2 +- share/html/Admin/Elements/SelectUsers | 2 +- share/html/Admin/Elements/ShowKeyInfo | 2 +- share/html/Admin/Elements/UpgradeHistory | 2 +- share/html/Admin/Elements/UpgradeHistoryRow | 2 +- .../Global/CustomFields/Class-Article.html | 2 +- .../Admin/Global/CustomFields/Groups.html | 2 +- .../Global/CustomFields/Queue-Tickets.html | 2 +- .../CustomFields/Queue-Transactions.html | 2 +- .../Admin/Global/CustomFields/Queues.html | 2 +- .../html/Admin/Global/CustomFields/Users.html | 2 +- .../html/Admin/Global/CustomFields/index.html | 2 +- share/html/Admin/Global/DashboardsInMenu.html | 2 +- share/html/Admin/Global/GroupRights.html | 2 +- share/html/Admin/Global/MyRT.html | 2 +- share/html/Admin/Global/Scrips.html | 2 +- share/html/Admin/Global/Template.html | 2 +- share/html/Admin/Global/Templates.html | 2 +- share/html/Admin/Global/Topics.html | 2 +- share/html/Admin/Global/UserRights.html | 2 +- share/html/Admin/Global/index.html | 2 +- share/html/Admin/Groups/GroupRights.html | 2 +- share/html/Admin/Groups/History.html | 2 +- share/html/Admin/Groups/Members.html | 2 +- share/html/Admin/Groups/Memberships.html | 2 +- share/html/Admin/Groups/Modify.html | 4 +- share/html/Admin/Groups/UserRights.html | 2 +- share/html/Admin/Groups/index.html | 2 +- share/html/Admin/Queues/CustomField.html | 2 +- share/html/Admin/Queues/CustomFields.html | 2 +- share/html/Admin/Queues/GroupRights.html | 2 +- share/html/Admin/Queues/History.html | 2 +- share/html/Admin/Queues/Modify.html | 4 +- share/html/Admin/Queues/People.html | 2 +- share/html/Admin/Queues/Scrips.html | 2 +- share/html/Admin/Queues/Template.html | 2 +- share/html/Admin/Queues/Templates.html | 2 +- share/html/Admin/Queues/UserRights.html | 2 +- share/html/Admin/Queues/index.html | 2 +- share/html/Admin/Scrips/Create.html | 2 +- share/html/Admin/Scrips/Elements/EditBasics | 2 +- .../html/Admin/Scrips/Elements/EditCustomCode | 2 +- .../html/Admin/Scrips/Elements/SelectTemplate | 2 +- share/html/Admin/Scrips/Modify.html | 2 +- share/html/Admin/Scrips/Objects.html | 2 +- share/html/Admin/Scrips/index.html | 2 +- share/html/Admin/Tools/Configuration.html | 2 +- share/html/Admin/Tools/Queries.html | 2 +- .../html/Admin/Tools/Shredder/Dumps/dhandler | 2 +- .../Tools/Shredder/Elements/DumpFileLink | 2 +- .../Tools/Shredder/Elements/Error/NoRights | 2 +- .../Tools/Shredder/Elements/Error/NoStorage | 2 +- .../Shredder/Elements/Object/RT--Attachment | 2 +- .../Tools/Shredder/Elements/Object/RT--Ticket | 2 +- .../Tools/Shredder/Elements/Object/RT--User | 2 +- .../Tools/Shredder/Elements/ObjectCheckBox | 2 +- .../Tools/Shredder/Elements/PluginArguments | 2 +- .../Admin/Tools/Shredder/Elements/PluginHelp | 2 +- .../Tools/Shredder/Elements/SelectObjects | 2 +- .../Tools/Shredder/Elements/SelectPlugin | 2 +- share/html/Admin/Tools/Shredder/autohandler | 2 +- share/html/Admin/Tools/Shredder/index.html | 2 +- share/html/Admin/Tools/Theme.html | 36 +- share/html/Admin/Tools/index.html | 2 +- share/html/Admin/Users/CustomFields.html | 2 +- share/html/Admin/Users/DashboardsInMenu.html | 2 +- share/html/Admin/Users/History.html | 2 +- share/html/Admin/Users/Keys.html | 2 +- share/html/Admin/Users/Memberships.html | 2 +- share/html/Admin/Users/Modify.html | 2 +- share/html/Admin/Users/MyRT.html | 5 +- share/html/Admin/Users/index.html | 2 +- share/html/Admin/autohandler | 2 +- share/html/Admin/index.html | 2 +- share/html/Approvals/Display.html | 2 +- share/html/Approvals/Elements/Approve | 2 +- .../html/Approvals/Elements/PendingMyApproval | 2 +- share/html/Approvals/Elements/ShowDependency | 2 +- share/html/Approvals/autohandler | 2 +- share/html/Approvals/index.html | 2 +- share/html/Articles/Article/Delete.html | 2 +- share/html/Articles/Article/Display.html | 2 +- share/html/Articles/Article/Edit.html | 2 +- .../html/Articles/Article/Elements/EditBasics | 2 +- .../Article/Elements/EditCustomFields | 2 +- .../html/Articles/Article/Elements/EditLinks | 2 +- .../html/Articles/Article/Elements/EditTopics | 2 +- .../Article/Elements/LinkEntryInstructions | 2 +- .../Articles/Article/Elements/Preformatted | 2 +- .../Article/Elements/SearchByCustomField | 2 +- .../Article/Elements/SelectSavedSearches | 2 +- .../Article/Elements/SelectSearchPrivacy | 2 +- .../html/Articles/Article/Elements/ShowLinks | 2 +- .../Article/Elements/ShowSavedSearches | 2 +- .../Article/Elements/ShowSearchCriteria | 2 +- .../html/Articles/Article/Elements/ShowTopics | 2 +- .../Articles/Article/ExtractFromTicket.html | 2 +- .../Articles/Article/ExtractIntoClass.html | 4 +- .../Articles/Article/ExtractIntoTopic.html | 2 +- share/html/Articles/Article/History.html | 2 +- share/html/Articles/Article/PreCreate.html | 2 +- share/html/Articles/Article/Search.html | 2 +- share/html/Articles/Elements/BeforeMessageBox | 2 +- share/html/Articles/Elements/CheckSkipCreate | 2 +- share/html/Articles/Elements/CreateArticle | 2 +- share/html/Articles/Elements/GotoArticle | 2 +- share/html/Articles/Elements/IncludeArticle | 2 +- share/html/Articles/Elements/MaybeNeedsSetup | 2 +- share/html/Articles/Elements/NeedsSetup | 2 +- share/html/Articles/Elements/NewestArticles | 2 +- share/html/Articles/Elements/QuickSearch | 2 +- share/html/Articles/Elements/SelectClass | 2 +- share/html/Articles/Elements/ShowTopic | 2 +- share/html/Articles/Elements/ShowTopicLink | 2 +- share/html/Articles/Elements/SubjectOverride | 2 +- share/html/Articles/Elements/UpdatedArticles | 2 +- share/html/Articles/Topics.html | 2 +- share/html/Articles/index.html | 2 +- .../Dashboards/Elements/DashboardsForObject | 2 +- share/html/Dashboards/Elements/Deleted | 2 +- share/html/Dashboards/Elements/HiddenSearches | 2 +- .../html/Dashboards/Elements/ListOfDashboards | 2 +- share/html/Dashboards/Elements/SelectPrivacy | 2 +- share/html/Dashboards/Elements/ShowDashboards | 2 +- .../Dashboards/Elements/ShowPortlet/component | 2 +- .../Dashboards/Elements/ShowPortlet/dashboard | 2 +- .../Dashboards/Elements/ShowPortlet/search | 2 +- share/html/Dashboards/Modify.html | 2 +- share/html/Dashboards/Queries.html | 2 +- share/html/Dashboards/Render.html | 2 +- share/html/Dashboards/Subscription.html | 2 +- share/html/Dashboards/dhandler | 2 +- share/html/Dashboards/index.html | 2 +- share/html/Download/CustomFieldValue/dhandler | 2 +- share/html/Elements/AddLinks | 2 +- share/html/Elements/BulkCustomFields | 27 +- share/html/Elements/BulkLinks | 4 +- share/html/Elements/CSRF | 2 +- share/html/Elements/Callback | 2 +- share/html/Elements/Checkbox | 2 +- share/html/Elements/CollectionAsTable/Header | 10 +- .../Elements/CollectionAsTable/ParseFormat | 3 +- share/html/Elements/CollectionAsTable/Row | 2 +- share/html/Elements/CollectionList | 2 +- share/html/Elements/CollectionListPaging | 2 +- share/html/Elements/ColumnMap | 12 +- share/html/Elements/CreateTicket | 2 +- share/html/Elements/Crypt/KeyIssues | 2 +- .../Elements/Crypt/SelectKeyForEncryption | 2 +- share/html/Elements/Crypt/SelectKeyForSigning | 2 +- share/html/Elements/Crypt/SignEncryptWidget | 2 +- share/html/Elements/CryptStatus | 2 +- share/html/Elements/Dashboards | 2 +- share/html/Elements/EditCustomField | 2 +- .../html/Elements/EditCustomFieldAutocomplete | 2 +- share/html/Elements/EditCustomFieldBinary | 2 +- share/html/Elements/EditCustomFieldCombobox | 2 +- .../Elements/EditCustomFieldCustomGroupings | 2 +- share/html/Elements/EditCustomFieldDate | 2 +- share/html/Elements/EditCustomFieldDateTime | 2 +- share/html/Elements/EditCustomFieldFreeform | 2 +- share/html/Elements/EditCustomFieldIPAddress | 2 +- .../Elements/EditCustomFieldIPAddressRange | 2 +- share/html/Elements/EditCustomFieldImage | 2 +- share/html/Elements/EditCustomFieldSelect | 60 +- share/html/Elements/EditCustomFieldText | 2 +- share/html/Elements/EditCustomFieldWikitext | 2 +- share/html/Elements/EditCustomFields | 4 +- share/html/Elements/EditLinks | 2 +- share/html/Elements/EditPassword | 2 +- share/html/Elements/EditTimeValue | 2 +- share/html/Elements/EmailInput | 2 +- share/html/Elements/Error | 2 +- share/html/Elements/FindUser | 2 +- share/html/Elements/FoldStanzaJS | 6 +- share/html/Elements/Footer | 4 +- share/html/Elements/Framekiller | 2 +- share/html/Elements/GotoTicket | 2 +- share/html/Elements/GotoUser | 2 +- share/html/Elements/Header | 6 +- share/html/Elements/HeaderJavascript | 4 +- share/html/Elements/JavascriptConfig | 2 +- share/html/Elements/ListActions | 2 +- share/html/Elements/ListMenu | 2 +- share/html/Elements/Login | 2 +- share/html/Elements/LoginHelp | 6 +- share/html/Elements/LoginRedirectWarning | 2 +- share/html/Elements/Logo | 2 +- share/html/Elements/MakeClicky | 2 +- share/html/Elements/Menu | 2 +- share/html/Elements/MessageBox | 22 +- share/html/Elements/MyAdminQueues | 2 +- share/html/Elements/MyRT | 2 +- share/html/Elements/MyReminders | 2 +- share/html/Elements/MySupportQueues | 2 +- share/html/Elements/PageLayout | 2 +- share/html/Elements/PersonalQuickbar | 2 +- share/html/Elements/QueriesAsComment | 2 +- share/html/Elements/QueryString | 2 +- share/html/Elements/QueueSummaryByLifecycle | 2 +- share/html/Elements/QueueSummaryByStatus | 2 +- share/html/Elements/QuickCreate | 2 +- share/html/Elements/Quicksearch | 2 +- share/html/Elements/RT__Article/ColumnMap | 2 +- share/html/Elements/RT__Class/ColumnMap | 2 +- share/html/Elements/RT__CustomField/ColumnMap | 4 +- share/html/Elements/RT__Dashboard/ColumnMap | 2 +- share/html/Elements/RT__Group/ColumnMap | 2 +- share/html/Elements/RT__Queue/ColumnMap | 2 +- share/html/Elements/RT__SavedSearch/ColumnMap | 2 +- share/html/Elements/RT__Scrip/ColumnMap | 4 +- share/html/Elements/RT__Template/ColumnMap | 2 +- share/html/Elements/RT__Ticket/ColumnMap | 2 +- share/html/Elements/RT__User/ColumnMap | 7 +- share/html/Elements/Refresh | 2 +- share/html/Elements/RefreshHomepage | 2 +- share/html/Elements/SavedSearches | 2 +- share/html/Elements/ScrubHTML | 2 +- share/html/Elements/Section | 2 +- share/html/Elements/SelectAttachmentField | 2 +- share/html/Elements/SelectBoolean | 2 +- share/html/Elements/SelectCustomFieldOperator | 2 +- share/html/Elements/SelectCustomFieldValue | 15 +- share/html/Elements/SelectDate | 2 +- share/html/Elements/SelectDateRelation | 2 +- share/html/Elements/SelectDateType | 2 +- share/html/Elements/SelectEqualityOperator | 2 +- share/html/Elements/SelectGroups | 2 +- share/html/Elements/SelectIPRelation | 2 +- share/html/Elements/SelectLang | 2 +- share/html/Elements/SelectMatch | 2 +- share/html/Elements/SelectNewTicketQueue | 2 +- share/html/Elements/SelectObject | 19 +- share/html/Elements/SelectOwner | 2 +- share/html/Elements/SelectOwnerAutocomplete | 2 +- share/html/Elements/SelectOwnerDropdown | 2 +- share/html/Elements/SelectPriority | 2 +- share/html/Elements/SelectQueue | 2 +- share/html/Elements/SelectResultsPerPage | 2 +- share/html/Elements/SelectStatus | 2 +- share/html/Elements/SelectTimeUnits | 2 +- share/html/Elements/SelectTimezone | 2 +- share/html/Elements/SelectUsers | 2 +- share/html/Elements/SelectWatcherType | 2 +- share/html/Elements/SetupSessionCookie | 2 +- share/html/Elements/ShowCustomFieldBinary | 2 +- .../Elements/ShowCustomFieldCustomGroupings | 2 +- share/html/Elements/ShowCustomFieldDate | 2 +- share/html/Elements/ShowCustomFieldDateTime | 2 +- share/html/Elements/ShowCustomFieldImage | 2 +- share/html/Elements/ShowCustomFieldText | 2 +- share/html/Elements/ShowCustomFieldWikitext | 2 +- share/html/Elements/ShowCustomFields | 2 +- share/html/Elements/ShowHistory | 6 +- share/html/Elements/ShowLink | 2 +- share/html/Elements/ShowLinks | 2 +- share/html/Elements/ShowLinksOfType | 2 +- share/html/Elements/ShowMemberships | 2 +- share/html/Elements/ShowMessageHeaders | 2 +- share/html/Elements/ShowMessageStanza | 2 +- share/html/Elements/ShowPrincipal | 2 +- share/html/Elements/ShowRecord | 2 +- share/html/Elements/ShowRelationLabel | 2 +- share/html/Elements/ShowReminders | 2 +- share/html/Elements/ShowSearch | 2 +- share/html/Elements/ShowTransaction | 7 +- .../html/Elements/ShowTransactionAttachments | 2 +- share/html/Elements/ShowUser | 2 +- share/html/Elements/ShowUserEmailFrequency | 2 +- share/html/Elements/SimpleSearch | 2 +- share/html/Elements/Submit | 2 +- share/html/Elements/Tabs | 8 +- share/html/Elements/TicketList | 2 +- share/html/Elements/TitleBox | 2 +- share/html/Elements/TitleBoxEnd | 2 +- share/html/Elements/TitleBoxStart | 2 +- share/html/Elements/ValidateCustomFields | 8 +- share/html/Elements/WidgetBar | 2 +- share/html/Errors/WebRemoteUser/Deauthorized | 2 +- .../html/Errors/WebRemoteUser/NoInternalUser | 2 +- share/html/Errors/WebRemoteUser/NoRemoteUser | 2 +- .../UserAutocreateDefaultsOnLogin | 2 +- share/html/Errors/WebRemoteUser/Wrapper | 2 +- .../Helpers/Autocomplete/CustomFieldValues | 16 +- share/html/Helpers/Autocomplete/Groups | 2 +- share/html/Helpers/Autocomplete/Owners | 2 +- share/html/Helpers/Autocomplete/Tickets | 2 +- share/html/Helpers/Autocomplete/Users | 2 +- share/html/Helpers/Autocomplete/autohandler | 2 +- share/html/Helpers/TicketHistory | 2 +- share/html/Helpers/Toggle/ShowRequestor | 2 +- share/html/Helpers/Toggle/TicketBookmark | 2 +- share/html/Helpers/UserInfo | 2 +- share/html/Helpers/autohandler | 2 +- share/html/Install/Basics.html | 2 +- share/html/Install/DatabaseDetails.html | 14 +- share/html/Install/DatabaseType.html | 2 +- share/html/Install/Elements/Errors | 2 +- share/html/Install/Elements/Wrapper | 2 +- share/html/Install/Finish.html | 2 +- share/html/Install/Global.html | 2 +- share/html/Install/Initialize.html | 3 +- share/html/Install/Sendmail.html | 2 +- share/html/Install/autohandler | 2 +- share/html/Install/index.html | 2 +- share/html/NoAuth/Helpers/CustomLogo/dhandler | 2 +- share/html/NoAuth/Login.html | 2 +- share/html/NoAuth/Logout.html | 2 +- share/html/NoAuth/RichText/autohandler | 2 +- share/html/NoAuth/css/aileron/AfterMenus | 2 +- share/html/NoAuth/css/aileron/InHeader | 2 +- share/html/NoAuth/css/autohandler | 2 +- share/html/NoAuth/css/ballard/InHeader | 4 +- share/html/NoAuth/css/dhandler | 2 +- share/html/NoAuth/css/rudder/AfterMenus | 2 +- share/html/NoAuth/css/rudder/InHeader | 2 +- share/html/NoAuth/css/web2/AfterMenus | 2 +- share/html/NoAuth/css/web2/InHeader | 2 +- share/html/NoAuth/iCal/dhandler | 2 +- share/html/NoAuth/js/autohandler | 2 +- share/html/NoAuth/js/dhandler | 2 +- share/html/NoAuth/rss/dhandler | 2 +- share/html/Prefs/DashboardsInMenu.html | 2 +- share/html/Prefs/MyRT.html | 5 +- share/html/Prefs/Other.html | 2 +- share/html/Prefs/Quicksearch.html | 2 +- share/html/Prefs/Search.html | 2 +- share/html/Prefs/SearchOptions.html | 2 +- share/html/REST/1.0/Forms/attachment/default | 2 +- share/html/REST/1.0/Forms/group/customfields | 2 +- share/html/REST/1.0/Forms/group/default | 51 +- share/html/REST/1.0/Forms/group/ns | 2 +- share/html/REST/1.0/Forms/queue/customfields | 2 +- share/html/REST/1.0/Forms/queue/default | 11 +- share/html/REST/1.0/Forms/queue/ns | 2 +- .../REST/1.0/Forms/queue/ticketcustomfields | 2 +- share/html/REST/1.0/Forms/ticket/attachments | 2 +- share/html/REST/1.0/Forms/ticket/comment | 3 +- share/html/REST/1.0/Forms/ticket/default | 3 +- share/html/REST/1.0/Forms/ticket/history | 2 +- share/html/REST/1.0/Forms/ticket/links | 2 +- share/html/REST/1.0/Forms/ticket/merge | 2 +- share/html/REST/1.0/Forms/ticket/take | 2 +- share/html/REST/1.0/Forms/transaction/default | 2 +- share/html/REST/1.0/Forms/user/default | 51 +- share/html/REST/1.0/Forms/user/ns | 2 +- share/html/REST/1.0/NoAuth/mail-gateway | 2 +- share/html/REST/1.0/autohandler | 2 +- share/html/REST/1.0/dhandler | 2 +- share/html/REST/1.0/logout | 2 +- share/html/REST/1.0/search/dhandler | 247 +- share/html/REST/1.0/ticket/comment | 3 +- share/html/REST/1.0/ticket/link | 2 +- share/html/REST/1.0/ticket/merge | 2 +- share/html/Search/Article.html | 2 +- share/html/Search/Build.html | 4 +- share/html/Search/Bulk.html | 2 +- share/html/Search/Chart | 2 +- share/html/Search/Chart.html | 10 +- share/html/Search/Edit.html | 2 +- share/html/Search/Elements/Article | 2 +- share/html/Search/Elements/BuildFormatString | 39 +- share/html/Search/Elements/Chart | 2 +- share/html/Search/Elements/ChartTable | 2 +- share/html/Search/Elements/ConditionRow | 2 +- share/html/Search/Elements/DisplayOptions | 2 +- share/html/Search/Elements/EditFormat | 6 +- share/html/Search/Elements/EditQuery | 2 +- share/html/Search/Elements/EditSearches | 2 +- share/html/Search/Elements/EditSort | 4 +- share/html/Search/Elements/Graph | 2 +- share/html/Search/Elements/NewListActions | 2 +- share/html/Search/Elements/PickBasics | 3 +- share/html/Search/Elements/PickCFs | 2 +- share/html/Search/Elements/PickCriteria | 2 +- share/html/Search/Elements/PickObjectCFs | 2 +- share/html/Search/Elements/PickTicketCFs | 2 +- share/html/Search/Elements/ResultsRSSView | 2 +- share/html/Search/Elements/SearchPrivacy | 2 +- share/html/Search/Elements/SearchesForObject | 2 +- share/html/Search/Elements/SelectAndOr | 2 +- .../html/Search/Elements/SelectChartFunction | 2 +- share/html/Search/Elements/SelectChartType | 2 +- share/html/Search/Elements/SelectGroup | 2 +- share/html/Search/Elements/SelectGroupBy | 2 +- share/html/Search/Elements/SelectLinks | 2 +- share/html/Search/Elements/SelectPersonType | 2 +- share/html/Search/Elements/SelectSearchObject | 2 +- .../Search/Elements/SelectSearchesForObjects | 2 +- share/html/Search/Results.html | 6 +- share/html/Search/Results.rdf | 2 +- share/html/Search/Results.tsv | 2 +- share/html/Search/Simple.html | 2 +- share/html/Search/index.html | 2 +- share/html/SelfService/Article/Display.html | 2 +- share/html/SelfService/Article/Search.html | 2 +- share/html/SelfService/Article/autohandler | 2 +- share/html/SelfService/Attachment/dhandler | 2 +- share/html/SelfService/Closed.html | 2 +- share/html/SelfService/Create.html | 2 +- .../html/SelfService/CreateTicketInQueue.html | 2 +- share/html/SelfService/Display.html | 12 +- share/html/SelfService/Elements/GotoTicket | 2 +- share/html/SelfService/Elements/Header | 2 +- share/html/SelfService/Elements/MyRequests | 2 +- share/html/SelfService/Elements/SearchArticle | 2 +- .../Helpers/Autocomplete/CustomFieldValues | 2 +- .../SelfService/Helpers/Autocomplete/Users | 2 +- share/html/SelfService/Prefs.html | 2 +- share/html/SelfService/Update.html | 2 +- share/html/SelfService/index.html | 2 +- .../Ticket/Attachment/WithHeaders/dhandler | 2 +- share/html/Ticket/Attachment/dhandler | 2 +- share/html/Ticket/Create.html | 12 +- share/html/Ticket/Crypt.html | 2 +- share/html/Ticket/Display.html | 4 +- share/html/Ticket/Elements/AddAttachments | 2 +- share/html/Ticket/Elements/AddWatchers | 2 +- share/html/Ticket/Elements/Bookmark | 2 +- share/html/Ticket/Elements/ClickToShowHistory | 2 +- share/html/Ticket/Elements/DelayShowHistory | 2 +- share/html/Ticket/Elements/EditBasics | 5 +- share/html/Ticket/Elements/EditCustomFields | 2 +- share/html/Ticket/Elements/EditDates | 2 +- share/html/Ticket/Elements/EditMerge | 2 +- share/html/Ticket/Elements/EditPeople | 2 +- .../Elements/EditTransactionCustomFields | 4 +- share/html/Ticket/Elements/EditWatchers | 2 +- .../html/Ticket/Elements/LoadTextAttachments | 2 +- share/html/Ticket/Elements/PreviewScrips | 4 +- share/html/Ticket/Elements/Reminders | 2 +- share/html/Ticket/Elements/SelectStatus | 2 +- share/html/Ticket/Elements/ShowAttachments | 2 +- share/html/Ticket/Elements/ShowBasics | 2 +- share/html/Ticket/Elements/ShowCustomFields | 2 +- share/html/Ticket/Elements/ShowDates | 2 +- .../html/Ticket/Elements/ShowDependencyStatus | 2 +- share/html/Ticket/Elements/ShowGroupMembers | 2 +- share/html/Ticket/Elements/ShowPeople | 2 +- share/html/Ticket/Elements/ShowPriority | 2 +- share/html/Ticket/Elements/ShowQueue | 2 +- share/html/Ticket/Elements/ShowRequestor | 2 +- .../Ticket/Elements/ShowRequestorExtraInfo | 2 +- .../html/Ticket/Elements/ShowRequestorTickets | 2 +- .../Elements/ShowRequestorTicketsActive | 2 +- .../Ticket/Elements/ShowRequestorTicketsAll | 2 +- .../Elements/ShowRequestorTicketsInactive | 2 +- .../Ticket/Elements/ShowSimplifiedRecipients | 2 +- share/html/Ticket/Elements/ShowSummary | 6 +- share/html/Ticket/Elements/ShowTime | 2 +- share/html/Ticket/Elements/ShowUpdateStatus | 8 +- share/html/Ticket/Elements/UpdateCc | 2 +- share/html/Ticket/Forward.html | 2 +- .../Graphs/Elements/EditGraphProperties | 2 +- share/html/Ticket/Graphs/Elements/ShowGraph | 2 +- share/html/Ticket/Graphs/Elements/ShowLegends | 2 +- share/html/Ticket/Graphs/dhandler | 2 +- share/html/Ticket/Graphs/index.html | 2 +- share/html/Ticket/History.html | 2 +- share/html/Ticket/Modify.html | 6 +- share/html/Ticket/ModifyAll.html | 4 +- share/html/Ticket/ModifyDates.html | 3 +- share/html/Ticket/ModifyLinks.html | 5 +- share/html/Ticket/ModifyPeople.html | 4 +- share/html/Ticket/Reminders.html | 2 +- share/html/Ticket/ShowEmailRecord.html | 38 +- share/html/Ticket/Update.html | 11 +- share/html/Ticket/autohandler | 2 +- share/html/Tools/MyDay.html | 2 +- share/html/Tools/MyReminders.html | 2 +- share/html/Tools/index.html | 2 +- .../html/User/Elements/Portlets/ActiveTickets | 2 +- .../html/User/Elements/Portlets/CreateTicket | 2 +- share/html/User/Elements/Portlets/ExtraInfo | 2 +- .../User/Elements/Portlets/InactiveTickets | 2 +- share/html/User/Elements/TicketList | 16 +- share/html/User/Elements/UserInfo | 2 +- share/html/User/History.html | 2 +- share/html/User/Prefs.html | 25 +- share/html/User/Search.html | 2 +- share/html/User/Summary.html | 2 +- share/html/Widgets/BulkEdit | 2 +- share/html/Widgets/BulkProcess | 2 +- share/html/Widgets/ComboBox | 2 +- share/html/Widgets/FinalizeWidgetArguments | 2 +- share/html/Widgets/Form/Boolean | 2 +- share/html/Widgets/Form/Integer | 2 +- share/html/Widgets/Form/Select | 2 +- share/html/Widgets/Form/String | 2 +- share/html/Widgets/SavedSearch | 2 +- share/html/Widgets/SelectionBox | 2 +- share/html/Widgets/TitleBox | 2 +- share/html/Widgets/TitleBoxEnd | 2 +- share/html/Widgets/TitleBoxStart | 2 +- share/html/autohandler | 2 +- share/html/dhandler | 2 +- share/html/index.html | 2 +- share/html/l | 2 +- share/html/l_unsafe | 2 +- share/html/m/_elements/footer | 4 +- share/html/m/_elements/full_site_link | 2 +- share/html/m/_elements/header | 2 +- share/html/m/_elements/login | 2 +- share/html/m/_elements/menu | 2 +- share/html/m/_elements/ticket_list | 2 +- share/html/m/_elements/ticket_menu | 2 +- share/html/m/_elements/wrapper | 2 +- share/html/m/dhandler | 2 +- share/html/m/index.html | 2 +- share/html/m/logout | 2 +- share/html/m/ticket/autohandler | 2 +- share/html/m/ticket/create | 2 +- share/html/m/ticket/history | 2 +- share/html/m/ticket/reply | 2 +- share/html/m/ticket/select_create_queue | 2 +- share/html/m/ticket/show | 2 +- share/html/m/tickets/search | 2 +- share/po/ar.po | 687 +- share/po/bg.po | 1345 +- share/po/ca.po | 677 +- share/po/cs.po | 1303 +- share/po/da.po | 3621 ++---- share/po/de.po | 3422 ++--- share/po/el.po | 3029 ++--- share/po/en.po | 8 +- share/po/en_GB.po | 2899 +++-- share/po/es.po | 4021 ++---- share/po/et.po | 2115 ++-- share/po/eu.po | 10029 +++++++++++++++ share/po/fi.po | 2983 +---- share/po/fr.po | 2235 +--- share/po/hr.po | 3341 ++--- share/po/hu.po | 1517 +-- share/po/id.po | 1745 +-- share/po/is.po | 1231 +- share/po/it.po | 3199 +---- share/po/ja.po | 1537 +-- share/po/lt.po | 2182 +--- share/po/lv.po | 1371 +- share/po/mk.po | 685 +- share/po/nb.po | 3853 ++---- share/po/nl.po | 2897 +---- share/po/nn.po | 1418 +-- share/po/oc.po | 675 +- share/po/pl.po | 3447 ++--- share/po/pt.po | 2669 ++-- share/po/pt_BR.po | 3904 ++---- share/po/pt_PT.po | 1533 +-- share/po/rt.pot | 679 +- share/po/ru.po | 2076 +--- share/po/sk.po | 639 +- share/po/sl.po | 1365 +- share/po/sr.po | 10373 ++++++++++++++++ share/po/sv.po | 2545 ++-- share/po/tr.po | 1599 +-- share/po/zh_CN.po | 4839 +------ share/po/zh_TW.po | 4853 +------- share/static/css/aileron/msie6.css | 23 + share/static/css/aileron/ticket-lists.css | 2 + share/static/css/ballard/msie6.css | 9 + share/static/css/ballard/nav.css | 1 - share/static/css/ballard/ticket-lists.css | 3 +- share/static/css/base/history-folding.css | 21 + share/static/css/base/misc.css | 12 + share/static/css/base/msie6.css | 19 + share/static/css/rudder/misc.css | 4 + share/static/css/web2/msie6.css | 5 + share/static/css/web2/ticket-lists.css | 3 +- share/static/js/cascaded.js | 47 +- share/static/js/event-registration.js | 6 +- share/static/js/forms.js | 2 +- share/static/js/history-folding.js | 2 +- share/static/js/late.js | 5 +- share/static/js/util.js | 29 +- 897 files changed, 45774 insertions(+), 63814 deletions(-) create mode 100644 docs/automating_rt.pod create mode 100644 etc/upgrade/4.0.18/content create mode 100644 etc/upgrade/4.0.19/content create mode 100644 etc/upgrade/4.0.19/schema.mysql create mode 100644 etc/upgrade/4.2.1/content create mode 100644 etc/upgrade/4.2.2/content create mode 100644 etc/upgrade/4.2.2/schema.mysql create mode 100644 lib/RT/DependencyWalker/FindDependencies.pm mode change 100644 => 100755 local/bin/rt-count create mode 100755 sbin/rt-importer create mode 100755 sbin/rt-serializer create mode 100644 share/po/eu.po create mode 100644 share/po/sr.po create mode 100644 share/static/css/base/msie6.css diff --git a/bin/rt b/bin/rt index d5a1161..d342b64 100755 --- a/bin/rt +++ b/bin/rt @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -329,32 +329,53 @@ sub list { $data{orderby} =~ s/^\+?(.*)/-$1/; } - if (!defined $q) { - $q = $config{query}; + $type ||= "ticket"; + + if (!defined $q ) { + if ( $type eq 'ticket' ) { + $q = $config{query}; + } + else { + $q = ''; + } } - - $q =~ s/^#//; # get rid of leading hash - if ($q =~ /^\d+$/) { - # only digits, must be an id, formulate a correct query - $q = "id=$q" if $q =~ /^\d+$/; - } else { - # a string only, take it as an owner or requestor (quoting done later) - $q = "(Owner=$q or Requestor like $q) and $config{query}" - if $q =~ /^[\w\-]+$/; - # always add a query for a specific queue or (comma separated) queues - $queue =~ s/,/ or Queue=/g if $queue; - $q .= " and (Queue=$queue)" if $queue and $q and $q !~ /Queue\s*=/i - and $q !~ /id\s*=/i; + + if ( $type ne 'ticket' ) { + $rawprint = 1; } - # correctly quote strings in a query - $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g; - $type ||= "ticket"; - unless ($type && defined $q) { + unless (defined $q) { my $item = $type ? "query string" : "object type"; whine "No $item specified."; $bad = 1; } + + $q =~ s/^#//; # get rid of leading hash + if ( $type eq 'ticket' ) { + if ( $q =~ /^\d+$/ ) { + + # only digits, must be an id, formulate a correct query + $q = "id=$q" if $q =~ /^\d+$/; + } + else { + + # a string only, take it as an owner or requestor (quoting done later) + $q = "(Owner=$q or Requestor like $q) and $config{query}" + if $q =~ /^[\w\-]+$/; + + # always add a query for a specific queue or (comma separated) queues + $queue =~ s/,/ or Queue=/g if $queue; + $q .= " and (Queue=$queue)" + if $queue + and $q + and $q !~ /Queue\s*=/i + and $q !~ /id\s*=/i; + } + + # correctly quote strings in a query + $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g; + } + #return help("list", $type) if $bad; return suggest_help("list", $type, $bad) if $bad; @@ -2198,13 +2219,14 @@ Text: Displays a list of objects matching the specified conditions. ("ls", "list", and "search" are synonyms.) - Conditions are expressed in the SQL-like syntax used internally by - RT. (For more information, see "rt help query".) The query string - must be supplied as one argument. + The query string must be supplied as one argument. + + if on tickets, query is in the SQL-like syntax used internally by + RT. (For more information, see "rt help query".), otherwise, query + is plain string with format "FIELD OP VALUE", e.g. "Name = General". - (Right now, the server doesn't support listing anything but tickets. - Other types will be supported in future; this client will be able to - take advantage of that support without any changes.) + if query string is absent, we limit to privileged ones on users and + user defined ones on groups automatically. Options: @@ -2235,6 +2257,9 @@ Text: rt ls -t ticket "Subject like '[PATCH]%'" rt ls -q systems rt ls -f owner,subject + rt ls -t queue 'Name = General' + rt ls -t user 'EmailAddress like foo@bar.com' + rt ls -t group 'Name like foo' -- diff --git a/bin/rt-crontool b/bin/rt-crontool index c8e0798..1c081e7 100755 --- a/bin/rt-crontool +++ b/bin/rt-crontool @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/bin/rt-mailgate b/bin/rt-mailgate index deccd70..4e5cc34 100755 --- a/bin/rt-mailgate +++ b/bin/rt-mailgate @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/docs/README b/docs/README index ec7fdcc..4bc7114 100644 --- a/docs/README +++ b/docs/README @@ -288,7 +288,7 @@ fix them. To report a bug, send email to . # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/docs/UPGRADING-3.8 b/docs/UPGRADING-3.8 index cfe01df..ba71777 100644 --- a/docs/UPGRADING-3.8 +++ b/docs/UPGRADING-3.8 @@ -168,11 +168,7 @@ Change this line to read: been assigned an ID of { $Ticket->SubjectTag }." If you were previously using RT::Extension::BrandedQueues, you MUST uninstall -it before upgrading. In addition, you must run the -'etc/upgrade/3.8-branded-queues-extension' perl script. This will -convert the extension's configuration into the new format. Finally, in -templates where you were using the Tag method ($Ticket->QueueObj->Tag), -you will need to replace it with $Ticket->SubjectTag +it before upgrading. RT::Action::LinearEscalate extension has been integrated into core, so you MUST uninstall it before upgrading. diff --git a/docs/UPGRADING-4.2 b/docs/UPGRADING-4.2 index 0e458fa..dd21c25 100644 --- a/docs/UPGRADING-4.2 +++ b/docs/UPGRADING-4.2 @@ -300,6 +300,14 @@ on C enabling these in F implicitly will need to pass C<--enable-gpg> to C, or alter their C to enable the functionality explicitly. +=item * + +In TicketSQL, "Starts = '1970-01-01'" will no longer find tickets with +no Starts date set. Instead, use "Starts IS NULL". As a direct +consequence, "Starts < 'today'" will no longer also find tickets with no +Starts date; use "Starts < 'today' OR Starts IS NULL" to have the +equivalent results in RT 4.2. + =back =cut diff --git a/docs/automating_rt.pod b/docs/automating_rt.pod new file mode 100644 index 0000000..5636d41 --- /dev/null +++ b/docs/automating_rt.pod @@ -0,0 +1,234 @@ +=head1 Automating Tasks in RT + +As RT tickets are created, worked on, and resolved, there are sometimes +updates or notifications that have defined rules and could be automatic. +These might include increasing ticket priority over time so tickets don't +get lost, resolving old tickets that haven't had any activity for a period of +time, or sending email notifications based on some ticket criteria like +being 3 days old and still having a status of new. + +The tool for automating RT tasks is L. It's designed to be +run from the cron scheduler and accepts a set of parameters that define +what RT objects it should operate on and what it should do. The sections +below describe some common L tasks as examples of the +different ways you can automate tasks. + +All of the options for L are documented with the tool itself: + + $ perldoc bin/rt-crontool + +and on the Best Practical web site. + +=head2 Running C + +As you'll see in the examples below, this tool gives full access to RT. +To manage the scope of changes that could be performed by the tool, we +recommended creating a dedicated unix user with limited privileges for +this purpose. Then create a user in RT with just enough access to +perform the changes you need to automate, and set the "Unix login" field +of the RT user to the username of the unix user you created. See the +L documentation for more information. + +=head2 Testing Tips + +When setting up a new automated crontool job, keep in mind that you might be +modifying a large number of tickets, especially the first time you run it. +Changes to tickets can trigger scrips just like the same change made via +the user interface. For example, changing the status to resolved will trigger +the 'On Resolve' scrips, which often means sending email. Depending on the +modification, you could end up sending a lot of email or triggering other +actions. + +You can test your TicketSQL search queries in the RT web interface +(using the Advanced tab of ticket search), and use bulk update if you +want to prepare things for your new automated job. You can also disable +scrips which you wish to avoid, or turn off outgoing mail with the +L option. This can be useful if you want to +clean up older tickets without sending notifications to requestors for +tickets that were resolved years ago. + +To help with debugging, the C<--verbose> option will give you more output. +The C<--log> option accepts all of the valid log levels for RT and allows +you to change the logging level just for the automated job. While testing, +it's often convenient to set: + + --log debug + +to see what's happening. + +=head1 A Simple Search + +Starting with a simple example, this command performs a search and +displays output, but doesn't do anything to the returned tickets. +This can be useful for safely testing search criteria. + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "Owner = 'root'" \ + --action RT::Action \ + --verbose \ + --log debug + +The C<--search> argument sets the search module RT should use, in this +case L which processes TicketSQL. The second +argument, C<--search-arg>, is the search query to use. These are +the same queries you create in the RT search interface, so can use +the RT web UI to refine your queries before setting up your job. + +The C<--action> argument is set to L which is the base class +for RT actions. Since this class doesn't perform any action itself, this +command will just output the results of the TicketSQL search. + +=head1 Auto-resolve Aged Tickets + +You can auto-set status based on any criteria you can define in +a TicketSQL statement. For example, this command will resolve all +active tickets that haven't been acted on in a month or more: + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "(Status != 'resolved' AND Status != 'rejected') \ + AND LastUpdated <= '1 month ago'" \ + --action RT::Action::SetStatus \ + --action-arg resolved + +The search is similar to the previous example with a slightly more +complicated search argument. Note that since LastUpdated is treated as +a timestamp (which increases over time) C +means "the timestamp when it was updated is before the timestamp one +month ago" and not "updated less than a month ago." + +The C<--action> in this case uses the L module +with an C<--action-arg> of C. For each of the tickets +returned from the search query, the status is set to resolved. When +setting up automated tasks, you can use actions provided as part of RT, +actions available from extensions, or actions you create yourself. + +As noted previously, the normal RT rules apply when running actions +with L, so for this example applicable 'On Resolve' +scrips will run. If a ticket has unresolved dependencies, it will +log an error since tickets can't be resolved until dependencies are +resolved. Also, the status argument must be valid for the lifecycle of +the selected tickets, and the transition must be allowed. + +=head1 Commenting and Corresponding on a Ticket + +The following command records a comment on all tickets returned from the +query -- in this case, tickets that are new and unowned after 3 days. + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "Owner = 'Nobody' AND Status = 'new' \ + AND Created < '3 days ago'" \ + --action RT::Action::RecordComment \ + --template 'Unowned tickets' + +The L action does just that, it records a +comment just like replying to a comment email or commenting in the +RT UI. It uses the global RT template defined by C<--template>, so you +could put whatever you like in that template. For example: + + Subject: {$Ticket->id} new and unowned + RT-Send-Cc: support-backup@example.com + + Ticket {$Ticket->id} is still new and unowned after 3 days! + +You can set up a similar command to send a reply rather than a comment +using the L module. + +=head1 Sending Notifications + +While the example above sends notifications as a side-effect of recording +a comment, you can also send notifications directly. + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "(Status != 'resolved' AND Status != 'rejected') \ + AND Queue = 'Project Work'" \ + --condition RT::Condition::Overdue \ + --action RT::Action::NotifyGroup \ + --action-arg 'project-manager@example.com' \ + --template 'Overdue task' + +This example shows the C<--condition> argument and the +L module, which returns true if the current +time (the time the cron job is running) is past the Due date on the +ticket. Like the C<--action> argument, you can use conditions +provided with RT, added from extensions, or conditions you have +created. + +L, despite the "Group" in the name, can accept a +bare email address or list of addresses as the action argument and it will +send mail to them. A combination of email addresses and group names separated +by commas also works. RT usernames are valid unless they conflict with group +names. + +The action sends email, but unlike comment and correspond above, it +doesn't record a transaction in the ticket history. + +=head1 Escalating Priority + +RT has a built-in ticket priority system with priority values from +0 to 99. Depending on how you configure your queues, you can set 1 as the +top priority with lower numbers meaning more important, or 99 can be the +top priority with higher numbers meaning more important. You can set this +in your queue configuration at Tools -> Configuration -> Queues. On the queue +configuration page, set "Priority starts at" and "Over time, priority moves +toward". + +Whichever scheme you choose, RT's L can +escalate the priority over time so tickets that are closer to their due +date and are still not resolved have priority escalated automatically. + +This command escalates tickets in a designated queue: + + bin/rt-crontool --search RT::Search::ActiveTicketsInQueue \ + --search-arg "General" \ + --action RT::Action::EscalatePriority + +The C<--search-arg> is the name of the queue in which to escalate tickets. +As shown in previous examples, you can also set your criteria using a +TicketSQL query as well: + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "(Status='new' OR Status='open') AND Due > 'Jan 1, 1970'" \ + --action RT::Action::EscalatePriority + +This example will find new and open tickets in all queues, but will skip tickets +with no explicit due dates set. Maybe you only want to bump the priority on tasks +that have to be done by a certain date. + +L is an alternative escalation module that +handles the "Due date not set" condition for you. It also offers some +configuration options to control whether a transaction is recorded on the +ticket and whether LastUpdated is modified. + +=head1 Transactions + +Many actions and conditions are also used in RT in scrips and may require +a transaction in addition to a ticket. For such cases, L +provides a C<--transaction> argument to designate a transaction. Valid +values are C, C, and C and these are relative to the +current ticket being processed. C and C are the first and +last transaction on the ticket. Be careful with the C option since +it will run the action on all transactions for the ticket. + +Since actions and conditions can be used in different contexts, you +may need to provide a transaction object even if it doesn't seem +necessary for your automated job. If you're seeing errors about +a missing transaction, setting C<--transaction> to C or +C is usually safe and will resolve the error. + +You can also target specific transaction types with C<--transation-type>. +This argument accepts one or more transaction types as a comma-separated +list. + +Using these options together, you can set up a command that sets the +appropriate transaction object for your conditions and actions. For +example, if you had an action you wanted to perform based on the content +of the last reply on stalled tickets, you could do something like: + + bin/rt-crontool --search RT::Search::FromSQL \ + --search-arg "Status = 'stalled' AND Queue = 'General'" \ + --action RT::Action::CheckLastCorrespond \ + --transaction last \ + --transaction-type Correspond + + +=cut diff --git a/docs/customizing/lifecycles.pod b/docs/customizing/lifecycles.pod index 9a6f38b..29ab96b 100644 --- a/docs/customizing/lifecycles.pod +++ b/docs/customizing/lifecycles.pod @@ -305,8 +305,10 @@ mapping, defining the most sensible mapping you can. If you don't provide a mapping, users will see an error when they try to move a ticket between queues with different lifecycles but no mapping. - Set( %Lifecycles, orders => { - # ..., + Set( %Lifecycles, + orders => { + # ... + }, __maps__ => { 'default -> orders' => { 'new' => 'pending', @@ -340,7 +342,7 @@ to experiment. # All the appropriate order statuses initial => [ 'pending' ], active => [ 'processing', 'delivery' ], - inactive => [ 'delivered', 'returned', 'declined' ], + inactive => [ 'delivered', 'returned', 'declined', 'deleted' ], # Default order statuses for certain actions defaults => { @@ -376,10 +378,6 @@ to experiment. label => 'Open For Processing', update => 'Comment', }, - 'pending -> delivered' => { - label => 'Mark as being delivered', - update => 'Comment', - }, 'pending -> declined' => { label => 'Decline', update => 'Respond', diff --git a/etc/RT_Config.pm b/etc/RT_Config.pm index 26ca3e9..c7c3762 100644 --- a/etc/RT_Config.pm +++ b/etc/RT_Config.pm @@ -370,11 +370,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 +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> @@ -972,6 +975,8 @@ Set(@CSSFiles, qw//); 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 @@ -1297,7 +1302,7 @@ Set ($DefaultSearchResultFormat, qq{ Owner, Priority, '__NEWLINE__', - '', + '__NBSP__', '__Requestors__', '__CreatedRelative__', '__ToldRelative__', @@ -2467,7 +2472,7 @@ Set(%GnuPGOptions, # 'auto-key-locate' => 'keyserver', # enables the automatic retrieving of keys when verifying signatures -# 'auto-key-retrieve' => undef, +# 'keyserver-options' => 'auto-key-retrieve', ); =back diff --git a/etc/acl.mysql b/etc/acl.mysql index 1688237..7e56e97 100644 --- a/etc/acl.mysql +++ b/etc/acl.mysql @@ -5,14 +5,13 @@ 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; return ( "GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE diff --git a/etc/initialdata b/etc/initialdata index 2a4a6e9..3de65f4 100644 --- a/etc/initialdata +++ b/etc/initialdata @@ -841,7 +841,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') } Name => 'HomepageSettings', Description => 'HomepageSettings', Content => { - 'body' => # loc + 'body' => # loc_left_pair [ { type => 'system', @@ -860,7 +860,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') } name => 'QuickCreate' # loc }, ], - 'sidebar' => # loc + 'sidebar' => # loc_left_pair [ { type => 'component', diff --git a/etc/schema.mysql b/etc/schema.mysql index 3669fb3..610a79c 100644 --- a/etc/schema.mysql +++ b/etc/schema.mysql @@ -22,9 +22,9 @@ CREATE TABLE Queues ( id INTEGER NOT NULL AUTO_INCREMENT, Name varchar(200) NOT NULL , Description varchar(255) NULL , - CorrespondAddress varchar(120) CHARACTER SET ascii NULL, - CommentAddress varchar(120) CHARACTER SET ascii NULL, - Lifecycle varchar(32) CHARACTER SET ascii NULL, + CorrespondAddress varchar(120) NULL, + CommentAddress varchar(120) NULL, + Lifecycle varchar(32) NULL, SubjectTag varchar(120) NULL, InitialPriority integer NOT NULL DEFAULT 0 , FinalPriority integer NOT NULL DEFAULT 0 , diff --git a/etc/upgrade/3.7.19/content b/etc/upgrade/3.7.19/content index a694562..34af550 100644 --- a/etc/upgrade/3.7.19/content +++ b/etc/upgrade/3.7.19/content @@ -26,9 +26,20 @@ our @Final = ( sub gen_scrip_description { my $scrip = shift; - my $condition = $scrip->ConditionObj->Name + + my $condition; + eval{ + $condition = $scrip->ConditionObj->Name || $scrip->ConditionObj->Description || ('On Condition #'. $scrip->Condition); + }; + + if ($@){ + print STDERR $@; + print STDERR "Reference to missing scrip condition found. If you have ScripCondition = 0 in the Scrips table, update with a real condition number.\n"; + $condition = 'On undefined Condition # 0'; + } + my $action = $scrip->ActionObj->Name || $scrip->ActionObj->Description || ('Run Action #'. $scrip->Action); diff --git a/etc/upgrade/3.8-ical-extension b/etc/upgrade/3.8-ical-extension index 3b81231..7b160d7 100644 --- a/etc/upgrade/3.8-ical-extension +++ b/etc/upgrade/3.8-ical-extension @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/4.0.18/content b/etc/upgrade/4.0.18/content new file mode 100644 index 0000000..64eea9a --- /dev/null +++ b/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/etc/upgrade/4.0.19/content b/etc/upgrade/4.0.19/content new file mode 100644 index 0000000..31e4d9f --- /dev/null +++ b/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/etc/upgrade/4.0.19/schema.mysql b/etc/upgrade/4.0.19/schema.mysql new file mode 100644 index 0000000..de28cc9 --- /dev/null +++ b/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/etc/upgrade/4.1.1/schema.Oracle b/etc/upgrade/4.1.1/schema.Oracle index 180cf0c..4590585 100644 --- a/etc/upgrade/4.1.1/schema.Oracle +++ b/etc/upgrade/4.1.1/schema.Oracle @@ -11,7 +11,7 @@ CREATE TABLE ObjectScrips ( LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, LastUpdated DATE ); -ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0; +ALTER TABLE Scrips ADD Disabled NUMBER(11,0) DEFAULT 0 NOT NULL; INSERT INTO ObjectScrips( id, Scrip, Stage, ObjectId, diff --git a/etc/upgrade/4.1.13/backcompat b/etc/upgrade/4.1.13/backcompat index b4e69a3..0dc53d2 100644 --- a/etc/upgrade/4.1.13/backcompat +++ b/etc/upgrade/4.1.13/backcompat @@ -4,6 +4,9 @@ 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', diff --git a/etc/upgrade/4.1.22/schema.Oracle b/etc/upgrade/4.1.22/schema.Oracle index 6ce5646..273779b 100644 --- a/etc/upgrade/4.1.22/schema.Oracle +++ b/etc/upgrade/4.1.22/schema.Oracle @@ -1 +1 @@ -ALTER TABLE Users ADD COLUMN SMIMECertificate CLOB; +ALTER TABLE Users ADD SMIMECertificate CLOB; diff --git a/etc/upgrade/4.1.23/indexes b/etc/upgrade/4.1.23/indexes index d76264f..78db4ae 100644 --- a/etc/upgrade/4.1.23/indexes +++ b/etc/upgrade/4.1.23/indexes @@ -94,13 +94,11 @@ my $dedup = sub { ); foreach my $e (@list) { RT->Logger->debug("Checking index on ". $e->{'Column'} ." in ". $e->{'Table'} ); - my ($index) = $RT::Handle->IndexesThatBeginWith( + my (@indexes) = $RT::Handle->IndexesThatBeginWith( Table => $e->{'Table'}, Columns => [$e->{'Column'}] ); - $index = undef if $index && @{$index->{'Columns'}}>1; - if ( - $index && $index->{'Unique'} - && ($RT::Handle->CaseSensitive? $index->{'CaseInsensitive'}{ lc $e->{'Column'} } : 1 ) + @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; @@ -108,7 +106,7 @@ my $dedup = sub { $dedup->( $e->{'Table'}, $e->{'Column'} ); - if ( $index ) { + for my $index ( @indexes ) { my ($status, $msg) = $RT::Handle->DropIndex( Table => $e->{'Table'}, Name => $index->{'Name'}, ); @@ -162,7 +160,8 @@ foreach my $table ('Users', 'Tickets') { my ($status, $msg) = $RT::Handle->DropIndex( Table => $table, Name => $index->{'Name'}, ); - RT->Logger->info($msg); + my $method = $status ? 'debug' : 'warning'; + RT->Logger->$method($msg); } } diff --git a/etc/upgrade/4.1.5/content b/etc/upgrade/4.1.5/content index 0ed1dda..4cf1bdb 100644 --- a/etc/upgrade/4.1.5/content +++ b/etc/upgrade/4.1.5/content @@ -6,6 +6,7 @@ our @Initial = ( sub { require RT::Scrips; my $scrips = RT::Scrips->new( RT->SystemUser ); + $scrips->{'find_disabled_rows'} = 1; $scrips->UnLimit; while ( my $scrip = $scrips->Next ) { my $id = $scrip->Template; diff --git a/etc/upgrade/4.1.5/schema.Oracle b/etc/upgrade/4.1.5/schema.Oracle index b0b4d4c..648784d 100644 --- a/etc/upgrade/4.1.5/schema.Oracle +++ b/etc/upgrade/4.1.5/schema.Oracle @@ -1,5 +1,6 @@ # Template column ALTER TABLE Scrips RENAME COLUMN Template TO TemplateOld; -ALTER TABLE Scrips ADD COLUMN Template VARCHAR2(200) NOT NULL; -UPDATE TABLE Scrips SET Template = CAST(TemplateOld AS varchar2); -ALTER TABLE Scrips DROP COLUMN TemplateOld; \ No newline at end of file +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/etc/upgrade/4.2.1/content b/etc/upgrade/4.2.1/content new file mode 100644 index 0000000..64eea9a --- /dev/null +++ b/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/etc/upgrade/4.2.2/content b/etc/upgrade/4.2.2/content new file mode 100644 index 0000000..762289a --- /dev/null +++ b/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/etc/upgrade/4.2.2/schema.mysql b/etc/upgrade/4.2.2/schema.mysql new file mode 100644 index 0000000..de28cc9 --- /dev/null +++ b/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/etc/upgrade/generate-rtaddressregexp b/etc/upgrade/generate-rtaddressregexp index 1dcff87..44451d2 100644 --- a/etc/upgrade/generate-rtaddressregexp +++ b/etc/upgrade/generate-rtaddressregexp @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/sanity-check-stylesheets.pl b/etc/upgrade/sanity-check-stylesheets.pl index aa4faaf..2019f25 100644 --- a/etc/upgrade/sanity-check-stylesheets.pl +++ b/etc/upgrade/sanity-check-stylesheets.pl @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/shrink_cgm_table.pl b/etc/upgrade/shrink_cgm_table.pl index 9b453ba..7157b20 100644 --- a/etc/upgrade/shrink_cgm_table.pl +++ b/etc/upgrade/shrink_cgm_table.pl @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/shrink_transactions_table.pl b/etc/upgrade/shrink_transactions_table.pl index 601c297..3bc1b6d 100644 --- a/etc/upgrade/shrink_transactions_table.pl +++ b/etc/upgrade/shrink_transactions_table.pl @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/split-out-cf-categories b/etc/upgrade/split-out-cf-categories index c39d6d4..7dbee50 100644 --- a/etc/upgrade/split-out-cf-categories +++ b/etc/upgrade/split-out-cf-categories @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/switch-templates-to b/etc/upgrade/switch-templates-to index c6270c8..138138d 100644 --- a/etc/upgrade/switch-templates-to +++ b/etc/upgrade/switch-templates-to @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/time-worked-history.pl b/etc/upgrade/time-worked-history.pl index 8c8a696..67ee104 100644 --- a/etc/upgrade/time-worked-history.pl +++ b/etc/upgrade/time-worked-history.pl @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/etc/upgrade/upgrade-articles b/etc/upgrade/upgrade-articles index 2d338b0..f9938bb 100644 --- a/etc/upgrade/upgrade-articles +++ b/etc/upgrade/upgrade-articles @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -157,6 +157,7 @@ sub copy_tables { use RT::CustomFields; my $cfs = RT::CustomFields->new(RT->SystemUser); $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' ); + $cfs->{'find_disabled_rows'} = 1; while ( my $cf = $cfs->Next ) { my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' ); warn "Update Custom Field LookupType for CF.".$cf->Id." $msg"; @@ -167,6 +168,7 @@ sub copy_tables { use RT::ObjectCustomFieldValues; my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System); $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + $ocfvs->{'find_expired_rows'} = 1; while ( my $ocfv = $ocfvs->Next ) { my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' ); warn "Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId'); diff --git a/etc/upgrade/upgrade-mysql-schema.pl b/etc/upgrade/upgrade-mysql-schema.pl index 98eb7b4..8d6615d 100644 --- a/etc/upgrade/upgrade-mysql-schema.pl +++ b/etc/upgrade/upgrade-mysql-schema.pl @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -184,8 +184,8 @@ my %charset = ( Queues => { Name => 'utf8', Description => 'utf8', - CorrespondAddress => 'ascii', - CommentAddress => 'ascii', + CorrespondAddress => 'utf8', + CommentAddress => 'utf8', }, ScripActions => { Name => 'utf8', @@ -239,7 +239,7 @@ my %charset = ( Password => 'binary', Comments => 'utf8', Signature => 'utf8', - EmailAddress => 'ascii', + EmailAddress => 'utf8', FreeformContactInfo => 'utf8', Organization => 'utf8', RealName => 'utf8', diff --git a/etc/upgrade/vulnerable-passwords b/etc/upgrade/vulnerable-passwords index 6a904c8..1785fa9 100644 --- a/etc/upgrade/vulnerable-passwords +++ b/etc/upgrade/vulnerable-passwords @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT.pm b/lib/RT.pm index 92e15f3..17aaffb 100644 --- a/lib/RT.pm +++ b/lib/RT.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -181,6 +181,8 @@ up logging|/InitLogging>, and L. =cut sub Init { + shift if @_%2; # code is inconsistent about calling as method + my %args = (@_); CheckPerlRequirements(); @@ -189,7 +191,7 @@ sub Init { #Get a database connection ConnectToDatabase(); InitSystemObjects(); - InitClasses(); + InitClasses(%args); InitLogging(); InitPlugins(); _BuildTableAttributes(); diff --git a/lib/RT/ACE.pm b/lib/RT/ACE.pm index 01e1795..eb83ebe 100644 --- a/lib/RT/ACE.pm +++ b/lib/RT/ACE.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ACL.pm b/lib/RT/ACL.pm index 9995b80..cf38c1f 100644 --- a/lib/RT/ACL.pm +++ b/lib/RT/ACL.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action.pm b/lib/RT/Action.pm index d02159b..53e2ec4 100644 --- a/lib/RT/Action.pm +++ b/lib/RT/Action.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/AutoOpen.pm b/lib/RT/Action/AutoOpen.pm index 30a58a7..7e65fc1 100644 --- a/lib/RT/Action/AutoOpen.pm +++ b/lib/RT/Action/AutoOpen.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/AutoOpenInactive.pm b/lib/RT/Action/AutoOpenInactive.pm index 58c55cb..9c06fea 100644 --- a/lib/RT/Action/AutoOpenInactive.pm +++ b/lib/RT/Action/AutoOpenInactive.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/Autoreply.pm b/lib/RT/Action/Autoreply.pm index 7390b43..1df8fb4 100644 --- a/lib/RT/Action/Autoreply.pm +++ b/lib/RT/Action/Autoreply.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/CreateTickets.pm b/lib/RT/Action/CreateTickets.pm index 8817adb..a88a6ee 100644 --- a/lib/RT/Action/CreateTickets.pm +++ b/lib/RT/Action/CreateTickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/EscalatePriority.pm b/lib/RT/Action/EscalatePriority.pm index 6e8d880..046d6dd 100644 --- a/lib/RT/Action/EscalatePriority.pm +++ b/lib/RT/Action/EscalatePriority.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/ExtractSubjectTag.pm b/lib/RT/Action/ExtractSubjectTag.pm index 6a3898e..92a7214 100644 --- a/lib/RT/Action/ExtractSubjectTag.pm +++ b/lib/RT/Action/ExtractSubjectTag.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/LinearEscalate.pm b/lib/RT/Action/LinearEscalate.pm index d0529a4..e6260aa 100644 --- a/lib/RT/Action/LinearEscalate.pm +++ b/lib/RT/Action/LinearEscalate.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/Notify.pm b/lib/RT/Action/Notify.pm index 41a992b..d38fd26 100644 --- a/lib/RT/Action/Notify.pm +++ b/lib/RT/Action/Notify.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/NotifyAsComment.pm b/lib/RT/Action/NotifyAsComment.pm index 0016a36..a2c57db 100644 --- a/lib/RT/Action/NotifyAsComment.pm +++ b/lib/RT/Action/NotifyAsComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/NotifyGroup.pm b/lib/RT/Action/NotifyGroup.pm index 1dece60..789c182 100644 --- a/lib/RT/Action/NotifyGroup.pm +++ b/lib/RT/Action/NotifyGroup.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/NotifyGroupAsComment.pm b/lib/RT/Action/NotifyGroupAsComment.pm index 6218061..19d4e19 100644 --- a/lib/RT/Action/NotifyGroupAsComment.pm +++ b/lib/RT/Action/NotifyGroupAsComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/OpenOnStarted.pm b/lib/RT/Action/OpenOnStarted.pm index f7551c3..267f30a 100644 --- a/lib/RT/Action/OpenOnStarted.pm +++ b/lib/RT/Action/OpenOnStarted.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/RecordComment.pm b/lib/RT/Action/RecordComment.pm index 2092196..4cb372e 100644 --- a/lib/RT/Action/RecordComment.pm +++ b/lib/RT/Action/RecordComment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/RecordCorrespondence.pm b/lib/RT/Action/RecordCorrespondence.pm index 058a88b..1a1136b 100644 --- a/lib/RT/Action/RecordCorrespondence.pm +++ b/lib/RT/Action/RecordCorrespondence.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/SendEmail.pm b/lib/RT/Action/SendEmail.pm index 5f02e43..1266d21 100644 --- a/lib/RT/Action/SendEmail.pm +++ b/lib/RT/Action/SendEmail.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/SendForward.pm b/lib/RT/Action/SendForward.pm index f6570da..0a7949c 100644 --- a/lib/RT/Action/SendForward.pm +++ b/lib/RT/Action/SendForward.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/SetPriority.pm b/lib/RT/Action/SetPriority.pm index 2043532..7385c13 100644 --- a/lib/RT/Action/SetPriority.pm +++ b/lib/RT/Action/SetPriority.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/SetStatus.pm b/lib/RT/Action/SetStatus.pm index ba7652d..0847fa4 100644 --- a/lib/RT/Action/SetStatus.pm +++ b/lib/RT/Action/SetStatus.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Action/UserDefined.pm b/lib/RT/Action/UserDefined.pm index b259323..adc40e9 100644 --- a/lib/RT/Action/UserDefined.pm +++ b/lib/RT/Action/UserDefined.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval.pm b/lib/RT/Approval.pm index dc60222..34cf100 100644 --- a/lib/RT/Approval.pm +++ b/lib/RT/Approval.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval/Rule.pm b/lib/RT/Approval/Rule.pm index 6892f41..1b7b7ac 100644 --- a/lib/RT/Approval/Rule.pm +++ b/lib/RT/Approval/Rule.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval/Rule/Created.pm b/lib/RT/Approval/Rule/Created.pm index 8fcaeb2..91063d1 100644 --- a/lib/RT/Approval/Rule/Created.pm +++ b/lib/RT/Approval/Rule/Created.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval/Rule/NewPending.pm b/lib/RT/Approval/Rule/NewPending.pm index 2054c53..533944b 100644 --- a/lib/RT/Approval/Rule/NewPending.pm +++ b/lib/RT/Approval/Rule/NewPending.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval/Rule/Passed.pm b/lib/RT/Approval/Rule/Passed.pm index 45a64e3..eb53de4 100644 --- a/lib/RT/Approval/Rule/Passed.pm +++ b/lib/RT/Approval/Rule/Passed.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Approval/Rule/Rejected.pm b/lib/RT/Approval/Rule/Rejected.pm index 7e0c4a8..edbc6c2 100644 --- a/lib/RT/Approval/Rule/Rejected.pm +++ b/lib/RT/Approval/Rule/Rejected.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Article.pm b/lib/RT/Article.pm index 05f209d..0e440b0 100644 --- a/lib/RT/Article.pm +++ b/lib/RT/Article.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Articles.pm b/lib/RT/Articles.pm index 8521432..410578a 100644 --- a/lib/RT/Articles.pm +++ b/lib/RT/Articles.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Attachment.pm b/lib/RT/Attachment.pm index ee10301..800f4f5 100644 --- a/lib/RT/Attachment.pm +++ b/lib/RT/Attachment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Attachments.pm b/lib/RT/Attachments.pm index 60fda95..4e8b824 100644 --- a/lib/RT/Attachments.pm +++ b/lib/RT/Attachments.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Attribute.pm b/lib/RT/Attribute.pm index 39987ad..797e22e 100644 --- a/lib/RT/Attribute.pm +++ b/lib/RT/Attribute.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Attributes.pm b/lib/RT/Attributes.pm index 43748b3..b3da755 100644 --- a/lib/RT/Attributes.pm +++ b/lib/RT/Attributes.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Base.pm b/lib/RT/Base.pm index 403c318..f83ed8e 100644 --- a/lib/RT/Base.pm +++ b/lib/RT/Base.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CachedGroupMember.pm b/lib/RT/CachedGroupMember.pm index 04cdb22..17e4842 100644 --- a/lib/RT/CachedGroupMember.pm +++ b/lib/RT/CachedGroupMember.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CachedGroupMembers.pm b/lib/RT/CachedGroupMembers.pm index 072f489..d070d49 100644 --- a/lib/RT/CachedGroupMembers.pm +++ b/lib/RT/CachedGroupMembers.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Class.pm b/lib/RT/Class.pm index c0a5f43..01c0d79 100644 --- a/lib/RT/Class.pm +++ b/lib/RT/Class.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -84,19 +84,19 @@ sub Load { } } -__PACKAGE__->AddRight( Staff => SeeClass => 'See that this class exists'); # loc_pair -__PACKAGE__->AddRight( Staff => CreateArticle => 'Create articles in this class'); # loc_pair -__PACKAGE__->AddRight( General => ShowArticle => 'See articles in this class'); # loc_pair -__PACKAGE__->AddRight( Staff => ShowArticleHistory => 'See changes to articles in this class'); # loc_pair -__PACKAGE__->AddRight( General => SeeCustomField => 'View custom field values' ); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyArticle => 'Modify or delete articles in this class'); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyArticleTopics => 'Modify topics for articles in this class'); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Modify custom field values' ); # loc_pair -__PACKAGE__->AddRight( Admin => AdminClass => 'Modify metadata and custom fields for this class'); # loc_pair -__PACKAGE__->AddRight( Admin => AdminTopics => 'Modify topic hierarchy associated with this class'); # loc_pair -__PACKAGE__->AddRight( Admin => ShowACL => 'Display Access Control List'); # loc_pair -__PACKAGE__->AddRight( Admin => ModifyACL => 'Create, modify and delete Access Control List entries'); # loc_pair -__PACKAGE__->AddRight( Staff => DeleteArticle => 'Delete articles in this class'); # loc_pair +__PACKAGE__->AddRight( Staff => SeeClass => 'See that this class exists'); # loc +__PACKAGE__->AddRight( Staff => CreateArticle => 'Create articles in this class'); # loc +__PACKAGE__->AddRight( General => ShowArticle => 'See articles in this class'); # loc +__PACKAGE__->AddRight( Staff => ShowArticleHistory => 'See changes to articles in this class'); # loc +__PACKAGE__->AddRight( General => SeeCustomField => 'View custom field values' ); # loc +__PACKAGE__->AddRight( Staff => ModifyArticle => 'Modify or delete articles in this class'); # loc +__PACKAGE__->AddRight( Staff => ModifyArticleTopics => 'Modify topics for articles in this class'); # loc +__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Modify custom field values' ); # loc +__PACKAGE__->AddRight( Admin => AdminClass => 'Modify metadata and custom fields for this class'); # loc +__PACKAGE__->AddRight( Admin => AdminTopics => 'Modify topic hierarchy associated with this class'); # loc +__PACKAGE__->AddRight( Admin => ShowACL => 'Display Access Control List'); # loc +__PACKAGE__->AddRight( Admin => ModifyACL => 'Create, modify and delete Access Control List entries'); # loc +__PACKAGE__->AddRight( Staff => DeleteArticle => 'Delete articles in this class'); # loc # {{{ Create diff --git a/lib/RT/Classes.pm b/lib/RT/Classes.pm index 112ab98..fd3a3aa 100644 --- a/lib/RT/Classes.pm +++ b/lib/RT/Classes.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition.pm b/lib/RT/Condition.pm index ab70972..3bb6909 100644 --- a/lib/RT/Condition.pm +++ b/lib/RT/Condition.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/AnyTransaction.pm b/lib/RT/Condition/AnyTransaction.pm index 2c9129c..5d8b3bc 100644 --- a/lib/RT/Condition/AnyTransaction.pm +++ b/lib/RT/Condition/AnyTransaction.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/BeforeDue.pm b/lib/RT/Condition/BeforeDue.pm index 1e27865..7e5f1f7 100644 --- a/lib/RT/Condition/BeforeDue.pm +++ b/lib/RT/Condition/BeforeDue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/CloseTicket.pm b/lib/RT/Condition/CloseTicket.pm index bdeaf2d..2e027f4 100644 --- a/lib/RT/Condition/CloseTicket.pm +++ b/lib/RT/Condition/CloseTicket.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/Overdue.pm b/lib/RT/Condition/Overdue.pm index 8e12f23..bf044f8 100644 --- a/lib/RT/Condition/Overdue.pm +++ b/lib/RT/Condition/Overdue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/OwnerChange.pm b/lib/RT/Condition/OwnerChange.pm index 51f482e..15274e6 100644 --- a/lib/RT/Condition/OwnerChange.pm +++ b/lib/RT/Condition/OwnerChange.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/PriorityChange.pm b/lib/RT/Condition/PriorityChange.pm index be79c01..ae70fcf 100644 --- a/lib/RT/Condition/PriorityChange.pm +++ b/lib/RT/Condition/PriorityChange.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/PriorityExceeds.pm b/lib/RT/Condition/PriorityExceeds.pm index b43ef83..784382d 100644 --- a/lib/RT/Condition/PriorityExceeds.pm +++ b/lib/RT/Condition/PriorityExceeds.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/QueueChange.pm b/lib/RT/Condition/QueueChange.pm index ed3d9ff..e00cbc6 100644 --- a/lib/RT/Condition/QueueChange.pm +++ b/lib/RT/Condition/QueueChange.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/ReopenTicket.pm b/lib/RT/Condition/ReopenTicket.pm index a057e40..69ef8f9 100644 --- a/lib/RT/Condition/ReopenTicket.pm +++ b/lib/RT/Condition/ReopenTicket.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm index f3a87cd..9cbccf8 100644 --- a/lib/RT/Condition/StatusChange.pm +++ b/lib/RT/Condition/StatusChange.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Condition/UserDefined.pm b/lib/RT/Condition/UserDefined.pm index 1abee67..4f4ff18 100644 --- a/lib/RT/Condition/UserDefined.pm +++ b/lib/RT/Condition/UserDefined.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm index 7ea5433..a6b3269 100644 --- a/lib/RT/Config.pm +++ b/lib/RT/Config.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Crypt.pm b/lib/RT/Crypt.pm index 7554aab..e275295 100644 --- a/lib/RT/Crypt.pm +++ b/lib/RT/Crypt.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Crypt/GnuPG.pm b/lib/RT/Crypt/GnuPG.pm index 44d6518..316d2fa 100644 --- a/lib/RT/Crypt/GnuPG.pm +++ b/lib/RT/Crypt/GnuPG.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -1840,11 +1840,13 @@ sub Probe { return 0; } } else { + local $ENV{PATH} = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' + unless defined $ENV{PATH}; my $path = File::Which::which( $bin ); unless ($path) { $RT::Logger->warning( - "Can't find gpg binary '$bin' in PATH; GnuPG support has been disabled. ". - "Check the 'GnuPG' configuration in %GnuPG"); + "Can't find gpg binary '$bin' in PATH ($ENV{PATH}); GnuPG support has been disabled. ". + "You may need to specify a full path to gpg via the 'GnuPG' configuration in %GnuPG"); return 0; } $self->GnuPGPath( $bin = $path ); diff --git a/lib/RT/Crypt/GnuPG/CRLFHandle.pm b/lib/RT/Crypt/GnuPG/CRLFHandle.pm index 0ed93f5..5e7fc04 100644 --- a/lib/RT/Crypt/GnuPG/CRLFHandle.pm +++ b/lib/RT/Crypt/GnuPG/CRLFHandle.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Crypt/Role.pm b/lib/RT/Crypt/Role.pm index df53438..b7bf49d 100644 --- a/lib/RT/Crypt/Role.pm +++ b/lib/RT/Crypt/Role.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm index cb05e33..5351dba 100644 --- a/lib/RT/Crypt/SMIME.pm +++ b/lib/RT/Crypt/SMIME.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -163,11 +163,13 @@ sub Probe { return 0; } } else { + local $ENV{PATH} = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' + unless defined $ENV{PATH}; my $path = File::Which::which( $bin ); unless ($path) { $RT::Logger->warning( - "Can't find openssl binary '$bin' in PATH; SMIME support has been disabled. ". - "Check the 'OpenSSL' configuration in %OpenSSL"); + "Can't find openssl binary '$bin' in PATH ($ENV{PATH}); SMIME support has been disabled. ". + "You may need to specify a full path to opensssl via the 'OpenSSL' configuration in %OpenSSL"); return 0; } $self->OpenSSLPath( $bin = $path ); diff --git a/lib/RT/CurrentUser.pm b/lib/RT/CurrentUser.pm index a87cec3..0ec3170 100644 --- a/lib/RT/CurrentUser.pm +++ b/lib/RT/CurrentUser.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm index da6e16a..fe4e5f6 100644 --- a/lib/RT/CustomField.pm +++ b/lib/RT/CustomField.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -210,10 +210,10 @@ __PACKAGE__->RegisterBuiltInGroupings( 'RT::User' => [ 'Identity', 'Access control', 'Location', 'Phones' ], ); -__PACKAGE__->AddRight( General => SeeCustomField => 'View custom fields'); # loc_pair -__PACKAGE__->AddRight( Admin => AdminCustomField => 'Create, modify and delete custom fields'); # loc_pair -__PACKAGE__->AddRight( Admin => AdminCustomFieldValues => 'Create, modify and delete custom fields values'); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Add, modify and delete custom field values for objects'); # loc_pair +__PACKAGE__->AddRight( General => SeeCustomField => 'View custom fields'); # loc +__PACKAGE__->AddRight( Admin => AdminCustomField => 'Create, modify and delete custom fields'); # loc +__PACKAGE__->AddRight( Admin => AdminCustomFieldValues => 'Create, modify and delete custom fields values'); # loc +__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Add, modify and delete custom field values for objects'); # loc =head1 NAME @@ -1052,11 +1052,6 @@ sub SetRenderType { $self->FriendlyType)); } - # XXX: Remove this restriction once we support lists and cascaded selects - if ( $self->BasedOnObj->id and $type =~ /List/ ) { - return (0, $self->loc("We can't currently render as a List when basing categories on another custom field. Please use another render type.")); - } - return $self->_Set( Field => 'RenderType', Value => $type, @_ ); } diff --git a/lib/RT/CustomFieldValue.pm b/lib/RT/CustomFieldValue.pm index fb8d83f..1ba73ef 100644 --- a/lib/RT/CustomFieldValue.pm +++ b/lib/RT/CustomFieldValue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CustomFieldValues.pm b/lib/RT/CustomFieldValues.pm index 37d1594..25d5d69 100644 --- a/lib/RT/CustomFieldValues.pm +++ b/lib/RT/CustomFieldValues.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CustomFieldValues/External.pm b/lib/RT/CustomFieldValues/External.pm index 4e58388..96ffc00 100644 --- a/lib/RT/CustomFieldValues/External.pm +++ b/lib/RT/CustomFieldValues/External.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CustomFieldValues/Groups.pm b/lib/RT/CustomFieldValues/Groups.pm index 34722bb..48234e2 100644 --- a/lib/RT/CustomFieldValues/Groups.pm +++ b/lib/RT/CustomFieldValues/Groups.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/CustomFields.pm b/lib/RT/CustomFields.pm index e30aa42..eab9a10 100644 --- a/lib/RT/CustomFields.pm +++ b/lib/RT/CustomFields.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Dashboard.pm b/lib/RT/Dashboard.pm index 8fafc1c..6b9244f 100644 --- a/lib/RT/Dashboard.pm +++ b/lib/RT/Dashboard.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -75,17 +75,17 @@ use base qw/RT::SharedSetting/; use RT::SavedSearch; use RT::System; -'RT::System'->AddRight( Staff => SubscribeDashboard => 'Subscribe to dashboards'); # loc_pair +'RT::System'->AddRight( Staff => SubscribeDashboard => 'Subscribe to dashboards'); # loc -'RT::System'->AddRight( General => SeeDashboard => 'View system dashboards'); # loc_pair -'RT::System'->AddRight( Admin => CreateDashboard => 'Create system dashboards'); # loc_pair -'RT::System'->AddRight( Admin => ModifyDashboard => 'Modify system dashboards'); # loc_pair -'RT::System'->AddRight( Admin => DeleteDashboard => 'Delete system dashboards'); # loc_pair +'RT::System'->AddRight( General => SeeDashboard => 'View system dashboards'); # loc +'RT::System'->AddRight( Admin => CreateDashboard => 'Create system dashboards'); # loc +'RT::System'->AddRight( Admin => ModifyDashboard => 'Modify system dashboards'); # loc +'RT::System'->AddRight( Admin => DeleteDashboard => 'Delete system dashboards'); # loc -'RT::System'->AddRight( Staff => SeeOwnDashboard => 'View personal dashboards'); # loc_pair -'RT::System'->AddRight( Staff => CreateOwnDashboard => 'Create personal dashboards'); # loc_pair -'RT::System'->AddRight( Staff => ModifyOwnDashboard => 'Modify personal dashboards'); # loc_pair -'RT::System'->AddRight( Staff => DeleteOwnDashboard => 'Delete personal dashboards'); # loc_pair +'RT::System'->AddRight( Staff => SeeOwnDashboard => 'View personal dashboards'); # loc +'RT::System'->AddRight( Staff => CreateOwnDashboard => 'Create personal dashboards'); # loc +'RT::System'->AddRight( Staff => ModifyOwnDashboard => 'Modify personal dashboards'); # loc +'RT::System'->AddRight( Staff => DeleteOwnDashboard => 'Delete personal dashboards'); # loc =head2 ObjectName diff --git a/lib/RT/Dashboard/Mailer.pm b/lib/RT/Dashboard/Mailer.pm index c4de860..5126560 100644 --- a/lib/RT/Dashboard/Mailer.pm +++ b/lib/RT/Dashboard/Mailer.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -147,7 +147,7 @@ sub IsSubscriptionReady { my $sub_hour = $subscription->SubValue('Hour'); my $sub_dow = $subscription->SubValue('Dow'); my $sub_dom = $subscription->SubValue('Dom'); - my $sub_fow = $subscription->SubValue('Fow'); + my $sub_fow = $subscription->SubValue('Fow') || 1; my ($hour, $dow, $dom) = @{ $args{LocalTime} }; @@ -166,8 +166,6 @@ sub IsSubscriptionReady { return 0 if $sub_dow ne $dow; # does it match the "every N weeks" clause? - $sub_fow = 1 if !$sub_fow; - return 1 if $counter % $sub_fow == 0; $subscription->SetSubValues(Counter => $counter + 1) @@ -426,12 +424,15 @@ sub BuildEmail { Type => 'text/html', Charset => 'UTF-8', Disposition => 'inline', + Encoding => "base64", ); for my $part (@parts) { $entity->add_part($part); } + $entity->make_singlepart; + return $entity; } diff --git a/lib/RT/Dashboards.pm b/lib/RT/Dashboards.pm index 023745c..7c8511f 100644 --- a/lib/RT/Dashboards.pm +++ b/lib/RT/Dashboards.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Date.pm b/lib/RT/Date.pm index 28a1593..509e11c 100644 --- a/lib/RT/Date.pm +++ b/lib/RT/Date.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -920,7 +920,7 @@ sub RFC2822 { my ($date, $time) = ('',''); $date .= "$DAYS_OF_WEEK[$wday], " if $args{'DayOfWeek'} && $args{'Date'}; - $date .= "$mday $MONTHS[$mon] $year" if $args{'Date'}; + $date .= sprintf("%02d %s %04d", $mday, $MONTHS[$mon], $year) if $args{'Date'}; if ( $args{'Time'} ) { $time .= sprintf("%02d:%02d", $hour, $min); @@ -988,28 +988,19 @@ sub iCal { @_, ); - my $tz; - if ( $args{'Date'} && !$args{'Time'} ) { - $tz = 'user'; - } else { - $tz = 'utc'; - } - - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydaym,$isdst,$offset) = - $self->Localtime( $tz ); - - #the month needs incrementing, as gmtime returns 0-11 - $mon++; - my $res; if ( $args{'Date'} && !$args{'Time'} ) { - $res = sprintf( '%04d%02d%02d', $year, $mon, $mday ); - } - elsif ( !$args{'Date'} && $args{'Time'} ) { + my (undef, undef, undef, $mday, $mon, $year) = + $self->Localtime( 'user' ); + $res = sprintf( '%04d%02d%02d', $year, $mon+1, $mday ); + } elsif ( !$args{'Date'} && $args{'Time'} ) { + my ($sec, $min, $hour) = + $self->Localtime( 'utc' ); $res = sprintf( 'T%02d%02d%02dZ', $hour, $min, $sec ); - } - else { - $res = sprintf( '%04d%02d%02dT%02d%02d%02dZ', $year, $mon, $mday, $hour, $min, $sec ); + } else { + my ($sec, $min, $hour, $mday, $mon, $year) = + $self->Localtime( 'utc' ); + $res = sprintf( '%04d%02d%02dT%02d%02d%02dZ', $year, $mon+1, $mday, $hour, $min, $sec ); } return $res; } diff --git a/lib/RT/DependencyWalker.pm b/lib/RT/DependencyWalker.pm index a1890e1..97f7ce2 100644 --- a/lib/RT/DependencyWalker.pm +++ b/lib/RT/DependencyWalker.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -51,7 +51,7 @@ package RT::DependencyWalker; use strict; use warnings; -use RT::DependencyWalker::Dependencies; +use RT::DependencyWalker::FindDependencies; use Carp; sub new { diff --git a/lib/RT/DependencyWalker/FindDependencies.pm b/lib/RT/DependencyWalker/FindDependencies.pm new file mode 100644 index 0000000..b3d3d19 --- /dev/null +++ b/lib/RT/DependencyWalker/FindDependencies.pm @@ -0,0 +1,65 @@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC +# +# +# (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 }}} + +package RT::DependencyWalker::FindDependencies; + +use strict; +use warnings; + +sub new { + my $class = shift; + return bless {out => [], in => []}, $class; +} + +sub Add { + my $self = shift; + my ($dir, $obj) = @_; + push @{$self->{$dir}}, $obj; +} + +1; diff --git a/lib/RT/EmailParser.pm b/lib/RT/EmailParser.pm index 8a4b2a3..283cc45 100644 --- a/lib/RT/EmailParser.pm +++ b/lib/RT/EmailParser.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -561,9 +561,38 @@ sub ParseEmailAddress { $logger->($e->{'value'} ." is not a valid email address"); } } + + $self->CleanupAddresses(@addresses); + return @addresses; } +=head2 CleanupAddresses ARRAY + +Massages an array of L objects to make their email addresses +more palatable. + +Currently this strips off surrounding single quotes around C<< ->address >> and +B<< modifies the L objects in-place >>. + +Returns the list of objects for convienence in C/C chains. + +=cut + +sub CleanupAddresses { + my $self = shift; + + for my $addr (@_) { + next unless defined $addr; + # Outlook sometimes sends addresses surrounded by single quotes; + # clean them all up + if ((my $email = $addr->address) =~ s/^'(.+)'$/$1/) { + $addr->address($email); + } + } + return @_; +} + =head2 RescueOutlook Outlook 2007/2010 have a bug when you write an email with the html format. diff --git a/lib/RT/Generated.pm b/lib/RT/Generated.pm index cb02eb4..c970d63 100644 --- a/lib/RT/Generated.pm +++ b/lib/RT/Generated.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -50,7 +50,7 @@ package RT; use warnings; use strict; -our $VERSION = '4.2.0'; +our $VERSION = '4.2.2'; our ($MAJOR_VERSION, $MINOR_VERSION, $REVISION) = $VERSION =~ /^(\d)\.(\d)\.(\d+)/; diff --git a/lib/RT/Generated.pm.in b/lib/RT/Generated.pm.in index 77b919b..d1b09fe 100644 --- a/lib/RT/Generated.pm.in +++ b/lib/RT/Generated.pm.in @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Graph/Tickets.pm b/lib/RT/Graph/Tickets.pm index 753ff20..477a5d0 100644 --- a/lib/RT/Graph/Tickets.pm +++ b/lib/RT/Graph/Tickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm index 2bec67b..f38f7a1 100644 --- a/lib/RT/Group.pm +++ b/lib/RT/Group.pm @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -85,16 +85,16 @@ use RT::GroupMembers; use RT::Principals; use RT::ACL; -__PACKAGE__->AddRight( Admin => AdminGroup => 'Modify group metadata or delete group'); # loc_pair -__PACKAGE__->AddRight( Admin => AdminGroupMembership => 'Modify group membership roster'); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyOwnMembership => 'Join or leave group'); # loc_pair -__PACKAGE__->AddRight( Admin => EditSavedSearches => 'Create, modify and delete saved searches'); # loc_pair -__PACKAGE__->AddRight( Staff => ShowSavedSearches => 'View saved searches'); # loc_pair -__PACKAGE__->AddRight( Staff => SeeGroup => 'View group'); # loc_pair -__PACKAGE__->AddRight( Staff => SeeGroupDashboard => 'View group dashboards'); # loc_pair -__PACKAGE__->AddRight( Admin => CreateGroupDashboard => 'Create group dashboards'); # loc_pair -__PACKAGE__->AddRight( Admin => ModifyGroupDashboard => 'Modify group dashboards'); # loc_pair -__PACKAGE__->AddRight( Admin => DeleteGroupDashboard => 'Delete group dashboards'); # loc_pair +__PACKAGE__->AddRight( Admin => AdminGroup => 'Modify group metadata or delete group'); # loc +__PACKAGE__->AddRight( Admin => AdminGroupMembership => 'Modify group membership roster'); # loc +__PACKAGE__->AddRight( Staff => ModifyOwnMembership => 'Join or leave group'); # loc +__PACKAGE__->AddRight( Admin => EditSavedSearches => 'Create, modify and delete saved searches'); # loc +__PACKAGE__->AddRight( Staff => ShowSavedSearches => 'View saved searches'); # loc +__PACKAGE__->AddRight( Staff => SeeGroup => 'View group'); # loc +__PACKAGE__->AddRight( Staff => SeeGroupDashboard => 'View group dashboards'); # loc +__PACKAGE__->AddRight( Admin => CreateGroupDashboard => 'Create group dashboards'); # loc +__PACKAGE__->AddRight( Admin => ModifyGroupDashboard => 'Modify group dashboards'); # loc +__PACKAGE__->AddRight( Admin => DeleteGroupDashboard => 'Delete group dashboards'); # loc =head1 METHODS @@ -1680,10 +1680,12 @@ sub PreInflate { return $duplicated->(); } } elsif ($data->{Domain} =~ /^(SystemInternal|RT::System-Role)$/) { - $obj->LoadByCols( Domain => $data->{Domain}, Type => $data->{Type} ); + $obj->LoadByCols( Domain => $data->{Domain}, Name => $data->{Name} ); return $duplicated->() if $obj->Id; } elsif ($data->{Domain} eq "RT::Queue-Role") { - $obj->LoadQueueRoleGroup( Queue => $data->{Instance}, Type => $data->{Type} ); + my $queue = RT::Queue->new( RT->SystemUser ); + $queue->Load( $data->{Instance} ); + $obj->LoadRoleGroup( Object => $queue, Name => $data->{Name} ); return $duplicated->() if $obj->Id; } @@ -1693,6 +1695,10 @@ sub PreInflate { Disabled => $disabled, ObjectId => 0, ); + + # Now we have a principal id, set the id for the group record + $data->{id} = $id; + $importer->Resolve( $principal_uid => ref($principal), $id ); $importer->Postpone( diff --git a/lib/RT/GroupMember.pm b/lib/RT/GroupMember.pm index 93e65a8..26d62e3 100644 --- a/lib/RT/GroupMember.pm +++ b/lib/RT/GroupMember.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/GroupMembers.pm b/lib/RT/GroupMembers.pm index 55861e5..91c2bf9 100644 --- a/lib/RT/GroupMembers.pm +++ b/lib/RT/GroupMembers.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Groups.pm b/lib/RT/Groups.pm index cc1e8e0..1ecc312 100644 --- a/lib/RT/Groups.pm +++ b/lib/RT/Groups.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm index a87f72a..a8652e4 100644 --- a/lib/RT/Handle.pm +++ b/lib/RT/Handle.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -83,17 +83,17 @@ L, using the C configuration. =cut sub FinalizeDatabaseType { - eval { - use base "DBIx::SearchBuilder::Handle::". RT->Config->Get('DatabaseType'); - }; - my $db_type = RT->Config->Get('DatabaseType'); - if ($@) { + my $package = "DBIx::SearchBuilder::Handle::$db_type"; + + unless (eval "require $package; 1;") { die "Unable to load DBIx::SearchBuilder database handle for '$db_type'.\n". "Perhaps you've picked an invalid database type or spelled it incorrectly.\n". $@; } + @RT::Handle::ISA = ($package); + # We use COLLATE NOCASE to enforce case insensitivity on the normally # case-sensitive SQLite, LOWER() approach works, but lucks performance # due to absence of functional indexes @@ -365,6 +365,9 @@ sub CreateDatabase { elsif ( $db_type eq 'Pg' ) { $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0"); } + elsif ( $db_type eq 'mysql' ) { + $status = $dbh->do("CREATE DATABASE $db_name DEFAULT CHARACTER SET utf8"); + } else { $status = $dbh->do("CREATE DATABASE $db_name"); } @@ -552,6 +555,15 @@ sub InsertIndexes { $path = $base_path; } + if ( $db_type eq 'Oracle' ) { + my $db_user = RT->Config->Get('DatabaseUser'); + my $status = $dbh->do( "ALTER SESSION SET CURRENT_SCHEMA=$db_user" ); + unless ( $status ) { + return $status, "Couldn't set current schema to $db_user." + ."\nError: ". $dbh->errstr; + } + } + local $@; eval { require $path; 1 } or return (0, "Couldn't execute '$path': " . $@); @@ -936,10 +948,14 @@ sub InsertData { my $apply_to = delete $item->{'ApplyTo'}; if ( $item->{'BasedOn'} ) { - if ( $item->{'LookupType'} ) { + if ( $item->{'BasedOn'} =~ /^\d+$/) { + # Already have an ID -- should be fine + } elsif ( $item->{'LookupType'} ) { my $basedon = RT::CustomField->new($RT::SystemUser); - my ($ok, $msg ) = $basedon->LoadByCols( Name => $item->{'BasedOn'}, - LookupType => $item->{'LookupType'} ); + my ($ok, $msg ) = $basedon->LoadByCols( + Name => $item->{'BasedOn'}, + LookupType => $item->{'LookupType'}, + Disabled => 0 ); if ($ok) { $item->{'BasedOn'} = $basedon->Id; } else { @@ -1301,8 +1317,8 @@ sub Indexes { } elsif ( $db_type eq 'Pg' ) { $list = $dbh->selectall_arrayref( - 'select tablename, indexname from pg_indexes where schemaname = ?', - undef, 'public' + 'select tablename, indexname from pg_indexes', + undef, ); } elsif ( $db_type eq 'SQLite' ) { @@ -1420,14 +1436,14 @@ sub IndexInfo { $res{'Unique'} = (grep lc $_->[1] eq lc $args{'Name'}, @$list)[0][2]? 1 : 0; } elsif ( $db_type eq 'Oracle' ) { - my $index = $dbh->selectrow_hashref( + my $index = $dbh->selectrow_arrayref( 'select uniqueness, funcidx_status from dba_indexes where lower(table_name) = ? AND lower(index_name) = ? AND LOWER(Owner) = ?', undef, lc $args{'Table'}, lc $args{'Name'}, lc RT->Config->Get('DatabaseUser'), ); - return () unless $index && keys %$index; - $res{'Unique'} = $index->{'uniqueness'} eq 'UNIQUE'? 1 : 0; - $res{'Functional'} = $index->{'funcidx_status'}? 1 : 0; + return () unless $index && @$index; + $res{'Unique'} = $index->[0] eq 'UNIQUE'? 1 : 0; + $res{'Functional'} = $index->[1] ? 1 : 0; my %columns = map @$_, @{ $dbh->selectall_arrayref( 'select column_position, column_name from dba_ind_columns @@ -1477,7 +1493,17 @@ sub DropIndex { } elsif ( $db_type eq 'Oracle' ) { my $user = RT->Config->Get('DatabaseUser'); - $res = $dbh->do("drop index $user.$args{'Name'}"); + # Check if it has constraints associated with it + my ($constraint) = $dbh->selectrow_arrayref( + 'SELECT constraint_name, table_name FROM dba_constraints WHERE LOWER(owner) = ? AND LOWER(index_name) = ?', + undef, lc $user, lc $args{'Name'} + ); + if ($constraint) { + my ($constraint_name, $table) = @{$constraint}; + $res = $dbh->do("ALTER TABLE $user.$table DROP CONSTRAINT $constraint_name"); + } else { + $res = $dbh->do("DROP INDEX $user.$args{'Name'}"); + } } else { die "Not implemented"; diff --git a/lib/RT/I18N.pm b/lib/RT/I18N.pm index 31e8741..5ac3f6c 100644 --- a/lib/RT/I18N.pm +++ b/lib/RT/I18N.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/I18N/cs.pm b/lib/RT/I18N/cs.pm index be2d819..3c151fe 100644 --- a/lib/RT/I18N/cs.pm +++ b/lib/RT/I18N/cs.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/I18N/de.pm b/lib/RT/I18N/de.pm index b8352da..3a40a7f 100644 --- a/lib/RT/I18N/de.pm +++ b/lib/RT/I18N/de.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/I18N/fr.pm b/lib/RT/I18N/fr.pm index 3e5b2d2..33ac68e 100644 --- a/lib/RT/I18N/fr.pm +++ b/lib/RT/I18N/fr.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/I18N/i_default.pm b/lib/RT/I18N/i_default.pm index 2b48c62..316f51a 100644 --- a/lib/RT/I18N/i_default.pm +++ b/lib/RT/I18N/i_default.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/I18N/ru.pm b/lib/RT/I18N/ru.pm index c10ac69..0bce4af 100644 --- a/lib/RT/I18N/ru.pm +++ b/lib/RT/I18N/ru.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Installer.pm b/lib/RT/Installer.pm index d876e10..c48b06c 100644 --- a/lib/RT/Installer.pm +++ b/lib/RT/Installer.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/CLI.pm b/lib/RT/Interface/CLI.pm index 7fa8452..8b6e540 100644 --- a/lib/RT/Interface/CLI.pm +++ b/lib/RT/Interface/CLI.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm index 444f842..7c1e126 100644 --- a/lib/RT/Interface/Email.pm +++ b/lib/RT/Interface/Email.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -912,7 +912,7 @@ sub ParseCcAddressesFromHead { return grep $_ ne $current_address && !RT::EmailParser->IsRTAddress( $_ ), map lc $user->CanonicalizeEmailAddress( $_->address ), - map Email::Address->parse( $args{'Head'}->get( $_ ) ), + map RT::EmailParser->CleanupAddresses( Email::Address->parse( $args{'Head'}->get( $_ ) ) ), qw(To Cc); } @@ -1765,8 +1765,9 @@ sub _RecordSendEmailFailure { =head2 ConvertHTMLToText HTML -Takes HTML and converts it to plain text. Appropriate for generating a plain -text part from an HTML part of an email. +Takes HTML and converts it to plain text. Appropriate for generating a +plain text part from an HTML part of an email. Returns undef if +conversion fails. =cut @@ -1774,20 +1775,27 @@ sub ConvertHTMLToText { my $html = shift; require HTML::FormatText::WithLinks::AndTables; - return HTML::FormatText::WithLinks::AndTables->convert( - $html => { - leftmargin => 0, - rightmargin => 78, - no_rowspacing => 1, - before_link => '', - after_link => ' (%l)', - footnote => '', - skip_linked_urls => 1, - with_emphasis => 0, - } - ); + my $text; + eval { + $text = HTML::FormatText::WithLinks::AndTables->convert( + $html => { + leftmargin => 0, + rightmargin => 78, + no_rowspacing => 1, + before_link => '', + after_link => ' (%l)', + footnote => '', + skip_linked_urls => 1, + with_emphasis => 0, + } + ); + $text //= ''; + }; + $RT::Logger->error("Failed to downgrade HTML to plain text: $@") if $@; + return $text; } + RT::Base->_ImportOverlays(); 1; diff --git a/lib/RT/Interface/Email/Auth/Crypt.pm b/lib/RT/Interface/Email/Auth/Crypt.pm index d716e2c..2703af9 100644 --- a/lib/RT/Interface/Email/Auth/Crypt.pm +++ b/lib/RT/Interface/Email/Auth/Crypt.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Email/Auth/MailFrom.pm b/lib/RT/Interface/Email/Auth/MailFrom.pm index bfe4939..b353907 100644 --- a/lib/RT/Interface/Email/Auth/MailFrom.pm +++ b/lib/RT/Interface/Email/Auth/MailFrom.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/REST.pm b/lib/RT/Interface/REST.pm index 3a85c2d..17fe446 100644 --- a/lib/RT/Interface/REST.pm +++ b/lib/RT/Interface/REST.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -47,6 +47,7 @@ # END BPS TAGGED BLOCK }}} package RT::Interface::REST; +use LWP::MediaTypes qw(guess_media_type); use strict; use warnings; use RT; diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm index 88800a6..0aebeed 100644 --- a/lib/RT/Interface/Web.pm +++ b/lib/RT/Interface/Web.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -1367,10 +1367,16 @@ our %is_whitelisted_component = ( # While these can be used for denial-of-service against RT # (construct a very inefficient query and trick lots of users into # running them against RT) it's incredibly useful to be able to link - # to a search result or bookmark a result page. + # to a search result (or chart) or bookmark a result page. '/Search/Results.html' => 1, '/Search/Simple.html' => 1, - '/m/tickets/search' => 1, + '/m/tickets/search' => 1, + '/Search/Chart.html' => 1, + + # This page takes Attachment and Transaction argument to figure + # out what to show, but it's read only and will deny information if you + # don't have ShowOutgoingEmail. + '/Ticket/ShowEmailRecord.html' => 1, ); # Components which are blacklisted from automatic, argument-based whitelisting. @@ -2032,7 +2038,9 @@ sub CreateTicket { } for my $argument (qw(Encrypt Sign)) { - $MIMEObj->head->replace( "X-RT-$argument" => $ARGS{$argument} ? 1 : 0 ); + if ( defined $ARGS{ $argument } ) { + $MIMEObj->head->replace( "X-RT-$argument" => $ARGS{$argument} ? 1 : 0 ); + } } my %create_args = ( @@ -3505,39 +3513,75 @@ sub ProcessRecordBulkCustomFields { my $ARGSRef = $args{'ARGSRef'}; + my %data; + my @results; foreach my $key ( keys %$ARGSRef ) { next unless $key =~ /^Bulk-(Add|Delete)-CustomField-(\d+)-(.*)$/; my ($op, $cfid, $rest) = ($1, $2, $3); next if $rest eq "Category"; - my $cf = RT::CustomField->new( $session{'CurrentUser'} ); - $cf->Load( $cfid ); - next unless $cf->Id; + my $res = $data{$cfid} ||= {}; + unless (keys %$res) { + my $cf = RT::CustomField->new( $session{'CurrentUser'} ); + $cf->Load( $cfid ); + next unless $cf->Id; + + $res->{'cf'} = $cf; + } + + if ( $op eq 'Delete' && $rest eq 'AllValues' ) { + $res->{'DeleteAll'} = $ARGSRef->{$key}; + next; + } my @values = _NormalizeObjectCustomFieldValue( - CustomField => $cf, + CustomField => $res->{'cf'}, Value => $ARGSRef->{$key}, Param => $key, ); + next unless @values; + $res->{$op} = \@values; + } + + while ( my ($cfid, $data) = each %data ) { + # just add one value for fields with single value + if ( $data->{'Add'} && $data->{'cf'}->MaxValues == 1 ) { + my ( $id, $msg ) = $args{'RecordObj'}->AddCustomFieldValue( + Field => $cfid, + Value => $data->{'Add'}[-1], + ); + push @results, $msg; + next; + } my $current_values = $args{'RecordObj'}->CustomFieldValues( $cfid ); - foreach my $value (@values) { - if ( $op eq 'Delete' && $current_values->HasEntry($value) ) { + if ( $data->{'DeleteAll'} ) { + while ( my $value = $current_values->Next ) { my ( $id, $msg ) = $args{'RecordObj'}->DeleteCustomFieldValue( - Field => $cfid, - Value => $value + Field => $cfid, + ValueId => $value->id, ); push @results, $msg; } + } + foreach my $value ( @{ $data->{'Delete'} || [] } ) { + next unless $current_values->HasEntry($value); - elsif ( $op eq 'Add' && !$current_values->HasEntry($value) ) { - my ( $id, $msg ) = $args{'RecordObj'}->AddCustomFieldValue( - Field => $cfid, - Value => $value - ); - push @results, $msg; - } + my ( $id, $msg ) = $args{'RecordObj'}->DeleteCustomFieldValue( + Field => $cfid, + Value => $value + ); + push @results, $msg; + } + foreach my $value ( @{ $data->{'Add'} || [] } ) { + next if $current_values->HasEntry($value); + + my ( $id, $msg ) = $args{'RecordObj'}->AddCustomFieldValue( + Field => $cfid, + Value => $value + ); + push @results, $msg; } } return @results; @@ -3579,7 +3623,8 @@ sub GetColumnMapEntry { } # complex things - elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.\{(.+)\}$/ ) { + elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.(.+)$/ ) { + $subkey =~ s/^\{(.*)\}$/$1/; return undef unless $args{'Map'}->{$mainkey}; return $args{'Map'}{$mainkey}{ $args{'Attribute'} } unless ref $args{'Map'}{$mainkey}{ $args{'Attribute'} } eq 'CODE'; diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm index f0e033f..79cca99 100644 --- a/lib/RT/Interface/Web/Handler.pm +++ b/lib/RT/Interface/Web/Handler.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Web/Menu.pm b/lib/RT/Interface/Web/Menu.pm index 3343b9b..c048609 100644 --- a/lib/RT/Interface/Web/Menu.pm +++ b/lib/RT/Interface/Web/Menu.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Web/QueryBuilder.pm b/lib/RT/Interface/Web/QueryBuilder.pm index 5464278..a1b0662 100644 --- a/lib/RT/Interface/Web/QueryBuilder.pm +++ b/lib/RT/Interface/Web/QueryBuilder.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/lib/RT/Interface/Web/QueryBuilder/Tree.pm index cd68ea1..f92e736 100644 --- a/lib/RT/Interface/Web/QueryBuilder/Tree.pm +++ b/lib/RT/Interface/Web/QueryBuilder/Tree.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Web/Request.pm b/lib/RT/Interface/Web/Request.pm index 53684c2..eeb20fe 100644 --- a/lib/RT/Interface/Web/Request.pm +++ b/lib/RT/Interface/Web/Request.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Interface/Web/Session.pm b/lib/RT/Interface/Web/Session.pm index f2dd603..368b51a 100644 --- a/lib/RT/Interface/Web/Session.pm +++ b/lib/RT/Interface/Web/Session.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -131,6 +131,8 @@ sub Attributes { Transaction => 1, }; } + $res->{LongReadLen} = RT->Config->Get('MaxAttachmentSize') + if $class->isa('Apache::Session::Oracle'); return $res; } diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm index 2ff7caa..659a648 100644 --- a/lib/RT/Lifecycle.pm +++ b/lib/RT/Lifecycle.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Lifecycle/Ticket.pm b/lib/RT/Lifecycle/Ticket.pm index 596832b..bd0bfc5 100644 --- a/lib/RT/Lifecycle/Ticket.pm +++ b/lib/RT/Lifecycle/Ticket.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm index c86b1a0..0418b8f 100644 --- a/lib/RT/Link.pm +++ b/lib/RT/Link.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Links.pm b/lib/RT/Links.pm index 292bd94..2dc66bd 100644 --- a/lib/RT/Links.pm +++ b/lib/RT/Links.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Migrate.pm b/lib/RT/Migrate.pm index baa7840..9f04294 100644 --- a/lib/RT/Migrate.pm +++ b/lib/RT/Migrate.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -176,11 +176,12 @@ sub progress { sub setup_logging { my ($dir, $file) = @_; - $RT::LogToScreen = 'warning'; - $RT::LogToFile = 'warning'; - $RT::LogDir = $dir; - $RT::LogToFileNamed = $file; - $RT::LogStackTraces = 'error'; + + RT->Config->Set(LogToSTDERR => 'warning'); + RT->Config->Set(LogToFile => 'warning'); + RT->Config->Set(LogDir => $dir); + RT->Config->Set(LogToFileNamed => $file); + RT->Config->Set(LogStackTraces => 'error'); undef $RT::Logger; RT->InitLogging(); diff --git a/lib/RT/Migrate/Importer.pm b/lib/RT/Migrate/Importer.pm index 9864274..14fb23a 100644 --- a/lib/RT/Migrate/Importer.pm +++ b/lib/RT/Migrate/Importer.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -427,7 +427,7 @@ sub CloseStream { # Take global CFs which we made and make them un-global my @queues = grep {$_} map {$self->LookupObj( $_ )} @{$self->{NewQueues}}; for my $obj (map {$self->LookupObj( $_ )} @{$self->{NewCFs}}) { - my $ocf = $obj->IsApplied( 0 ) or next; + my $ocf = $obj->IsGlobal or next; $ocf->Delete; $obj->AddToObject( $_ ) for @queues; } diff --git a/lib/RT/Migrate/Importer/File.pm b/lib/RT/Migrate/Importer/File.pm index 4edd951..02e9f44 100644 --- a/lib/RT/Migrate/Importer/File.pm +++ b/lib/RT/Migrate/Importer/File.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Migrate/Incremental.pm b/lib/RT/Migrate/Incremental.pm index 1ed9aca..c0bc440 100644 --- a/lib/RT/Migrate/Incremental.pm +++ b/lib/RT/Migrate/Incremental.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -410,6 +410,18 @@ s!(?<=Your ticket has been (?:approved|rejected) by { eval { )\$Approval->OwnerO }, }, + '4.0.19' => { + 'RT::CustomField' => sub { + my ($ref) = @_; + $ref->{LookupType} = 'RT::Class-RT::Article' + if $ref->{LookupType} eq 'RT::FM::Class-RT::FM::Article'; + }, + 'RT::ObjectCustomFieldValue' => sub { + my ($ref) = @_; + $ref->{ObjectType} = 'RT::Article' + if $ref->{ObjectType} eq 'RT::FM::Article'; + }, + }, '4.1.0' => { @@ -525,7 +537,7 @@ s!(?<=Your ticket has been (?:approved|rejected) by { eval { )\$Approval->OwnerO 'RT::Group' => sub { my ($ref) = @_; $ref->{Name} = $ref->{Type} - if $ref->Domain =~ /^(ACLEquivalence|SystemInternal|.*-Role)$/; + if $ref->{Domain} =~ /^(ACLEquivalence|SystemInternal|.*-Role)$/; }, }, @@ -617,6 +629,29 @@ This is a forward of ticket #{ $Ticket->id } } }, }, + + '4.2.1' => { + 'RT::Attribute' => sub { + my ($ref, $classref) = @_; + if ($ref->{ObjectType} eq "RT::System" and $ref->{Name} eq "BrandedSubjectTag") { + $$classref = undef; + } + }, + }, + + '4.2.2' => { + 'RT::CustomField' => sub { + my ($ref) = @_; + $ref->{LookupType} = 'RT::Class-RT::Article' + if $ref->{LookupType} eq 'RT::FM::Class-RT::FM::Article'; + }, + 'RT::ObjectCustomFieldValue' => sub { + my ($ref) = @_; + $ref->{ObjectType} = 'RT::Article' + if $ref->{ObjectType} eq 'RT::FM::Article'; + }, + }, + ); 1; diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm index 6e43cfc..2afb7fe 100644 --- a/lib/RT/Migrate/Serializer.pm +++ b/lib/RT/Migrate/Serializer.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -112,6 +112,9 @@ sub Metadata { # Determine the highest upgrade step that we run my @versions = ($RT::VERSION, keys %RT::Migrate::Incremental::UPGRADES); my ($max) = reverse sort cmp_version @versions; + # we don't want to run upgrades to 4.2.x if we're running + # the serializier on an 4.0 instance. + $max = $RT::VERSION unless $self->{Incremental}; return { Format => "0.8", @@ -238,7 +241,7 @@ sub PushBasics { # System role groups my $systemroles = RT::Groups->new( RT->SystemUser ); - $systemroles->LimitToRolesForSystem; + $systemroles->LimitToRolesForObject( RT->System ); $self->PushObj( $systemroles ); # CFs on Users, Groups, Queues diff --git a/lib/RT/Migrate/Serializer/File.pm b/lib/RT/Migrate/Serializer/File.pm index f8231e8..76415cf 100644 --- a/lib/RT/Migrate/Serializer/File.pm +++ b/lib/RT/Migrate/Serializer/File.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Migrate/Serializer/IncrementalRecord.pm b/lib/RT/Migrate/Serializer/IncrementalRecord.pm index 50cb65a..cc390ea 100644 --- a/lib/RT/Migrate/Serializer/IncrementalRecord.pm +++ b/lib/RT/Migrate/Serializer/IncrementalRecord.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Migrate/Serializer/IncrementalRecords.pm b/lib/RT/Migrate/Serializer/IncrementalRecords.pm index 5e3a408..068428b 100644 --- a/lib/RT/Migrate/Serializer/IncrementalRecords.pm +++ b/lib/RT/Migrate/Serializer/IncrementalRecords.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectClass.pm b/lib/RT/ObjectClass.pm index 4a88263..887d41c 100644 --- a/lib/RT/ObjectClass.pm +++ b/lib/RT/ObjectClass.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectClasses.pm b/lib/RT/ObjectClasses.pm index 267cf71..6963e92 100644 --- a/lib/RT/ObjectClasses.pm +++ b/lib/RT/ObjectClasses.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectCustomField.pm b/lib/RT/ObjectCustomField.pm index 6041286..3437116 100644 --- a/lib/RT/ObjectCustomField.pm +++ b/lib/RT/ObjectCustomField.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectCustomFieldValue.pm b/lib/RT/ObjectCustomFieldValue.pm index b2a6c51..226ba0c 100644 --- a/lib/RT/ObjectCustomFieldValue.pm +++ b/lib/RT/ObjectCustomFieldValue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectCustomFieldValues.pm b/lib/RT/ObjectCustomFieldValues.pm index 547708c..c55a684 100644 --- a/lib/RT/ObjectCustomFieldValues.pm +++ b/lib/RT/ObjectCustomFieldValues.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectCustomFields.pm b/lib/RT/ObjectCustomFields.pm index b9522d8..424345f 100644 --- a/lib/RT/ObjectCustomFields.pm +++ b/lib/RT/ObjectCustomFields.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectScrip.pm b/lib/RT/ObjectScrip.pm index 80ed48a..740f508 100644 --- a/lib/RT/ObjectScrip.pm +++ b/lib/RT/ObjectScrip.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectScrips.pm b/lib/RT/ObjectScrips.pm index 6bf2855..6d5e052 100644 --- a/lib/RT/ObjectScrips.pm +++ b/lib/RT/ObjectScrips.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectTopic.pm b/lib/RT/ObjectTopic.pm index cb20d52..3596b5b 100644 --- a/lib/RT/ObjectTopic.pm +++ b/lib/RT/ObjectTopic.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ObjectTopics.pm b/lib/RT/ObjectTopics.pm index ca83c11..3e51e79 100644 --- a/lib/RT/ObjectTopics.pm +++ b/lib/RT/ObjectTopics.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/PlackRunner.pm b/lib/RT/PlackRunner.pm index 53f4dd6..5f5975f 100644 --- a/lib/RT/PlackRunner.pm +++ b/lib/RT/PlackRunner.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Plugin.pm b/lib/RT/Plugin.pm index 07b25f7..cb22ae4 100644 --- a/lib/RT/Plugin.pm +++ b/lib/RT/Plugin.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Pod/HTML.pm b/lib/RT/Pod/HTML.pm index 540c1f1..c44a50f 100644 --- a/lib/RT/Pod/HTML.pm +++ b/lib/RT/Pod/HTML.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -145,6 +145,12 @@ sub resolve_local_link { # We process README separately in devel/tools/rt-static-docs $local = $name; } + elsif ($name =~ /^UPGRADING.*/) { + # If an UPGRADING file is referred to anywhere else (such as + # templates.pod) we won't have seen UPGRADING yet and will treat + # it as a non-local file. + $local = $name; + } # These matches handle links that look like filenames, such as those we # parse out of F<> tags. elsif ( $name =~ m{^(?:lib/)(RT/[\w/]+?)\.pm$} diff --git a/lib/RT/Pod/HTMLBatch.pm b/lib/RT/Pod/HTMLBatch.pm index 94004f1..2545ea9 100644 --- a/lib/RT/Pod/HTMLBatch.pm +++ b/lib/RT/Pod/HTMLBatch.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Pod/Search.pm b/lib/RT/Pod/Search.pm index 29e7d43..e0670ea 100644 --- a/lib/RT/Pod/Search.pm +++ b/lib/RT/Pod/Search.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm index d2a31d8..fe8a25a 100644 --- a/lib/RT/Principal.pm +++ b/lib/RT/Principal.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Principals.pm b/lib/RT/Principals.pm index 3ef1bdc..62d0d16 100644 --- a/lib/RT/Principals.pm +++ b/lib/RT/Principals.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm index 02f66cf..9b680fd 100644 --- a/lib/RT/Queue.pm +++ b/lib/RT/Queue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -106,37 +106,37 @@ use RT::Interface::Email; # $self->loc('rejected'); # For the string extractor to get a string to localize # $self->loc('deleted'); # For the string extractor to get a string to localize -__PACKAGE__->AddRight( General => SeeQueue => 'View queue' ); # loc_pair -__PACKAGE__->AddRight( Admin => AdminQueue => 'Create, modify and delete queue' ); # loc_pair -__PACKAGE__->AddRight( Admin => ShowACL => 'Display Access Control List' ); # loc_pair -__PACKAGE__->AddRight( Admin => ModifyACL => 'Create, modify and delete Access Control List entries' ); # loc_pair -__PACKAGE__->AddRight( Admin => ModifyQueueWatchers => 'Modify queue watchers' ); # loc_pair -__PACKAGE__->AddRight( General => SeeCustomField => 'View custom field values' ); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Modify custom field values' ); # loc_pair -__PACKAGE__->AddRight( Admin => AssignCustomFields => 'Assign and remove queue custom fields' ); # loc_pair -__PACKAGE__->AddRight( Admin => ModifyTemplate => 'Modify Scrip templates' ); # loc_pair -__PACKAGE__->AddRight( Admin => ShowTemplate => 'View Scrip templates' ); # loc_pair - -__PACKAGE__->AddRight( Admin => ModifyScrips => 'Modify Scrips' ); # loc_pair -__PACKAGE__->AddRight( Admin => ShowScrips => 'View Scrips' ); # loc_pair - -__PACKAGE__->AddRight( General => ShowTicket => 'View ticket summaries' ); # loc_pair -__PACKAGE__->AddRight( Staff => ShowTicketComments => 'View ticket private commentary' ); # loc_pair -__PACKAGE__->AddRight( Staff => ShowOutgoingEmail => 'View exact outgoing email messages and their recipients' ); # loc_pair - -__PACKAGE__->AddRight( General => Watch => 'Sign up as a ticket Requestor or ticket or queue Cc' ); # loc_pair -__PACKAGE__->AddRight( Staff => WatchAsAdminCc => 'Sign up as a ticket or queue AdminCc' ); # loc_pair -__PACKAGE__->AddRight( General => CreateTicket => 'Create tickets' ); # loc_pair -__PACKAGE__->AddRight( General => ReplyToTicket => 'Reply to tickets' ); # loc_pair -__PACKAGE__->AddRight( General => CommentOnTicket => 'Comment on tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => OwnTicket => 'Own tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => ModifyTicket => 'Modify tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => DeleteTicket => 'Delete tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => TakeTicket => 'Take tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => StealTicket => 'Steal tickets' ); # loc_pair -__PACKAGE__->AddRight( Staff => ReassignTicket => 'Modify ticket owner on owned tickets' ); # loc_pair - -__PACKAGE__->AddRight( Staff => ForwardMessage => 'Forward messages outside of RT' ); # loc_pair +__PACKAGE__->AddRight( General => SeeQueue => 'View queue' ); # loc +__PACKAGE__->AddRight( Admin => AdminQueue => 'Create, modify and delete queue' ); # loc +__PACKAGE__->AddRight( Admin => ShowACL => 'Display Access Control List' ); # loc +__PACKAGE__->AddRight( Admin => ModifyACL => 'Create, modify and delete Access Control List entries' ); # loc +__PACKAGE__->AddRight( Admin => ModifyQueueWatchers => 'Modify queue watchers' ); # loc +__PACKAGE__->AddRight( General => SeeCustomField => 'View custom field values' ); # loc +__PACKAGE__->AddRight( Staff => ModifyCustomField => 'Modify custom field values' ); # loc +__PACKAGE__->AddRight( Admin => AssignCustomFields => 'Assign and remove queue custom fields' ); # loc +__PACKAGE__->AddRight( Admin => ModifyTemplate => 'Modify Scrip templates' ); # loc +__PACKAGE__->AddRight( Admin => ShowTemplate => 'View Scrip templates' ); # loc + +__PACKAGE__->AddRight( Admin => ModifyScrips => 'Modify Scrips' ); # loc +__PACKAGE__->AddRight( Admin => ShowScrips => 'View Scrips' ); # loc + +__PACKAGE__->AddRight( General => ShowTicket => 'View ticket summaries' ); # loc +__PACKAGE__->AddRight( Staff => ShowTicketComments => 'View ticket private commentary' ); # loc +__PACKAGE__->AddRight( Staff => ShowOutgoingEmail => 'View exact outgoing email messages and their recipients' ); # loc + +__PACKAGE__->AddRight( General => Watch => 'Sign up as a ticket Requestor or ticket or queue Cc' ); # loc +__PACKAGE__->AddRight( Staff => WatchAsAdminCc => 'Sign up as a ticket or queue AdminCc' ); # loc +__PACKAGE__->AddRight( General => CreateTicket => 'Create tickets' ); # loc +__PACKAGE__->AddRight( General => ReplyToTicket => 'Reply to tickets' ); # loc +__PACKAGE__->AddRight( General => CommentOnTicket => 'Comment on tickets' ); # loc +__PACKAGE__->AddRight( Staff => OwnTicket => 'Own tickets' ); # loc +__PACKAGE__->AddRight( Staff => ModifyTicket => 'Modify tickets' ); # loc +__PACKAGE__->AddRight( Staff => DeleteTicket => 'Delete tickets' ); # loc +__PACKAGE__->AddRight( Staff => TakeTicket => 'Take tickets' ); # loc +__PACKAGE__->AddRight( Staff => StealTicket => 'Steal tickets' ); # loc +__PACKAGE__->AddRight( Staff => ReassignTicket => 'Modify ticket owner on owned tickets' ); # loc + +__PACKAGE__->AddRight( Staff => ForwardMessage => 'Forward messages outside of RT' ); # loc =head2 Create(ARGS) @@ -1096,7 +1096,7 @@ sub FindDependencies { # Queue role groups( Cc, AdminCc ) my $objs = RT::Groups->new( $self->CurrentUser ); - $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' ); + $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 ); $objs->Limit( FIELD => 'Instance', VALUE => $self->Id ); $deps->Add( in => $objs ); @@ -1135,7 +1135,7 @@ sub FindDependencies { # Tickets $objs = RT::Tickets->new( $self->CurrentUser ); - $objs->_SQLLimit( FIELD => "Queue", VALUE => $self->Id ); + $objs->Limit( FIELD => "Queue", VALUE => $self->Id ); $objs->{allow_deleted_search} = 1; $deps->Add( in => $objs ); } diff --git a/lib/RT/Queues.pm b/lib/RT/Queues.pm index c143e20..add6f61 100644 --- a/lib/RT/Queues.pm +++ b/lib/RT/Queues.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm index d113c57..84410db 100644 --- a/lib/RT/Record.pm +++ b/lib/RT/Record.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -745,9 +745,20 @@ sub _Accessible { } -=head2 _EncodeLOB BODY MIME_TYPE +=head2 _EncodeLOB BODY MIME_TYPE FILENAME -Takes a potentially large attachment. Returns (ContentEncoding, EncodedBody) based on system configuration and selected database +Takes a potentially large attachment. Returns (ContentEncoding, +EncodedBody, MimeType, Filename) based on system configuration and +selected database. Returns a custom (short) text/plain message if +DropLongAttachments causes an attachment to not be stored. + +Encodes your data as base64 or Quoted-Printable as needed based on your +Databases's restrictions and the UTF-8ness of the data being passed in. Since +we are storing in columns marked UTF8, we must ensure that binary data is +encoded on databases which are strict. + +This function expects to receive an octet string in order to properly +evaluate and encode it. It will return an octet string. =cut @@ -775,7 +786,7 @@ sub _EncodeLOB { $MaxSize = $MaxSize * 3 / 4; # Some databases (postgres) can't handle non-utf8 data } elsif ( !$RT::Handle->BinarySafeBLOBs - && $MIMEType !~ /text\/plain/gi + && $Body =~ /\P{ASCII}/ && !Encode::is_utf8( $Body, 1 ) ) { $ContentEncoding = 'quoted-printable'; } @@ -820,6 +831,27 @@ sub _EncodeLOB { } +=head2 _DecodeLOB + +Unpacks data stored in the database, which may be base64 or QP encoded +because of our need to store binary and badly encoded data in columns +marked as UTF-8. Databases such as PostgreSQL and Oracle care that you +are feeding them invalid UTF-8 and will refuse the content. This +function handles unpacking the encoded data. + +It returns textual data as a UTF-8 string which has been processed by Encode's +PERLQQ filter which will replace the invalid bytes with \x{HH} so you can see +the invalid byte but won't run into problems treating the data as UTF-8 later. + +This is similar to how we filter all data coming in via the web UI in +RT::Interface::Web::DecodeARGS. This filter should only end up being +applied to old data from less UTF-8-safe versions of RT. + +Important Note - This function expects an octet string and returns a +character string for non-binary data. + +=cut + sub _DecodeLOB { my $self = shift; my $ContentType = shift || ''; @@ -836,7 +868,7 @@ sub _DecodeLOB { return ( $self->loc( "Unknown ContentEncoding [_1]", $ContentEncoding ) ); } if ( RT::I18N::IsTextualContentType($ContentType) ) { - $Content = Encode::decode_utf8($Content) unless Encode::is_utf8($Content); + $Content = Encode::decode('UTF-8',$Content,Encode::FB_PERLQQ) unless Encode::is_utf8($Content); } return ($Content); } diff --git a/lib/RT/Record/AddAndSort.pm b/lib/RT/Record/AddAndSort.pm index 2feb3eb..bb88459 100644 --- a/lib/RT/Record/AddAndSort.pm +++ b/lib/RT/Record/AddAndSort.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role.pm b/lib/RT/Record/Role.pm index bd66c03..8fa8fce 100644 --- a/lib/RT/Record/Role.pm +++ b/lib/RT/Record/Role.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role/Lifecycle.pm b/lib/RT/Record/Role/Lifecycle.pm index b2b4aa2..a5e0db8 100644 --- a/lib/RT/Record/Role/Lifecycle.pm +++ b/lib/RT/Record/Role/Lifecycle.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role/Links.pm b/lib/RT/Record/Role/Links.pm index 977db70..971dcb2 100644 --- a/lib/RT/Record/Role/Links.pm +++ b/lib/RT/Record/Role/Links.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role/Rights.pm b/lib/RT/Record/Role/Rights.pm index 5870eae..0f494df 100644 --- a/lib/RT/Record/Role/Rights.pm +++ b/lib/RT/Record/Role/Rights.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role/Roles.pm b/lib/RT/Record/Role/Roles.pm index 21fb076..aad2673 100644 --- a/lib/RT/Record/Role/Roles.pm +++ b/lib/RT/Record/Role/Roles.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Record/Role/Status.pm b/lib/RT/Record/Role/Status.pm index f0c99cc..dcea127 100644 --- a/lib/RT/Record/Role/Status.pm +++ b/lib/RT/Record/Role/Status.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Reminders.pm b/lib/RT/Reminders.pm index dc18e03..9243fa3 100644 --- a/lib/RT/Reminders.pm +++ b/lib/RT/Reminders.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Report/Tickets.pm b/lib/RT/Report/Tickets.pm index 9adf7f1..3561434 100644 --- a/lib/RT/Report/Tickets.pm +++ b/lib/RT/Report/Tickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -183,7 +183,7 @@ our %GROUPINGS_META = ( $cf = $obj->Name; } - return 'Custom field [_1]', $self->CurrentUser->loc( $cf ); + return 'Custom field [_1]', $cf; }, }, Enum => { @@ -191,8 +191,8 @@ our %GROUPINGS_META = ( }, ); -# loc'able strings below generated with: -# perl -MRT=-init -MRT::Report::Tickets -E 'say qq{\# loc("$_->[0]")} while $_ = splice @RT::Report::Tickets::STATISTICS, 0, 2' +# loc'able strings below generated with (s/loq/loc/): +# perl -MRT=-init -MRT::Report::Tickets -E 'say qq{\# loq("$_->[0]")} while $_ = splice @RT::Report::Tickets::STATISTICS, 0, 2' # # loc("Ticket count") # loc("Summary of time worked") diff --git a/lib/RT/Report/Tickets/Entry.pm b/lib/RT/Report/Tickets/Entry.pm index a584efd..5f90e31 100644 --- a/lib/RT/Report/Tickets/Entry.pm +++ b/lib/RT/Report/Tickets/Entry.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Rule.pm b/lib/RT/Rule.pm index f498070..e3ab599 100644 --- a/lib/RT/Rule.pm +++ b/lib/RT/Rule.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Ruleset.pm b/lib/RT/Ruleset.pm index 26227b7..e6267da 100644 --- a/lib/RT/Ruleset.pm +++ b/lib/RT/Ruleset.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SQL.pm b/lib/RT/SQL.pm index 1a469d6..0e7ff10 100644 --- a/lib/RT/SQL.pm +++ b/lib/RT/SQL.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SavedSearch.pm b/lib/RT/SavedSearch.pm index 7c4df8b..3e0e928 100644 --- a/lib/RT/SavedSearch.pm +++ b/lib/RT/SavedSearch.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SavedSearches.pm b/lib/RT/SavedSearches.pm index e917892..0b56d7c 100644 --- a/lib/RT/SavedSearches.pm +++ b/lib/RT/SavedSearches.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm index 0e1c76b..14df0c9 100644 --- a/lib/RT/Scrip.pm +++ b/lib/RT/Scrip.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm index 901266c..feb1b2c 100644 --- a/lib/RT/ScripAction.pm +++ b/lib/RT/ScripAction.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -193,8 +193,8 @@ sub TemplateObj { Remove => "4.4", ); - return undef unless $self->{Template}; if ( !$self->{'TemplateObj'} ) { + return undef unless $self->{Template}; $self->{'TemplateObj'} = RT::Template->new( $self->CurrentUser ); $self->{'TemplateObj'}->Load( $self->{'Template'} ); diff --git a/lib/RT/ScripActions.pm b/lib/RT/ScripActions.pm index c1fcd6f..6c8a0e2 100644 --- a/lib/RT/ScripActions.pm +++ b/lib/RT/ScripActions.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ScripCondition.pm b/lib/RT/ScripCondition.pm index e3cd20a..8a59c1f 100644 --- a/lib/RT/ScripCondition.pm +++ b/lib/RT/ScripCondition.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/ScripConditions.pm b/lib/RT/ScripConditions.pm index 7452822..31cc0fd 100644 --- a/lib/RT/ScripConditions.pm +++ b/lib/RT/ScripConditions.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Scrips.pm b/lib/RT/Scrips.pm index 9faf525..5fe6dd3 100644 --- a/lib/RT/Scrips.pm +++ b/lib/RT/Scrips.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Search.pm b/lib/RT/Search.pm index 7ec50de..8e13987 100644 --- a/lib/RT/Search.pm +++ b/lib/RT/Search.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Search/ActiveTicketsInQueue.pm b/lib/RT/Search/ActiveTicketsInQueue.pm index 9e3e88a..c7ae497 100644 --- a/lib/RT/Search/ActiveTicketsInQueue.pm +++ b/lib/RT/Search/ActiveTicketsInQueue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Search/FromSQL.pm b/lib/RT/Search/FromSQL.pm index 4cb17f5..2f27fee 100644 --- a/lib/RT/Search/FromSQL.pm +++ b/lib/RT/Search/FromSQL.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Search/Simple.pm b/lib/RT/Search/Simple.pm index f368e5a..ba1bfdc 100644 --- a/lib/RT/Search/Simple.pm +++ b/lib/RT/Search/Simple.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm index aae88b1..aaff9f1 100644 --- a/lib/RT/SearchBuilder.pm +++ b/lib/RT/SearchBuilder.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SearchBuilder/AddAndSort.pm b/lib/RT/SearchBuilder/AddAndSort.pm index 76e79bf..9eae80d 100644 --- a/lib/RT/SearchBuilder/AddAndSort.pm +++ b/lib/RT/SearchBuilder/AddAndSort.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SearchBuilder/Role.pm b/lib/RT/SearchBuilder/Role.pm index 35a74e0..2c1cb13 100644 --- a/lib/RT/SearchBuilder/Role.pm +++ b/lib/RT/SearchBuilder/Role.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm index eeabbfc..c8028f0 100644 --- a/lib/RT/SearchBuilder/Role/Roles.pm +++ b/lib/RT/SearchBuilder/Role/Roles.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SharedSetting.pm b/lib/RT/SharedSetting.pm index 95d7095..2eece3c 100644 --- a/lib/RT/SharedSetting.pm +++ b/lib/RT/SharedSetting.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/SharedSettings.pm b/lib/RT/SharedSettings.pm index 487ff72..94fa4ca 100644 --- a/lib/RT/SharedSettings.pm +++ b/lib/RT/SharedSettings.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder.pm b/lib/RT/Shredder.pm index b1450e5..fa47b3a 100644 --- a/lib/RT/Shredder.pm +++ b/lib/RT/Shredder.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -164,6 +164,21 @@ your F: Be sure to specify an absolute path. +=head1 Database Indexes + +We have found that the following indexes significantly speed up +shredding on most databases. + + CREATE INDEX SHREDDER_CGM1 ON CachedGroupMembers(MemberId, GroupId, Disabled); + CREATE INDEX SHREDDER_CGM2 ON CachedGroupMembers(ImmediateParentId,MemberId); + CREATE INDEX SHREDDER_CGM3 on CachedGroupMembers (Via, Id); + + CREATE UNIQUE INDEX SHREDDER_GM1 ON GroupMembers(MemberId, GroupId); + + CREATE INDEX SHREDDER_TXN1 ON Transactions(ReferenceType, OldReference); + CREATE INDEX SHREDDER_TXN2 ON Transactions(ReferenceType, NewReference); + CREATE INDEX SHREDDER_TXN3 ON Transactions(Type, OldValue); + CREATE INDEX SHREDDER_TXN4 ON Transactions(Type, NewValue) =head1 INFORMATION FOR DEVELOPERS diff --git a/lib/RT/Shredder/ACE.pm b/lib/RT/Shredder/ACE.pm index 6d348bb..737dacf 100644 --- a/lib/RT/Shredder/ACE.pm +++ b/lib/RT/Shredder/ACE.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Attachment.pm b/lib/RT/Shredder/Attachment.pm index c8cd6a4..ffd4165 100644 --- a/lib/RT/Shredder/Attachment.pm +++ b/lib/RT/Shredder/Attachment.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/CachedGroupMember.pm b/lib/RT/Shredder/CachedGroupMember.pm index 192c61d..7ad2869 100644 --- a/lib/RT/Shredder/CachedGroupMember.pm +++ b/lib/RT/Shredder/CachedGroupMember.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Constants.pm b/lib/RT/Shredder/Constants.pm index 518dec1..dcb0003 100644 --- a/lib/RT/Shredder/Constants.pm +++ b/lib/RT/Shredder/Constants.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/CustomField.pm b/lib/RT/Shredder/CustomField.pm index e8f6270..125d103 100644 --- a/lib/RT/Shredder/CustomField.pm +++ b/lib/RT/Shredder/CustomField.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/CustomFieldValue.pm b/lib/RT/Shredder/CustomFieldValue.pm index 41ad878..08e19ae 100644 --- a/lib/RT/Shredder/CustomFieldValue.pm +++ b/lib/RT/Shredder/CustomFieldValue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Dependencies.pm b/lib/RT/Shredder/Dependencies.pm index 9364887..fdfcb8b 100644 --- a/lib/RT/Shredder/Dependencies.pm +++ b/lib/RT/Shredder/Dependencies.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Dependency.pm b/lib/RT/Shredder/Dependency.pm index e2666e8..00dea55 100644 --- a/lib/RT/Shredder/Dependency.pm +++ b/lib/RT/Shredder/Dependency.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Exceptions.pm b/lib/RT/Shredder/Exceptions.pm index 8c1d6ed..6cfc555 100644 --- a/lib/RT/Shredder/Exceptions.pm +++ b/lib/RT/Shredder/Exceptions.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -67,27 +67,27 @@ use base qw(RT::Shredder::Exception); my %DESCRIPTION = ( DependenciesLimit => < < < < # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/GroupMember.pm b/lib/RT/Shredder/GroupMember.pm index ab34537..b9a7e08 100644 --- a/lib/RT/Shredder/GroupMember.pm +++ b/lib/RT/Shredder/GroupMember.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Link.pm b/lib/RT/Shredder/Link.pm index e512ee1..a561db9 100644 --- a/lib/RT/Shredder/Link.pm +++ b/lib/RT/Shredder/Link.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/ObjectCustomFieldValue.pm b/lib/RT/Shredder/ObjectCustomFieldValue.pm index ad34f2c..440645e 100644 --- a/lib/RT/Shredder/ObjectCustomFieldValue.pm +++ b/lib/RT/Shredder/ObjectCustomFieldValue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/POD.pm b/lib/RT/Shredder/POD.pm index 6cc8695..ee4fb09 100644 --- a/lib/RT/Shredder/POD.pm +++ b/lib/RT/Shredder/POD.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin.pm b/lib/RT/Shredder/Plugin.pm index e247889..896b5d8 100644 --- a/lib/RT/Shredder/Plugin.pm +++ b/lib/RT/Shredder/Plugin.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Attachments.pm b/lib/RT/Shredder/Plugin/Attachments.pm index f0f64a1..05f264e 100644 --- a/lib/RT/Shredder/Plugin/Attachments.pm +++ b/lib/RT/Shredder/Plugin/Attachments.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Base.pm b/lib/RT/Shredder/Plugin/Base.pm index 0adadfd..7ada97e 100644 --- a/lib/RT/Shredder/Plugin/Base.pm +++ b/lib/RT/Shredder/Plugin/Base.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Base/Dump.pm b/lib/RT/Shredder/Plugin/Base/Dump.pm index 903a962..945bd93 100644 --- a/lib/RT/Shredder/Plugin/Base/Dump.pm +++ b/lib/RT/Shredder/Plugin/Base/Dump.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Base/Search.pm b/lib/RT/Shredder/Plugin/Base/Search.pm index a493cd8..bb21bd6 100644 --- a/lib/RT/Shredder/Plugin/Base/Search.pm +++ b/lib/RT/Shredder/Plugin/Base/Search.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Objects.pm b/lib/RT/Shredder/Plugin/Objects.pm index 2090574..ebfe2a0 100644 --- a/lib/RT/Shredder/Plugin/Objects.pm +++ b/lib/RT/Shredder/Plugin/Objects.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/SQLDump.pm b/lib/RT/Shredder/Plugin/SQLDump.pm index 2e7c259..cc0d4cc 100644 --- a/lib/RT/Shredder/Plugin/SQLDump.pm +++ b/lib/RT/Shredder/Plugin/SQLDump.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Summary.pm b/lib/RT/Shredder/Plugin/Summary.pm index 40d5245..a81b1f0 100644 --- a/lib/RT/Shredder/Plugin/Summary.pm +++ b/lib/RT/Shredder/Plugin/Summary.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Tickets.pm b/lib/RT/Shredder/Plugin/Tickets.pm index 0344487..180c45c 100644 --- a/lib/RT/Shredder/Plugin/Tickets.pm +++ b/lib/RT/Shredder/Plugin/Tickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Plugin/Users.pm b/lib/RT/Shredder/Plugin/Users.pm index b45c685..74ac950 100644 --- a/lib/RT/Shredder/Plugin/Users.pm +++ b/lib/RT/Shredder/Plugin/Users.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Principal.pm b/lib/RT/Shredder/Principal.pm index 65d2ce7..e51f223 100644 --- a/lib/RT/Shredder/Principal.pm +++ b/lib/RT/Shredder/Principal.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Queue.pm b/lib/RT/Shredder/Queue.pm index 46fea2f..d95c213 100644 --- a/lib/RT/Shredder/Queue.pm +++ b/lib/RT/Shredder/Queue.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Record.pm b/lib/RT/Shredder/Record.pm index 726ab28..ebfa7c2 100644 --- a/lib/RT/Shredder/Record.pm +++ b/lib/RT/Shredder/Record.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Scrip.pm b/lib/RT/Shredder/Scrip.pm index a75ff76..c4953c6 100644 --- a/lib/RT/Shredder/Scrip.pm +++ b/lib/RT/Shredder/Scrip.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/ScripAction.pm b/lib/RT/Shredder/ScripAction.pm index d9a047f..1bb94b8 100644 --- a/lib/RT/Shredder/ScripAction.pm +++ b/lib/RT/Shredder/ScripAction.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/ScripCondition.pm b/lib/RT/Shredder/ScripCondition.pm index b5e576b..cec8bec 100644 --- a/lib/RT/Shredder/ScripCondition.pm +++ b/lib/RT/Shredder/ScripCondition.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Template.pm b/lib/RT/Shredder/Template.pm index 5c0d09f..b606a64 100644 --- a/lib/RT/Shredder/Template.pm +++ b/lib/RT/Shredder/Template.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Ticket.pm b/lib/RT/Shredder/Ticket.pm index 7c8da55..b1b39a2 100644 --- a/lib/RT/Shredder/Ticket.pm +++ b/lib/RT/Shredder/Ticket.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/Transaction.pm b/lib/RT/Shredder/Transaction.pm index 3b5670b..b4f00ba 100644 --- a/lib/RT/Shredder/Transaction.pm +++ b/lib/RT/Shredder/Transaction.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Shredder/User.pm b/lib/RT/Shredder/User.pm index 1bf1a69..41f3d02 100644 --- a/lib/RT/Shredder/User.pm +++ b/lib/RT/Shredder/User.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Squish.pm b/lib/RT/Squish.pm index e64b711..e0e6106 100644 --- a/lib/RT/Squish.pm +++ b/lib/RT/Squish.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Squish/CSS.pm b/lib/RT/Squish/CSS.pm index 35aebcc..5837379 100644 --- a/lib/RT/Squish/CSS.pm +++ b/lib/RT/Squish/CSS.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Squish/JS.pm b/lib/RT/Squish/JS.pm index 5d97d28..0c3bd3d 100644 --- a/lib/RT/Squish/JS.pm +++ b/lib/RT/Squish/JS.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/System.pm b/lib/RT/System.pm index 3a02037..43c021a 100644 --- a/lib/RT/System.pm +++ b/lib/RT/System.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -80,17 +80,17 @@ use RT::ACL; use RT::ACE; use Data::GUID; -__PACKAGE__->AddRight( Admin => SuperUser => 'Do anything and everything'); # loc_pair -__PACKAGE__->AddRight( Staff => ShowUserHistory => 'Show history of public user properties'); # loc_pair -__PACKAGE__->AddRight( Admin => AdminUsers => 'Create, modify and delete users'); # loc_pair -__PACKAGE__->AddRight( Staff => ModifySelf => "Modify one's own RT account"); # loc_pair -__PACKAGE__->AddRight( Staff => ShowArticlesMenu => 'Show Articles menu'); # loc_pair -__PACKAGE__->AddRight( Admin => ShowConfigTab => 'Show Admin menu'); # loc_pair -__PACKAGE__->AddRight( Admin => ShowApprovalsTab => 'Show Approvals tab'); # loc_pair -__PACKAGE__->AddRight( Staff => ShowGlobalTemplates => 'Show global templates'); # loc_pair -__PACKAGE__->AddRight( General => LoadSavedSearch => 'Allow loading of saved searches'); # loc_pair -__PACKAGE__->AddRight( General => CreateSavedSearch => 'Allow creation of saved searches'); # loc_pair -__PACKAGE__->AddRight( Admin => ExecuteCode => 'Allow writing Perl code in templates, scrips, etc'); # loc_pair +__PACKAGE__->AddRight( Admin => SuperUser => 'Do anything and everything'); # loc +__PACKAGE__->AddRight( Staff => ShowUserHistory => 'Show history of public user properties'); # loc +__PACKAGE__->AddRight( Admin => AdminUsers => 'Create, modify and delete users'); # loc +__PACKAGE__->AddRight( Staff => ModifySelf => "Modify one's own RT account"); # loc +__PACKAGE__->AddRight( Staff => ShowArticlesMenu => 'Show Articles menu'); # loc +__PACKAGE__->AddRight( Admin => ShowConfigTab => 'Show Admin menu'); # loc +__PACKAGE__->AddRight( Admin => ShowApprovalsTab => 'Show Approvals tab'); # loc +__PACKAGE__->AddRight( Staff => ShowGlobalTemplates => 'Show global templates'); # loc +__PACKAGE__->AddRight( General => LoadSavedSearch => 'Allow loading of saved searches'); # loc +__PACKAGE__->AddRight( General => CreateSavedSearch => 'Allow creation of saved searches'); # loc +__PACKAGE__->AddRight( Admin => ExecuteCode => 'Allow writing Perl code in templates, scrips, etc'); # loc =head2 AvailableRights diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm index 9b9ca3f..39e42a4 100644 --- a/lib/RT/Template.pm +++ b/lib/RT/Template.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -288,7 +288,7 @@ sub Create { if $tmp->id; } - my $result = $self->SUPER::Create( + my ( $result, $msg ) = $self->SUPER::Create( Content => $args{'Content'}, Queue => $args{'Queue'}, Description => $args{'Description'}, @@ -296,7 +296,11 @@ sub Create { Type => $args{'Type'}, ); - return ($result); + if ( wantarray ) { + return ( $result, $msg ); + } else { + return ( $result ); + } } @@ -656,14 +660,17 @@ sub _DowngradeFromHTML { $orig_entity->head->mime_attr( "Content-Type" => 'text/html' ); $orig_entity->head->mime_attr( "Content-Type.charset" => 'utf-8' ); - $orig_entity->make_multipart('alternative', Force => 1); require Encode; - $new_entity->bodyhandle(MIME::Body::InCore->new( - # need to decode_utf8, see the doc of MIMEObj method - \(RT::Interface::Email::ConvertHTMLToText(Encode::decode_utf8($new_entity->bodyhandle->as_string))) - )); + my $body = $new_entity->bodyhandle->as_string; + # need to decode_utf8, see the doc of MIMEObj method + $body = Encode::decode_utf8( $body ); + my $html = RT::Interface::Email::ConvertHTMLToText( $body ); + return unless defined $html; + $new_entity->bodyhandle(MIME::Body::InCore->new( \$html )); + + $orig_entity->make_multipart('alternative', Force => 1); $orig_entity->add_part($new_entity, 0); # plain comes before html $self->{MIMEObj} = $orig_entity; diff --git a/lib/RT/Templates.pm b/lib/RT/Templates.pm index 551d3ea..c53f2dd 100644 --- a/lib/RT/Templates.pm +++ b/lib/RT/Templates.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm index ae1bbb4..0ef4942 100644 --- a/lib/RT/Test.pm +++ b/lib/RT/Test.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -140,6 +140,8 @@ sub import { if $args{'requires'}; push @{ $args{'plugins'} ||= [] }, $args{'testing'} if $args{'testing'}; + push @{ $args{'plugins'} ||= [] }, split " ", $ENV{RT_TEST_PLUGINS} + if $ENV{RT_TEST_PLUGINS}; $class->bootstrap_tempdir; @@ -516,7 +518,7 @@ sub bootstrap_plugins_paths { if ( grep $name eq $_, @plugins ) { my $variants = join "(?:|::|-|_)", map "\Q$_\E", split /::/, $name; - my ($path) = map $ENV{$_}, grep /^CHIMPS_(?:$variants).*_ROOT$/i, keys %ENV; + my ($path) = map $ENV{$_}, grep /^RT_TEST_PLUGIN_(?:$variants).*_ROOT$/i, keys %ENV; return $path if $path; } return $old_func->(@_); @@ -1610,9 +1612,7 @@ sub stop_server { my $in_end = shift; return unless @SERVERS; - my $sig = 'TERM'; - $sig = 'INT' if $ENV{'RT_TEST_WEB_HANDLER'} eq "plack"; - kill $sig, @SERVERS; + kill 'TERM', @SERVERS; foreach my $pid (@SERVERS) { if ($ENV{RT_TEST_WEB_HANDLER} =~ /^apache/) { sleep 1 while kill 0, $pid; diff --git a/lib/RT/Test/Apache.pm b/lib/RT/Test/Apache.pm index 11fea77..1e2fb04 100644 --- a/lib/RT/Test/Apache.pm +++ b/lib/RT/Test/Apache.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test/Email.pm b/lib/RT/Test/Email.pm index 8cf6839..54aa87d 100644 --- a/lib/RT/Test/Email.pm +++ b/lib/RT/Test/Email.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test/GnuPG.pm b/lib/RT/Test/GnuPG.pm index a63d1e3..9782822 100644 --- a/lib/RT/Test/GnuPG.pm +++ b/lib/RT/Test/GnuPG.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test/SMIME.pm b/lib/RT/Test/SMIME.pm index 3fe0aff..acdba90 100644 --- a/lib/RT/Test/SMIME.pm +++ b/lib/RT/Test/SMIME.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test/Shredder.pm b/lib/RT/Test/Shredder.pm index 13c56d9..480dfc9 100644 --- a/lib/RT/Test/Shredder.pm +++ b/lib/RT/Test/Shredder.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Test/Web.pm b/lib/RT/Test/Web.pm index 83fd339..872cd29 100644 --- a/lib/RT/Test/Web.pm +++ b/lib/RT/Test/Web.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm index 80af7f5..961e4d0 100644 --- a/lib/RT/Ticket.pm +++ b/lib/RT/Ticket.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -2064,6 +2064,9 @@ are owned by Nobody because that is the context appropriate for the TakeTicket right. If you need to strictly test a user for a right, use HasRight to check for the right directly. +For some custom types of owner changes (C and C), it also +verifies that those actions are possible given the current ticket owner. + =head3 Rights to Set Owner The current user can set or change the Owner field in the following @@ -2119,11 +2122,22 @@ in the GUI. This method accepts the following parameters as a paramshash: -NewOwnerObj: Optional. A user object representing the proposed -new owner of the ticket. +=over + +=item C + +Optional; an L object representing the proposed new owner of +the ticket. + +=item C + +Optional; the type of set owner operation. Valid values are C, +C, or C. Note that if the type is C, this method +will return false if the current user is already the owner; similarly, +it will return false for C if the ticket has no owner or the +owner is the current user. -Type: Optional. The type of set owner operation. Valid values are Take, -Steal, or Force. +=back As noted above, there are exceptions to the standard ticket-based rights described here. The Force option allows for these and is used @@ -2145,8 +2159,10 @@ sub CurrentUserCanSetOwner { return ($ok, $message) if not $ok; } - # ReassignTicket unconditionally allows you to SetOwner - return (1, undef) if $self->CurrentUserHasRight('ReassignTicket'); + # ReassignTicket allows you to SetOwner, but we also need to check ticket's + # current owner for Take and Steal Types + return ( 1, undef ) if $self->CurrentUserHasRight('ReassignTicket') + && $args{Type} ne 'Take' && $args{Type} ne 'Steal'; # Ticket is unowned # Can set owner to yourself withn ModifyTicket or TakeTicket @@ -2159,6 +2175,7 @@ sub CurrentUserCanSetOwner { } unless ( ( $self->CurrentUserHasRight('ModifyTicket') + or $self->CurrentUserHasRight('ReassignTicket') or $self->CurrentUserHasRight('TakeTicket') ) and $self->CurrentUserHasRight('OwnTicket') ) { return ( 0, $self->loc("Permission Denied") ); @@ -2172,6 +2189,7 @@ sub CurrentUserCanSetOwner { && $OldOwnerObj->Id != $self->CurrentUser->id ) { unless ( $self->CurrentUserHasRight('ModifyTicket') + || $self->CurrentUserHasRight('ReassignTicket') || $self->CurrentUserHasRight('StealTicket') ) { return ( 0, $self->loc("Permission Denied") ) } @@ -2187,7 +2205,8 @@ sub CurrentUserCanSetOwner { and $args{'NewOwnerObj'}->id == $self->CurrentUser->id )) { return ( 0, $self->loc("You can only take tickets that are unowned") ); } - else { + + unless ( $self->CurrentUserHasRight('ReassignTicket') ) { return ( 0, $self->loc( "You can only reassign tickets that you own or that are unowned")); } @@ -2195,7 +2214,12 @@ sub CurrentUserCanSetOwner { # You own the ticket # Untake falls through to here, so we don't need to explicitly handle that Type else { - unless ( $self->CurrentUserHasRight('ModifyTicket') ) { + if ( $args{'Type'} eq 'Take' || $args{'Type'} eq 'Steal' ) { + return ( 0, $self->loc("You already own this ticket") ); + } + + unless ( $self->CurrentUserHasRight('ModifyTicket') + || $self->CurrentUserHasRight('ReassignTicket') ) { return ( 0, $self->loc("Permission Denied") ); } } @@ -3563,7 +3587,7 @@ sub FindDependencies { # Ticket role groups( Owner, Requestors, Cc, AdminCc ) $objs = RT::Groups->new( $self->CurrentUser ); - $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role' ); + $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role', CASESENSITIVE => 0 ); $objs->Limit( FIELD => 'Instance', VALUE => $self->Id ); $deps->Add( in => $objs ); diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm index 6400267..140e09d 100644 --- a/lib/RT/Tickets.pm +++ b/lib/RT/Tickets.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -155,6 +155,7 @@ our %FIELD_METADATA = ( TransactionCF => [ 'CUSTOMFIELD' => 'Transaction' ], #loc_left_pair QueueCF => [ 'CUSTOMFIELD' => 'Queue' ], #loc_left_pair Updated => [ 'TRANSDATE', ], #loc_left_pair + UpdatedBy => [ 'TRANSCREATOR', ], #loc_left_pair OwnerGroup => [ 'MEMBERSHIPFIELD' => 'Owner', ], #loc_left_pair RequestorGroup => [ 'MEMBERSHIPFIELD' => 'Requestor', ], #loc_left_pair CCGroup => [ 'MEMBERSHIPFIELD' => 'Cc', ], #loc_left_pair @@ -185,6 +186,7 @@ our %dispatch = ( TRANSFIELD => \&_TransLimit, TRANSCONTENT => \&_TransContentLimit, TRANSDATE => \&_TransDateLimit, + TRANSCREATOR => \&_TransCreatorLimit, WATCHERFIELD => \&_WatcherLimit, MEMBERSHIPFIELD => \&_WatcherMembershipLimit, CUSTOMFIELD => \&_CustomFieldLimit, @@ -200,6 +202,8 @@ my %DefaultEA = ( '!=' => 'AND' }, DATE => { + 'IS' => 'OR', + 'IS NOT' => 'OR', '=' => 'OR', '>=' => 'AND', '<=' => 'AND', @@ -444,10 +448,6 @@ sub _LinkLimit { my $is_null = 0; $is_null = 1 if !$value || $value =~ /^null$/io; - unless ($is_null) { - $value = RT::URI->new( $sb->CurrentUser )->CanonicalizeURI( $value ); - } - my $direction = $meta->[1] || ''; my ($matchfield, $linkfield) = ('', ''); if ( $direction eq 'To' ) { @@ -474,6 +474,7 @@ sub _LinkLimit { $op = ($op =~ /^(=|IS)$/i)? 'IS': 'IS NOT'; } elsif ( $value =~ /\D/ ) { + $value = RT::URI->new( $sb->CurrentUser )->CanonicalizeURI( $value ); $is_local = 0; } $matchfield = "Local$matchfield" if $is_local; @@ -551,12 +552,22 @@ sub _DateLimit { my ( $sb, $field, $op, $value, %rest ) = @_; die "Invalid Date Op: $op" - unless $op =~ /^(=|>|<|>=|<=)$/; + unless $op =~ /^(=|>|<|>=|<=|IS(\s+NOT)?)$/i; my $meta = $FIELD_METADATA{$field}; die "Incorrect Meta Data for $field" unless ( defined $meta->[1] ); + if ( $op =~ /^(IS(\s+NOT)?)$/i) { + return $sb->Limit( + FUNCTION => $sb->NotSetDateToNullFunction, + FIELD => $meta->[1], + OPERATOR => $op, + VALUE => "NULL", + %rest, + ); + } + if ( my $subkey = $rest{SUBKEY} ) { if ( $subkey eq 'DayOfWeek' && $op !~ /IS/i && $value =~ /[^0-9]/ ) { for ( my $i = 0; $i < @RT::Date::DAYS_OF_WEEK; $i++ ) { @@ -764,6 +775,21 @@ sub _TransDateLimit { $sb->_CloseParen; } +sub _TransCreatorLimit { + my ( $sb, $field, $op, $value, @rest ) = @_; + $op = "!=" if $op eq "<>"; + die "Invalid Operation: $op for $field" unless $op eq "=" or $op eq "!="; + + # See the comments for TransLimit, they apply here too + my $txn_alias = $sb->JoinTransactions; + if ( defined $value && $value !~ /^\d+$/ ) { + my $u = RT::User->new( $sb->CurrentUser ); + $u->Load($value); + $value = $u->id || 0; + } + $sb->_SQLLimit( ALIAS => $txn_alias, FIELD => 'Creator', OPERATOR => $op, VALUE => $value, @rest ); +} + =head2 _TransLimit Limit based on the ContentType or the Filename of a transaction. diff --git a/lib/RT/Topic.pm b/lib/RT/Topic.pm index 52c8b42..932ad29 100644 --- a/lib/RT/Topic.pm +++ b/lib/RT/Topic.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Topics.pm b/lib/RT/Topics.pm index 53218f6..4188653 100644 --- a/lib/RT/Topics.pm +++ b/lib/RT/Topics.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm index 37337fc..d1be663 100644 --- a/lib/RT/Transaction.pm +++ b/lib/RT/Transaction.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -343,10 +343,22 @@ sub Content { $content = $content_obj->Content ||''; if ( lc $content_obj->ContentType eq 'text/html' ) { - $content =~ s/

--\s+
.*?$//s if $args{'Quote'}; + $content =~ s/(?:(<\/div>)|

||)\s*--\s+.*?$/$1/s if $args{'Quote'}; if ($args{Type} ne 'text/html') { $content = RT::Interface::Email::ConvertHTMLToText($content); + } else { + # Scrub out , , , and , and + # leave all else untouched. + my $scrubber = HTML::Scrubber->new(); + $scrubber->rules( + html => 0, + head => 0, + meta => 0, + body => 0, + ); + $scrubber->default( 1 => { '*' => 1 } ); + $content = $scrubber->scrub( $content ); } } else { @@ -367,10 +379,18 @@ sub Content { } if ( $args{'Quote'} ) { - $content = $self->ApplyQuoteWrap(content => $content, - cols => $args{'Wrap'} ); + if ($args{Type} eq 'text/html') { + $content = '

' + . $self->QuoteHeader + . '
' + . $content + . '


'; + } else { + $content = $self->ApplyQuoteWrap(content => $content, + cols => $args{'Wrap'} ); - $content = $self->QuoteHeader . "\n$content\n\n"; + $content = $self->QuoteHeader . "\n$content\n\n"; + } } return ($content); @@ -780,46 +800,46 @@ sub _FormatUser { %_BriefDescriptions = ( Create => sub { my $self = shift; - return ( "[_1] created", $self->FriendlyObjectType ); #loc + return ( "[_1] created", $self->FriendlyObjectType ); #loc() }, Enabled => sub { my $self = shift; - return ( "[_1] enabled", $self->FriendlyObjectType ); #loc + return ( "[_1] enabled", $self->FriendlyObjectType ); #loc() }, Disabled => sub { my $self = shift; - return ( "[_1] disabled", $self->FriendlyObjectType ); #loc + return ( "[_1] disabled", $self->FriendlyObjectType ); #loc() }, Status => sub { my $self = shift; if ( $self->Field eq 'Status' ) { if ( $self->NewValue eq 'deleted' ) { - return ( "[_1] deleted", $self->FriendlyObjectType ); #loc + return ( "[_1] deleted", $self->FriendlyObjectType ); #loc() } else { my $canon = $self->Object->DOES("RT::Record::Role::Status") ? sub { $self->Object->LifecycleObj->CanonicalCase(@_) } : sub { return $_[0] }; return ( - "Status changed from [_1] to [_2]", #loc + "Status changed from [_1] to [_2]", "'" . $self->loc( $canon->($self->OldValue) ) . "'", "'" . $self->loc( $canon->($self->NewValue) ) . "'" - ); + ); # loc() } } # Generic: my $no_value = $self->loc("(no value)"); return ( - "[_1] changed from [_2] to [_3]", #loc + "[_1] changed from [_2] to [_3]", $self->Field, ( $self->OldValue ? "'" . $self->OldValue . "'" : $no_value ), "'" . $self->NewValue . "'" - ); + ); #loc() }, SystemError => sub { my $self = shift; - return ("System error"); #loc + return ("System error"); #loc() }, "Forward Transaction" => sub { my $self = shift; @@ -827,9 +847,9 @@ sub _FormatUser { RT::User->Format( Address => $_, CurrentUser => $self->CurrentUser ) } RT::EmailParser->ParseEmailAddress($self->Data); - return ( "Forwarded [_3]Transaction #[_1][_4] to [_2]", #loc + return ( "Forwarded [_3]Transaction #[_1][_4] to [_2]", $self->Field, $recipients, - [\''], \''); + [\''], \''); #loc() }, "Forward Ticket" => sub { my $self = shift; @@ -837,23 +857,23 @@ sub _FormatUser { RT::User->Format( Address => $_, CurrentUser => $self->CurrentUser ) } RT::EmailParser->ParseEmailAddress($self->Data); - return ( "Forwarded Ticket to [_1]", $recipients ); #loc + return ( "Forwarded Ticket to [_1]", $recipients ); #loc() }, CommentEmailRecord => sub { my $self = shift; - return ("Outgoing email about a comment recorded"); #loc + return ("Outgoing email about a comment recorded"); #loc() }, EmailRecord => sub { my $self = shift; - return ("Outgoing email recorded"); #loc + return ("Outgoing email recorded"); #loc() }, Correspond => sub { my $self = shift; - return ("Correspondence added"); #loc + return ("Correspondence added"); #loc() }, Comment => sub { my $self = shift; - return ("Comments added"); #loc + return ("Comments added"); #loc() }, CustomField => sub { my $self = shift; @@ -910,22 +930,22 @@ sub _FormatUser { } if ( !defined($old) || $old eq '' ) { - return ("[_1] [_2] added", $field, $new); #loc + return ("[_1] [_2] added", $field, $new); #loc() } elsif ( !defined($new) || $new eq '' ) { - return ("[_1] [_2] deleted", $field, $old); #loc + return ("[_1] [_2] deleted", $field, $old); #loc() } else { - return ("[_1] [_2] changed to [_3]", $field, $old, $new); #loc + return ("[_1] [_2] changed to [_3]", $field, $old, $new); #loc() } }, Untake => sub { my $self = shift; - return ("Untaken"); #loc + return ("Untaken"); #loc() }, Take => sub { my $self = shift; - return ("Taken"); #loc + return ("Taken"); #loc() }, Force => sub { my $self = shift; @@ -934,42 +954,42 @@ sub _FormatUser { my $New = RT::User->new( $self->CurrentUser ); $New->Load( $self->NewValue ); - return ("Owner forcibly changed from [_1] to [_2]", #loc - map { $self->_FormatUser($_) } $Old, $New); + return ("Owner forcibly changed from [_1] to [_2]", + map { $self->_FormatUser($_) } $Old, $New); #loc() }, Steal => sub { my $self = shift; my $Old = RT::User->new( $self->CurrentUser ); $Old->Load( $self->OldValue ); - return ("Stolen from [_1]", $self->_FormatUser($Old)); #loc + return ("Stolen from [_1]", $self->_FormatUser($Old)); #loc() }, Give => sub { my $self = shift; my $New = RT::User->new( $self->CurrentUser ); $New->Load( $self->NewValue ); - return ( "Given to [_1]", $self->_FormatUser($New)); #loc + return ( "Given to [_1]", $self->_FormatUser($New)); #loc() }, AddWatcher => sub { my $self = shift; my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($self->NewValue); - return ( "[_1] [_2] added", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc + return ( "[_1] [_2] added", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc() }, DelWatcher => sub { my $self = shift; my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($self->OldValue); - return ( "[_1] [_2] deleted", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc + return ( "[_1] [_2] deleted", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc() }, SetWatcher => sub { my $self = shift; my $principal = RT::Principal->new($self->CurrentUser); $principal->Load($self->NewValue); - return ( "[_1] set to [_2]", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc + return ( "[_1] set to [_2]", $self->loc($self->Field), $self->_FormatPrincipal($principal)); #loc() }, Subject => sub { my $self = shift; - return ( "Subject changed to [_1]", $self->Data ); #loc + return ( "Subject changed to [_1]", $self->Data ); #loc() }, AddLink => sub { my $self = shift; @@ -988,29 +1008,29 @@ sub _FormatUser { } if ( $self->Field eq 'DependsOn' ) { - return ( "Dependency on [_1] added", $value ); #loc + return ( "Dependency on [_1] added", $value ); #loc() } elsif ( $self->Field eq 'DependedOnBy' ) { - return ( "Dependency by [_1] added", $value ); #loc + return ( "Dependency by [_1] added", $value ); #loc() } elsif ( $self->Field eq 'RefersTo' ) { - return ( "Reference to [_1] added", $value ); #loc + return ( "Reference to [_1] added", $value ); #loc() } elsif ( $self->Field eq 'ReferredToBy' ) { - return ( "Reference by [_1] added", $value ); #loc + return ( "Reference by [_1] added", $value ); #loc() } elsif ( $self->Field eq 'MemberOf' ) { - return ( "Membership in [_1] added", $value ); #loc + return ( "Membership in [_1] added", $value ); #loc() } elsif ( $self->Field eq 'HasMember' ) { - return ( "Member [_1] added", $value ); #loc + return ( "Member [_1] added", $value ); #loc() } elsif ( $self->Field eq 'MergedInto' ) { - return ( "Merged into [_1]", $value ); #loc + return ( "Merged into [_1]", $value ); #loc() } } else { - return ( "[_1]", $self->Data ); #loc + return ( "[_1]", $self->Data ); #loc() } }, DeleteLink => sub { @@ -1030,26 +1050,26 @@ sub _FormatUser { } if ( $self->Field eq 'DependsOn' ) { - return ( "Dependency on [_1] deleted", $value ); #loc + return ( "Dependency on [_1] deleted", $value ); #loc() } elsif ( $self->Field eq 'DependedOnBy' ) { - return ( "Dependency by [_1] deleted", $value ); #loc + return ( "Dependency by [_1] deleted", $value ); #loc() } elsif ( $self->Field eq 'RefersTo' ) { - return ( "Reference to [_1] deleted", $value ); #loc + return ( "Reference to [_1] deleted", $value ); #loc() } elsif ( $self->Field eq 'ReferredToBy' ) { - return ( "Reference by [_1] deleted", $value ); #loc + return ( "Reference by [_1] deleted", $value ); #loc() } elsif ( $self->Field eq 'MemberOf' ) { - return ( "Membership in [_1] deleted", $value ); #loc + return ( "Membership in [_1] deleted", $value ); #loc() } elsif ( $self->Field eq 'HasMember' ) { - return ( "Member [_1] deleted", $value ); #loc + return ( "Member [_1] deleted", $value ); #loc() } } else { - return ( "[_1]", $self->Data ); #loc + return ( "[_1]", $self->Data ); #loc() } }, Told => sub { @@ -1059,26 +1079,26 @@ sub _FormatUser { $t1->Set(Format => 'ISO', Value => $self->NewValue); my $t2 = RT::Date->new($self->CurrentUser); $t2->Set(Format => 'ISO', Value => $self->OldValue); - return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), $t2->AsString, $t1->AsString ); #loc + return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), $t2->AsString, $t1->AsString ); #loc() } else { - return ( "[_1] changed from [_2] to [_3]", #loc + return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), - ($self->OldValue? "'".$self->OldValue ."'" : $self->loc("(no value)")) , "'". $self->NewValue."'" ); + ($self->OldValue? "'".$self->OldValue ."'" : $self->loc("(no value)")) , "'". $self->NewValue."'" ); #loc() } }, Set => sub { my $self = shift; if ( $self->Field eq 'Password' ) { - return ('Password changed'); #loc + return ('Password changed'); #loc() } elsif ( $self->Field eq 'Queue' ) { my $q1 = RT::Queue->new( $self->CurrentUser ); $q1->Load( $self->OldValue ); my $q2 = RT::Queue->new( $self->CurrentUser ); $q2->Load( $self->NewValue ); - return ("[_1] changed from [_2] to [_3]", #loc - $self->loc($self->Field) , $q1->Name , $q2->Name); + return ("[_1] changed from [_2] to [_3]", + $self->loc($self->Field) , $q1->Name , $q2->Name); #loc() } # Write the date/time change at local time: @@ -1087,7 +1107,7 @@ sub _FormatUser { $t1->Set(Format => 'ISO', Value => $self->NewValue); my $t2 = RT::Date->new($self->CurrentUser); $t2->Set(Format => 'ISO', Value => $self->OldValue); - return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), $t2->AsString, $t1->AsString ); #loc + return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), $t2->AsString, $t1->AsString ); #loc() } elsif ( $self->Field eq 'Owner' ) { my $Old = RT::User->new( $self->CurrentUser ); @@ -1097,36 +1117,37 @@ sub _FormatUser { if ( $Old->id == RT->Nobody->id ) { if ( $New->id == $self->Creator ) { - return ("Taken"); #loc + return ("Taken"); #loc() } else { - return ( "Given to [_1]", $self->_FormatUser($New) ); #loc + return ( "Given to [_1]", $self->_FormatUser($New) ); #loc() } } else { if ( $New->id == $self->Creator ) { - return ("Stolen from [_1]", $self->_FormatUser($Old) ); #loc + return ("Stolen from [_1]", $self->_FormatUser($Old) ); #loc() } elsif ( $Old->id == $self->Creator ) { if ( $New->id == RT->Nobody->id ) { - return ("Untaken"); #loc + return ("Untaken"); #loc() } else { - return ( "Given to [_1]", $self->_FormatUser($New) ); #loc + return ( "Given to [_1]", $self->_FormatUser($New) ); #loc() } } else { return ( - "Owner forcibly changed from [_1] to [_2]", #loc + "Owner forcibly changed from [_1] to [_2]", map { $self->_FormatUser($_) } $Old, $New - ); + ); #loc() } } } else { - return ( "[_1] changed from [_2] to [_3]", #loc + return ( "[_1] changed from [_2] to [_3]", $self->loc($self->Field), - ($self->OldValue? "'".$self->OldValue ."'" : $self->loc("(no value)")) , "'". $self->NewValue."'" ); + ($self->OldValue? "'".$self->OldValue ."'" : $self->loc("(no value)")), + ($self->NewValue? "'".$self->NewValue ."'" : $self->loc("(no value)"))); #loc() } }, "Set-TimeWorked" => sub { @@ -1145,7 +1166,7 @@ sub _FormatUser { }, PurgeTransaction => sub { my $self = shift; - return ("Transaction [_1] purged", $self->Data); #loc + return ("Transaction [_1] purged", $self->Data); #loc() }, AddReminder => sub { my $self = shift; @@ -1156,7 +1177,7 @@ sub _FormatUser { "/Ticket/Reminders.html?id=", $self->ObjectId, "#reminder-", $ticket->id, \'">', $ticket->Subject, \'' ]; - return ("Reminder '[_1]' added", $subject); #loc + return ("Reminder '[_1]' added", $subject); #loc() }, OpenReminder => sub { my $self = shift; @@ -1167,7 +1188,7 @@ sub _FormatUser { "/Ticket/Reminders.html?id=", $self->ObjectId, "#reminder-", $ticket->id, \'">', $ticket->Subject, \'' ]; - return ("Reminder '[_1]' reopened", $subject); #loc + return ("Reminder '[_1]' reopened", $subject); #loc() }, ResolveReminder => sub { my $self = shift; @@ -1178,7 +1199,7 @@ sub _FormatUser { "/Ticket/Reminders.html?id=", $self->ObjectId, "#reminder-", $ticket->id, \'">', $ticket->Subject, \'' ]; - return ("Reminder '[_1]' completed", $subject); #loc + return ("Reminder '[_1]' completed", $subject); #loc() } ); diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm index e603997..ef9838c 100644 --- a/lib/RT/Transactions.pm +++ b/lib/RT/Transactions.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI.pm b/lib/RT/URI.pm index 00508ac..eaafe56 100644 --- a/lib/RT/URI.pm +++ b/lib/RT/URI.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI/a.pm b/lib/RT/URI/a.pm index 36a6274..7cc9249 100644 --- a/lib/RT/URI/a.pm +++ b/lib/RT/URI/a.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI/base.pm b/lib/RT/URI/base.pm index 63af140..820f83f 100644 --- a/lib/RT/URI/base.pm +++ b/lib/RT/URI/base.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI/fsck_com_article.pm b/lib/RT/URI/fsck_com_article.pm index 19e913b..0c61623 100644 --- a/lib/RT/URI/fsck_com_article.pm +++ b/lib/RT/URI/fsck_com_article.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI/fsck_com_rt.pm b/lib/RT/URI/fsck_com_rt.pm index 7daec8b..001ba0c 100644 --- a/lib/RT/URI/fsck_com_rt.pm +++ b/lib/RT/URI/fsck_com_rt.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/URI/t.pm b/lib/RT/URI/t.pm index 71c81fa..d3a1214 100644 --- a/lib/RT/URI/t.pm +++ b/lib/RT/URI/t.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/User.pm b/lib/RT/User.pm index 9500aca..c07cfc8 100644 --- a/lib/RT/User.pm +++ b/lib/RT/User.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -89,26 +89,26 @@ use Text::Password::Pronounceable; sub _OverlayAccessible { { - Name => { public => 1, admin => 1 }, + Name => { public => 1, admin => 1 }, # loc_left_pair Password => { read => 0 }, - EmailAddress => { public => 1 }, - Organization => { public => 1, admin => 1 }, - RealName => { public => 1 }, - NickName => { public => 1 }, - Lang => { public => 1 }, + EmailAddress => { public => 1 }, # loc_left_pair + Organization => { public => 1, admin => 1 }, # loc_left_pair + RealName => { public => 1 }, # loc_left_pair + NickName => { public => 1 }, # loc_left_pair + Lang => { public => 1 }, # loc_left_pair EmailEncoding => { public => 1 }, WebEncoding => { public => 1 }, ExternalContactInfoId => { public => 1, admin => 1 }, ContactInfoSystem => { public => 1, admin => 1 }, ExternalAuthId => { public => 1, admin => 1 }, AuthSystem => { public => 1, admin => 1 }, - Gecos => { public => 1, admin => 1 }, - PGPKey => { public => 1, admin => 1 }, - SMIMECertificate => { public => 1, admin => 1 }, + Gecos => { public => 1, admin => 1 }, # loc_left_pair + PGPKey => { public => 1, admin => 1 }, # loc_left_pair + SMIMECertificate => { public => 1, admin => 1 }, # loc_left_pair PrivateKey => { admin => 1 }, - City => { public => 1 }, - Country => { public => 1 }, - Timezone => { public => 1 }, + City => { public => 1 }, # loc_left_pair + Country => { public => 1 }, # loc_left_pair + Timezone => { public => 1 }, # loc_left_pair } } @@ -2672,7 +2672,7 @@ sub FindDependencies { # ACL equivalence group my $objs = RT::Groups->new( $self->CurrentUser ); - $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence' ); + $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 ); $objs->Limit( FIELD => 'Instance', VALUE => $self->Id ); $deps->Add( in => $objs ); @@ -2695,6 +2695,7 @@ sub FindDependencies { ALIAS => $groups, FIELD => 'Domain', VALUE => 'SystemInternal', + CASESENSITIVE => 0 ); $deps->Add( in => $objs ); @@ -2751,6 +2752,10 @@ sub PreInflate { Disabled => $disabled, ObjectId => 0, ); + + # Now we have a principal id, set the id for the user record + $data->{id} = $id; + $importer->Resolve( $principal_uid => ref($principal), $id ); $importer->Postpone( diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm index 9181b7f..a3eccf3 100644 --- a/lib/RT/Users.pm +++ b/lib/RT/Users.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/lib/RT/Util.pm b/lib/RT/Util.pm index 87f8413..89ea585 100644 --- a/lib/RT/Util.pm +++ b/lib/RT/Util.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/local/bin/rt-count b/local/bin/rt-count old mode 100644 new mode 100755 diff --git a/sbin/rt-attributes-viewer b/sbin/rt-attributes-viewer index ec67be9..7e45615 100755 --- a/sbin/rt-attributes-viewer +++ b/sbin/rt-attributes-viewer @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-clean-sessions b/sbin/rt-clean-sessions index 23aa9c0..c9f2d3b 100755 --- a/sbin/rt-clean-sessions +++ b/sbin/rt-clean-sessions @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-dump-metadata b/sbin/rt-dump-metadata index 3953e5c..7de9554 100755 --- a/sbin/rt-dump-metadata +++ b/sbin/rt-dump-metadata @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -72,7 +72,11 @@ BEGIN { # BEGIN RT CMD BOILERPLATE use Getopt::Long; my %opt; -GetOptions( \%opt, "help|h" ); +GetOptions( \%opt, "help|h", + "limit-to-privileged|l", + "skip-disabled|s", + "all|a", +); if ( $opt{help} ) { require Pod::Usage; @@ -86,8 +90,6 @@ require XML::Simple; RT::LoadConfig(); RT::Init(); -my $LocalOnly = @ARGV ? shift(@ARGV) : 1; - my %RV; my %Ignore = ( All => [ @@ -105,8 +107,16 @@ my @classes = qw( foreach my $class (@classes) { require "RT/$class.pm"; my $objects = "RT::$class"->new( RT->SystemUser ); - $objects->{find_disabled_rows} = 1; + $objects->{find_disabled_rows} = 1 unless $opt{'skip-disabled'}; $objects->UnLimit; + $objects->LimitToPrivileged if $class eq 'Users' + && $opt{'limit-to-privileged'}; + $objects->Limit( + FIELD => 'Domain', + OPERATOR => '=', + VALUE => 'UserDefined', + CASESENSITIVE => 0, + ) if $class eq 'Groups'; if ( $class eq 'CustomFields' ) { $objects->OrderByCols( @@ -118,7 +128,7 @@ foreach my $class (@classes) { $objects->OrderBy( FIELD => 'Id' ); } - if ($LocalOnly) { + unless ($opt{all}) { next if $class eq 'ACL'; # XXX - would go into infinite loop - XXX $objects->Limit( FIELD => 'LastUpdatedBy', @@ -130,15 +140,10 @@ foreach my $class (@classes) { OPERATOR => '!=', VALUE => $SystemUserId ) if $class eq 'Users'; - $objects->Limit( - FIELD => 'Domain', - OPERATOR => '=', - VALUE => 'UserDefined', - CASESENSITIVE => 0, - ) if $class eq 'Groups'; } my %fields; +OBJECT: while ( my $obj = $objects->Next ) { next if $obj->can('LastUpdatedBy') @@ -152,36 +157,106 @@ foreach my $class (@classes) { my $rv; - # next if $obj-> # skip default names - foreach my $field ( sort keys %fields ) { - my $value = $obj->__Value($field); - $rv->{$field} = $value if ( defined($value) && length($value) ); - } - delete $rv->{Disabled} unless $rv->{Disabled}; - - foreach my $record ( map { /ACL/ ? 'ACE' : substr( $_, 0, -1 ) } - @classes ) - { - foreach my $key ( map "$record$_", ( '', 'Id' ) ) { - next unless exists $rv->{$key}; - my $id = $rv->{$key} or next; - my $obj = "RT::$record"->new( RT->SystemUser ); - $obj->LoadByCols( Id => $id ) or next; - $rv->{$key} = $obj->__Value('Name') || 0; + if ( $class ne 'ACL' ) { + # next if $obj-> # skip default names + foreach my $field ( sort keys %fields ) { + my $value = $obj->__Value($field); + $rv->{$field} = $value if ( defined($value) && length($value) ); + } + delete $rv->{Disabled} unless $rv->{Disabled}; + + foreach my $record ( map { /ACL/ ? 'ACE' : substr( $_, 0, -1 ) } + @classes ) + { + foreach my $key ( map "$record$_", ( '', 'Id' ) ) { + next unless exists $rv->{$key}; + my $id = $rv->{$key} or next; + my $obj = "RT::$record"->new( RT->SystemUser ); + $obj->LoadByCols( Id => $id ) or next; + $rv->{$key} = $obj->__Value('Name') || 0; + } + } + + if ( $class eq 'Users' and defined $obj->Privileged ) { + $rv->{Privileged} = int( $obj->Privileged ); + } elsif ( $class eq 'CustomFields' ) { + my $values = $obj->Values; + while ( my $value = $values->Next ) { + push @{ $rv->{Values} }, { + map { ( $_ => $value->__Value($_) ) } + qw( + Name Description SortOrder + ), + }; + } + if ( $obj->LookupType eq 'RT::Queue-RT::Ticket' ) { + # XXX-TODO: unused CF's turn into global CF when importing + # as the sub InsertData in RT::Handle creates a global CF + # when no queue is specified. + $rv->{Queue} = []; + my $applies = $obj->AppliedTo; + while ( my $queue = $applies->Next ) { + push @{ $rv->{Queue} }, $queue->Name; + } + } } } + else { + # 1) pick the right + $rv->{Right} = $obj->RightName; + + # 2) Pick a level: Granted on Queue, CF, CF+Queue, or Globally? + for ( $obj->ObjectType ) { + if ( /^RT::Queue$/ ) { + next OBJECT if $opt{'skip-disabled'} && $obj->Object->Disabled; + $rv->{Queue} = $obj->Object->Name; + } + elsif ( /^RT::CustomField$/ ) { + next OBJECT if $opt{'skip-disabled'} && $obj->Object->Disabled; + $rv->{CF} = $obj->Object->Name; + } + elsif ( /^RT::Group$/ ) { + # No support for RT::Group ACLs in RT::Handle yet. + next OBJECT; + } + elsif ( /^RT::System$/ ) { + # skip setting anything on $rv; + # "Specifying none of the above will get you a global right." + } + } - if ( $class eq 'Users' and defined $obj->Privileged ) { - $rv->{Privileged} = int( $obj->Privileged ); - } elsif ( $class eq 'CustomFields' ) { - my $values = $obj->Values; - while ( my $value = $values->Next ) { - push @{ $rv->{Values} }, { - map { ( $_ => $value->__Value($_) ) } - qw( - Name Description SortOrder - ), - }; + # 3) Pick a Principal; User or Group or Role + if ( $obj->PrincipalType eq 'Group' ) { + next OBJECT if $opt{'skip-disabled'} && $obj->PrincipalObj->Disabled; + my $group = $obj->PrincipalObj->Object; + for ( $group->Domain ) { + # An internal user group + if ( /^SystemInternal$/ ) { + $rv->{GroupDomain} = $group->Domain; + $rv->{GroupType} = $group->Type; + } + # An individual user + elsif ( /^ACLEquivalence$/ ) { + my $member = $group->MembersObj->Next->MemberObj; + next OBJECT if $opt{'skip-disabled'} && $member->Disabled; + $rv->{UserId} = $member->Object->Name; + } + # A group you created + elsif ( /^UserDefined$/ ) { + $rv->{GroupDomain} = 'UserDefined'; + $rv->{GroupId} = $group->Name; + } + } + } else { + $rv->{GroupType} = $obj->PrincipalType; + # A system-level role + if ( $obj->ObjectType eq 'RT::System' ) { + $rv->{GroupDomain} = 'RT::System-Role'; + } + # A queue-level role + elsif ( $obj->ObjectType eq 'RT::Queue' ) { + $rv->{GroupDomain} = 'RT::Queue-Role'; + } } } @@ -189,6 +264,9 @@ foreach my $class (@classes) { my $attributes = $obj->Attributes; while ( my $attribute = $attributes->Next ) { my $content = $attribute->Content; + if ( $class eq 'Users' and $attribute->Name eq 'Bookmarks' ) { + next; + } $rv->{Attributes}{ $attribute->Name } = $content if length($content); } @@ -221,7 +299,7 @@ rt-dump-metadata - dump configuration metadata from an RT database =head1 SYNOPSIS - rt-dump-metdata [ 0 ] + rt-dump-metdata [--all] =head1 DESCRIPTION @@ -231,11 +309,28 @@ C. To dump and load a full RT database, you should generally use the native database tools instead, as well as performing any necessary steps from UPGRADING. -When run without arguments, the metadata dump will only include 'local' +This is NOT a tool for backing up an RT database. See also +L for more straightforward means of importing data. + +=head1 OPTIONS + +=over + +=item C<--all> or C<-a> + +When run with C<--all>, the dump will include all configuration +metadata; otherwise, the metadata dump will only include 'local' configuration changes, i.e. those done manually in the web interface. -When run with the argument '0', the dump will include all configuration -metadata. +=item C<--limit-to-privileged> or C<-l> + +Causes the dumper to only dump privileged users. + +=item C<--skip-disabled> or C<-s> + +Ignores disabled rows in the database. + +=back -This is NOT a tool for backing up an RT database. +=cut diff --git a/sbin/rt-email-dashboards b/sbin/rt-email-dashboards index b75ce32..ad34389 100755 --- a/sbin/rt-email-dashboards +++ b/sbin/rt-email-dashboards @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-email-digest b/sbin/rt-email-digest index 726e491..b1d4b10 100755 --- a/sbin/rt-email-digest +++ b/sbin/rt-email-digest @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-email-group-admin b/sbin/rt-email-group-admin index 536b884..2fa245c 100755 --- a/sbin/rt-email-group-admin +++ b/sbin/rt-email-group-admin @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-fulltext-indexer b/sbin/rt-fulltext-indexer index b535fcf..6e5256d 100755 --- a/sbin/rt-fulltext-indexer +++ b/sbin/rt-fulltext-indexer @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-importer b/sbin/rt-importer new file mode 100755 index 0000000..d2480c8 --- /dev/null +++ b/sbin/rt-importer @@ -0,0 +1,282 @@ +#!/usr/bin/perl +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC +# +# +# (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 strict; +use warnings; + +# fix lib paths, some may be relative +BEGIN { + require File::Spec; + my @libs = ("lib", "local/lib"); + my $bin_path; + + for my $lib (@libs) { + unless ( File::Spec->file_name_is_absolute($lib) ) { + unless ($bin_path) { + if ( File::Spec->file_name_is_absolute(__FILE__) ) { + $bin_path = ( File::Spec->splitpath(__FILE__) )[1]; + } + else { + require FindBin; + no warnings "once"; + $bin_path = $FindBin::Bin; + } + } + $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib ); + } + unshift @INC, $lib; + } + +} + +use RT; +RT::LoadConfig(); +RT->Config->Set(RecordBaseClass => "DBIx::SearchBuilder::Record"); +RT::Init(); + +use RT::Migrate; +use RT::Migrate::Importer::File; +use Getopt::Long; +use Pod::Usage qw//; +use Time::HiRes qw//; + +my %OPT = (resume => 1); +GetOptions( + \%OPT, + "help|?", + "quiet|q!", + "list|l!", + + "resume!", + "originalid|i=s", + + "ask", + "ignore-errors", + + "dump=s@", +) or Pod::Usage::pod2usage(); + +Pod::Usage::pod2usage(-verbose => 1) if $OPT{help}; + +Pod::Usage::pod2usage() unless @ARGV == 1; +my ($dir) = @ARGV; +$dir =~ s|/$||; +die "No such directory $dir\n" unless -d $dir; +die "$dir doesn't appear to contain serialized data\n" + unless -f "$dir/001.dat"; + +if ($OPT{dump}) { + die "Dumping objects only works in conjunction with --list\n" + unless $OPT{list}; + + $OPT{dump} = [ split /,/, join(',', @{$OPT{dump}}) ]; +} + +my $error_handler; +if ($OPT{ask}) { + die "Interactive mode (--ask) doesn't work when STDERR and STDIN aren't terminals.\n" + unless -t STDERR and -t STDIN; + + $error_handler = sub { + my $importer = shift; + local $| = 1; + print STDERR "\n", @_, "\n"; + print STDERR "Hit any key to abort import, or type 'ignore' to continue anyway.\n"; + print STDERR "Continuing may leave you with a corrupt database. > "; + chomp( my $resp = ); + return lc($resp) eq 'ignore'; + }; +} +elsif ($OPT{'ignore-errors'}) { + $error_handler = sub { + my $importer = shift; + warn "Ignoring error: ", @_; + return 1; + }; +} + +my $import = RT::Migrate::Importer::File->new( + Directory => $dir, + OriginalId => $OPT{originalid}, + DumpObjects => $OPT{dump}, + Resume => $OPT{resume}, + HandleError => $error_handler, +); + +if ($import->Metadata and -t STDOUT and not $OPT{quiet}) { + $import->Progress( + RT::Migrate::progress( + counts => sub { $import->ObjectCount }, + max => $import->Metadata->{ObjectCount}, + ) + ); +} + +my $log = RT::Migrate::setup_logging( $dir => 'importer.log' ); +print "Logging warnings and errors to $log\n" if $log; + +my %counts; +if ($OPT{list}) { + %counts = $import->List; + + my $org = $import->Organization; + print "=========== Dump of $org ===========\n\n"; +} else { + %counts = $import->Import; + + my $org = $import->Organization; + print "========== Import of $org ==========\n\n"; +} + +print "Total object counts:\n"; +for (sort {$counts{$b} <=> $counts{$a}} keys %counts) { + printf "%8d %s\n", $counts{$_}, $_; +} + +my @missing = $import->Missing; +if (@missing) { + warn "The following UIDs were expected but never observed:\n"; + warn " $_\n" for @missing; +} + +my @invalid = $import->Invalid; +if (@invalid) { + warn "The following UIDs (serialized => imported) referred to objects missing from the original database:\n"; + for my $info (@invalid) { + my $uid = delete $info->{uid}; + my $obj = $import->LookupObj($uid); + warn sprintf " %s => %s (%s)\n", + $uid, + ($obj && $obj->Id ? $obj->UID : '(not imported)'), + join(", ", map { "$_ => $info->{$_}" } + grep { defined $info->{$_} } + sort keys %$info); + } +} + +if ($log and -s $log) { + print STDERR "\n! Some warnings or errors occurred during import." + ."\n! Please see $log for details.\n\n"; +} + +exit @missing; + +=head1 NAME + +rt-importer - Import a serialized RT database on top of the current one + +=head1 SYNOPSIS + + rt-importer path/to/export/directory + +This script is used to import the contents of a dump created by +C. It will create all of the objects in the dump in the +current database; this may include users, queues, and tickets. + +It is possible to stop the import process with ^C; it can be later +resumed by re-running the importer. + +=head2 OPTIONS + +=over + +=item B<--list> + +Print a summary of the data contained in the dump. + +=item B<--originalid> I + +Places the original ticket organization and ID into a global custom +field with the given name. If no global ticket custom field with that +name is found in the current database, it will create one. + +=item B<--ask> + +Prompt for action when an error occurs inserting a record into the +database. This can often happen when importing data from very old RTs +where some attachments (usually spam) contain invalid UTF-8. + +The importer will pause and ask if you want to ignore the error and +continue on or abort (potentially to restart later). Ignoring errors +will result in missing records in the database, which may cause database +integrity problems later. If you ignored any errors, you should run +C after import. + +=item B<--ignore-errors> + +Ignore all record creation errors and continue on when importing. This +is equivalent to running with C<--ask> and manually typing "ignore" at +every prompt. You should always run C after importing +with errors ignored. + +B + +=item B<--dump> I[,I] + +Prints L representations of the objects of type I in the +serialized data. This is mostly useful for debugging. + +Works only in conjunction with C<--list>. + +=back + + +=head1 CLONED DATA + +Some dumps may have been taken as complete clones of the RT system, +which are only suitable for inserting into a schema with no data in it. +You can setup the required database state for the receiving RT instance +by running: + + sbin/rt-setup-database --action create,schema,acl --prompt-for-dba-password + +The normal C step will B work because it also inserts +core system data. + + +=cut diff --git a/sbin/rt-preferences-viewer b/sbin/rt-preferences-viewer index e604b68..819a938 100755 --- a/sbin/rt-preferences-viewer +++ b/sbin/rt-preferences-viewer @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-serializer b/sbin/rt-serializer new file mode 100755 index 0000000..5d27393 --- /dev/null +++ b/sbin/rt-serializer @@ -0,0 +1,397 @@ +#!/usr/bin/perl +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC +# +# +# (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 strict; +use warnings; + +# fix lib paths, some may be relative +BEGIN { + require File::Spec; + my @libs = ("lib", "local/lib"); + my $bin_path; + + for my $lib (@libs) { + unless ( File::Spec->file_name_is_absolute($lib) ) { + unless ($bin_path) { + if ( File::Spec->file_name_is_absolute(__FILE__) ) { + $bin_path = ( File::Spec->splitpath(__FILE__) )[1]; + } + else { + require FindBin; + no warnings "once"; + $bin_path = $FindBin::Bin; + } + } + $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib ); + } + unshift @INC, $lib; + } + +} + +use RT; +RT::LoadConfig(); +RT->Config->Set(RecordBaseClass => "DBIx::SearchBuilder::Record"); +RT::Init(); + +use RT::Migrate; +use RT::Migrate::Serializer::File; +use Getopt::Long; +use Pod::Usage qw//; +use Time::HiRes qw//; + +my %OPT; +GetOptions( + \%OPT, + "help|?", + "verbose|v!", + "quiet|q!", + + "directory|d=s", + "force|f!", + "size|s=i", + + "users!", + "groups!", + "deleted!", + + "scrips!", + "tickets!", + "acls!", + + "clone", + "incremental", + + "gc=i", + "page=i", +) or Pod::Usage::pod2usage(); + +Pod::Usage::pod2usage(-verbose => 1) if $OPT{help}; + +my %args; +$args{Directory} = $OPT{directory}; +$args{Force} = $OPT{force}; +$args{MaxFileSize} = $OPT{size} if $OPT{size}; + +$args{AllUsers} = $OPT{users} if defined $OPT{users}; +$args{AllGroups} = $OPT{groups} if defined $OPT{groups}; +$args{FollowDeleted} = $OPT{deleted} if defined $OPT{deleted}; + +$args{FollowScrips} = $OPT{scrips} if defined $OPT{scrips}; +$args{FollowTickets} = $OPT{tickets} if defined $OPT{tickets}; +$args{FollowACL} = $OPT{acls} if defined $OPT{acls}; + +$args{Clone} = $OPT{clone} if $OPT{clone}; +$args{Incremental} = $OPT{incremental} if $OPT{incremental}; + +$args{GC} = defined $OPT{gc} ? $OPT{gc} : 5000; +$args{Page} = defined $OPT{page} ? $OPT{page} : 100; + +if (($OPT{clone} or $OPT{incremental}) + and grep { /^(users|groups|deleted|scrips|tickets|acls)$/ } keys %OPT) { + die "You cannot specify object types when cloning.\n\nPlease see $0 --help.\n"; +} + +my $walker; + +my $gnuplot = `which gnuplot`; +my $msg = ""; +if (-t STDOUT and not $OPT{verbose} and not $OPT{quiet}) { + $args{Progress} = RT::Migrate::progress( + top => \&gnuplot, + bottom => sub { print "\n$msg"; $msg = ""; }, + counts => sub { $walker->ObjectCount }, + max => { estimate() }, + ); + $args{MessageHandler} = sub { + print "\r", " "x60, "\r", $_[-1]; $msg = $_[-1]; + }; + $args{Verbose} = 0; +} +$args{Verbose} = 0 if $OPT{quiet}; + + +$walker = RT::Migrate::Serializer::File->new( %args ); + +my $log = RT::Migrate::setup_logging( $walker->{Directory} => 'serializer.log' ); +print "Logging warnings and errors to $log\n" if $log; + +print "Beginning database serialization..."; +my %counts = $walker->Export; + +my @files = $walker->Files; +print "Wrote @{[scalar @files]} files:\n"; +print " $_\n" for @files; +print "\n"; + +print "Total object counts:\n"; +for (sort {$counts{$b} <=> $counts{$a}} keys %counts) { + printf "%8d %s\n", $counts{$_}, $_; +} + +if ($log and -s $log) { + print STDERR "\n! Some warnings or errors occurred during serialization." + ."\n! Please see $log for details.\n\n"; +} else { + unlink $log; +} + +sub estimate { + $| = 1; + my %e; + + # Expected types we'll serialize + my @types = map {"RT::$_"} qw/ + Queue Ticket Transaction Attachment Link + User Group GroupMember Attribute + CustomField CustomFieldValue + ObjectCustomField ObjectCustomFieldValue + /; + + for my $class (@types) { + print "Estimating $class count..."; + my $collection = $class . "s"; + eval "require $collection"; + unless ($@) { + my $objs = $collection->new( RT->SystemUser ); + $objs->FindAllRows; + $objs->UnLimit; + $objs->{allow_deleted_search} = 1 if $class eq "RT::Ticket"; + $e{$class} = $objs->DBIx::SearchBuilder::Count; + } + print "\r", " "x60, "\r"; + } + + return %e; +} + + +sub gnuplot { + my ($elapsed, $rows, $cols) = @_; + my $length = $walker->StackSize; + my $file = $walker->Directory . "/progress.plot"; + open(my $dat, ">>", $file); + printf $dat "%10.3f\t%8d\n", $elapsed, $length; + close $dat; + + if ($rows <= 24 or not $gnuplot) { + print "\n\n"; + } elsif ($elapsed) { + my $gnuplot = qx| + gnuplot -e ' + set term dumb $cols @{[$rows - 12]}; + set xlabel "Seconds"; + unset key; + set xrange [0:*]; + set yrange [0:*]; + set title "Queue length"; + plot "$file" using 1:2 with lines + ' + |; + if ($? == 0 and $gnuplot) { + $gnuplot =~ s/^(\s*\n)//; + print $gnuplot; + unlink $file; + } else { + warn "Couldn't run gnuplot (\$? == $?): $!\n"; + } + } else { + print "\n" for 1..($rows - 13); + } +} + +=head1 NAME + +rt-serializer - Serialize an RT database to disk + +=head1 SYNOPSIS + + rt-validator --check && rt-serializer + +This script is used to write out the entire RT database to disk, for +later import into a different RT instance. It requires that the data in +the database be self-consistent, in order to do so; please make sure +that the database being exported passes validation by L +before attempting to use C. + +While running, it will attempt to estimate the number of remaining +objects to be serialized; these estimates are pessimistic, and will be +incorrect if C<--no-users>, C<--no-groups>, or C<--no-tickets> are used. + +If the controlling terminal is large enough (more than 25 columns high) +and the C program is installed, it will also show a textual +graph of the queue size over time. + +=head2 OPTIONS + +=over + +=item B<--directory> I + +The name of the output directory to write data files to, which should +not exist yet; it is a fatal error if it does. Defaults to +C<< ./I<$Organization>:I/ >>, where I<$Organization> is as set in +F, and I is today's date. + +=item B<--force> + +Remove the output directory before starting. + +=item B<--size> I + +By default, C chunks its output into data files which are +around 32Mb in size; this option is used to set a different threshold +size, in megabytes. Note that this is the threshold after which it +rotates to writing a new file, and is as such the I on the +size of each output file. + +=item B<--no-users> + +By default, all privileged users are serialized; passing C<--no-users> +limits it to only those users which are strictly necessary. + +=item B<--no-groups> + +By default, all groups are serialized; passing C<--no-groups> limits it +to only those groups which are strictly necessary. + +=item B<--no-deleted> + +By default, all tickets, including deleted tickets, are serialized; +passing C<--no-deleted> skips deleted tickets during serialization. + +=item B<--scrips> + +No scrips or templates are serialized by default; this option forces all +scrips and templates to be serialized. + +=item B<--acls> + +No ACLs are serialized by default; this option forces all ACLs to be +serialized. + +=item B<--no-tickets> + +Skip serialization of all ticket data. + +=item B<--clone> + +Serializes your entire database, creating a clone. This option should +be used if you want to migrate your RT database from one database type +to another (e.g. MySQL to Postgres). It is an error to combine +C<--clone> with any option that limits object types serialized. No +dependency walking is performed when cloning. C will detect +that your serialized data set was generated by a clone. + +=item B<--incremental> + +Will generate an incremenal serialized dataset using the data stored in +your IncrementalRecords database table. This assumes that you have created +that table and run RT using the Record_Local.pm shim as documented in +C. + +=item B<--gc> I + +Adjust how often the garbage collection sweep is done; lower numbers are +more frequent. See L. + +=item B<--page> I + +Adjust how many rows are pulled from the database in a single query. Disable +paging by setting this to 0. Defaults to 100. + +Keep in mind that rows from RT's Attachments table are the limiting factor when +determining page size. You should likely be aiming for 60-75% of your total +memory on an otherwise unloaded box. + +=item B<--quiet> + +Do not show graphical progress UI. + +=item B<--verbose> + +Do not show graphical progress UI, but rather log was each row is +written out. + +=back + +=head1 GARBAGE COLLECTION + +C maintains a priority queue of objects to serialize, or +searches which may result in objects to serialize. When inserting into +this queue, it does no checking if the object in question is already in +the queue, or if the search will contain any results. These checks are +done when the object reaches the front of the queue, or during periodic +garbage collection. + +During periodic garbage collection, the entire queue is swept for +objects which have already been serialized, occur more than once in the +queue, and searches which contain no results in the database. This is +done to reduce the memory footprint of the serialization process, and is +triggered when enough new objects have been placed in the queue. This +parameter is tunable via the C<--gc> parameter, which defaults to +running garbage collection every 5,000 objects inserted into the queue; +smaller numbers will result in more frequent garbage collection. + +The default of 5,000 is roughly tuned based on a database with several +thousand tickets, but optimal values will vary wildly depending on +database configuration and size. Values as low as 25 have provided +speedups with smaller databases; if speed is a factor, experimenting +with different C<--gc> values may be helpful. Note that there are +significant boundary condition changes in serialization rate, as the +queue empties and fills, causing the time estimates to be rather +imprecise near the start and end of the process. + +Setting C<--gc> to 0 turns off all garbage collection. Be aware that +this will bloat the memory usage of the serializer. Any negative value +for C<--gc> turns off periodic garbage collection and instead objects +already serialized or in the queue are checked for at the time they +would be inserted. + +=cut + diff --git a/sbin/rt-server b/sbin/rt-server index ef6e0f7..39be083 100755 --- a/sbin/rt-server +++ b/sbin/rt-server @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -120,7 +120,7 @@ EOF RT->InstallMode(1); } else { - RT->Init(); + RT->Init( Heavy => 1 ); my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'post'); unless ( $status ) { diff --git a/sbin/rt-server.fcgi b/sbin/rt-server.fcgi index ef6e0f7..39be083 100755 --- a/sbin/rt-server.fcgi +++ b/sbin/rt-server.fcgi @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -120,7 +120,7 @@ EOF RT->InstallMode(1); } else { - RT->Init(); + RT->Init( Heavy => 1 ); my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'post'); unless ( $status ) { diff --git a/sbin/rt-session-viewer b/sbin/rt-session-viewer index 204bbdc..6dcfd4f 100755 --- a/sbin/rt-session-viewer +++ b/sbin/rt-session-viewer @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-setup-database b/sbin/rt-setup-database index b1b9d9a..813e39e 100755 --- a/sbin/rt-setup-database +++ b/sbin/rt-setup-database @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -84,6 +84,7 @@ GetOptions( 'dba=s', 'dba-password=s', 'prompt-for-dba-password', 'package=s', 'datafile=s', 'datadir=s', 'skip-create', 'root-password-file=s', 'package=s', 'ext-version=s', + 'upgrade-from=s', 'upgrade-to=s', 'help|h', ); @@ -424,7 +425,7 @@ sub action_upgrade { } else { print "Enter $args{package} version you're upgrading from: "; } - $upgrading_from = scalar ; + $upgrading_from = $args{'upgrade-from'} || scalar ; chomp $upgrading_from; $upgrading_from =~ s/\s+//g; } while $upgrading_from !~ /$version_dir/; @@ -458,7 +459,7 @@ sub action_upgrade { print "\nEnter $args{package} version if you want to stop upgrade at some point,\n"; print " or leave it blank if you want apply above upgrades: "; } - $custom_upgrading_to = scalar ; + $custom_upgrading_to = $args{'upgrade-to'} || scalar ; chomp $custom_upgrading_to; $custom_upgrading_to =~ s/\s+//g; last unless $custom_upgrading_to; @@ -777,6 +778,16 @@ of the extension or plugin making changes to the DB. current version of extension making a change. Not needed for RT since RT has a more elaborate system to track upgrades across multiple versions. +=item upgrade-from + +for 'upgrade': specifies the version to upgrade from, and do not prompt +for it if it appears to be a valid version. + +=item upgrade-to + +for 'upgrade': specifies the version to upgrade to, and do not prompt +for it if it appears to be a valid version. + =back =cut diff --git a/sbin/rt-setup-fulltext-index b/sbin/rt-setup-fulltext-index index bd9a8d1..e93f6c1 100755 --- a/sbin/rt-setup-fulltext-index +++ b/sbin/rt-setup-fulltext-index @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-shredder b/sbin/rt-shredder index 9a6fc2d..b5c5529 100755 --- a/sbin/rt-shredder +++ b/sbin/rt-shredder @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-test-dependencies b/sbin/rt-test-dependencies index fbb11dc..c5af39e 100755 --- a/sbin/rt-test-dependencies +++ b/sbin/rt-test-dependencies @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/rt-validate-aliases b/sbin/rt-validate-aliases index e3cf10d..d5b41b8 100755 --- a/sbin/rt-validate-aliases +++ b/sbin/rt-validate-aliases @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -173,7 +173,7 @@ while (my $q = $queues->Next) { if (not $value) { my @other = grep {$_ ne $global{$setting}} @{$seen{lc $q->Name}{$action} || []}; - warn "CorrespondAddress not set on $qname, but in aliases as " + warn "$setting not set on $qname, but in aliases as " .join(" and ", @other) . "\n" if @other; next; } diff --git a/sbin/rt-validator b/sbin/rt-validator index 5c110c1..96b52e6 100755 --- a/sbin/rt-validator +++ b/sbin/rt-validator @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) diff --git a/sbin/standalone_httpd b/sbin/standalone_httpd index ef6e0f7..39be083 100755 --- a/sbin/standalone_httpd +++ b/sbin/standalone_httpd @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -120,7 +120,7 @@ EOF RT->InstallMode(1); } else { - RT->Init(); + RT->Init( Heavy => 1 ); my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'post'); unless ( $status ) { diff --git a/share/html/Admin/Articles/Classes/CustomFields.html b/share/html/Admin/Articles/Classes/CustomFields.html index 65705b9..f8a5bd6 100644 --- a/share/html/Admin/Articles/Classes/CustomFields.html +++ b/share/html/Admin/Articles/Classes/CustomFields.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/GroupRights.html b/share/html/Admin/Articles/Classes/GroupRights.html index 9fdd60d..433e3d5 100644 --- a/share/html/Admin/Articles/Classes/GroupRights.html +++ b/share/html/Admin/Articles/Classes/GroupRights.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/Modify.html b/share/html/Admin/Articles/Classes/Modify.html index 95bb176..304a8e5 100644 --- a/share/html/Admin/Articles/Classes/Modify.html +++ b/share/html/Admin/Articles/Classes/Modify.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/Objects.html b/share/html/Admin/Articles/Classes/Objects.html index f07422d..1345e65 100644 --- a/share/html/Admin/Articles/Classes/Objects.html +++ b/share/html/Admin/Articles/Classes/Objects.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/Topics.html b/share/html/Admin/Articles/Classes/Topics.html index 88b602e..525bf45 100644 --- a/share/html/Admin/Articles/Classes/Topics.html +++ b/share/html/Admin/Articles/Classes/Topics.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/UserRights.html b/share/html/Admin/Articles/Classes/UserRights.html index fe614ba..9f26fdc 100644 --- a/share/html/Admin/Articles/Classes/UserRights.html +++ b/share/html/Admin/Articles/Classes/UserRights.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Classes/index.html b/share/html/Admin/Articles/Classes/index.html index f8b3c8f..78b8803 100644 --- a/share/html/Admin/Articles/Classes/index.html +++ b/share/html/Admin/Articles/Classes/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/Elements/Topics b/share/html/Admin/Articles/Elements/Topics index c6a3839..f30f69e 100644 --- a/share/html/Admin/Articles/Elements/Topics +++ b/share/html/Admin/Articles/Elements/Topics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Articles/index.html b/share/html/Admin/Articles/index.html index bfe434c..266bf92 100644 --- a/share/html/Admin/Articles/index.html +++ b/share/html/Admin/Articles/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/CustomFields/GroupRights.html b/share/html/Admin/CustomFields/GroupRights.html index b8096a8..9e50ce9 100644 --- a/share/html/Admin/CustomFields/GroupRights.html +++ b/share/html/Admin/CustomFields/GroupRights.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/CustomFields/Modify.html b/share/html/Admin/CustomFields/Modify.html index c28c7d4..78995f3 100644 --- a/share/html/Admin/CustomFields/Modify.html +++ b/share/html/Admin/CustomFields/Modify.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/CustomFields/Objects.html b/share/html/Admin/CustomFields/Objects.html index a76b26f..e0afa8c 100644 --- a/share/html/Admin/CustomFields/Objects.html +++ b/share/html/Admin/CustomFields/Objects.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/CustomFields/UserRights.html b/share/html/Admin/CustomFields/UserRights.html index d469298..bc2d800 100644 --- a/share/html/Admin/CustomFields/UserRights.html +++ b/share/html/Admin/CustomFields/UserRights.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/CustomFields/index.html b/share/html/Admin/CustomFields/index.html index cf5f3bf..845e863 100644 --- a/share/html/Admin/CustomFields/index.html +++ b/share/html/Admin/CustomFields/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/AddCustomFieldValue b/share/html/Admin/Elements/AddCustomFieldValue index ac570db..ec1a34b 100644 --- a/share/html/Admin/Elements/AddCustomFieldValue +++ b/share/html/Admin/Elements/AddCustomFieldValue @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/ConfigureDashboardsInMenu b/share/html/Admin/Elements/ConfigureDashboardsInMenu index 61dc7bd..4fc51d3 100644 --- a/share/html/Admin/Elements/ConfigureDashboardsInMenu +++ b/share/html/Admin/Elements/ConfigureDashboardsInMenu @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/ConfigureMyRT b/share/html/Admin/Elements/ConfigureMyRT index 91e71d2..4be6803 100644 --- a/share/html/Admin/Elements/ConfigureMyRT +++ b/share/html/Admin/Elements/ConfigureMyRT @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditCustomField b/share/html/Admin/Elements/EditCustomField index 4b0647a..17fe9dc 100644 --- a/share/html/Admin/Elements/EditCustomField +++ b/share/html/Admin/Elements/EditCustomField @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditCustomFieldValues b/share/html/Admin/Elements/EditCustomFieldValues index 3271580..5a81ec7 100644 --- a/share/html/Admin/Elements/EditCustomFieldValues +++ b/share/html/Admin/Elements/EditCustomFieldValues @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditCustomFieldValuesSource b/share/html/Admin/Elements/EditCustomFieldValuesSource index 2b30514..3aecf7c 100644 --- a/share/html/Admin/Elements/EditCustomFieldValuesSource +++ b/share/html/Admin/Elements/EditCustomFieldValuesSource @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditCustomFields b/share/html/Admin/Elements/EditCustomFields index 2ca7492..e35d2a2 100644 --- a/share/html/Admin/Elements/EditCustomFields +++ b/share/html/Admin/Elements/EditCustomFields @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditQueueWatcherGroup b/share/html/Admin/Elements/EditQueueWatcherGroup index 56c6490..767bc85 100644 --- a/share/html/Admin/Elements/EditQueueWatcherGroup +++ b/share/html/Admin/Elements/EditQueueWatcherGroup @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditQueueWatchers b/share/html/Admin/Elements/EditQueueWatchers index 4734332..897326a 100644 --- a/share/html/Admin/Elements/EditQueueWatchers +++ b/share/html/Admin/Elements/EditQueueWatchers @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditRights b/share/html/Admin/Elements/EditRights index dc26d0f..046112e 100644 --- a/share/html/Admin/Elements/EditRights +++ b/share/html/Admin/Elements/EditRights @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Elements/EditRightsCategoryTabs b/share/html/Admin/Elements/EditRightsCategoryTabs index 60a5b79..36c5c19 100644 --- a/share/html/Admin/Elements/EditRightsCategoryTabs +++ b/share/html/Admin/Elements/EditRightsCategoryTabs @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) @@ -65,7 +65,8 @@ if ( blessed($Context) and $Context->can('RightCategories') ) { my %right_categories = %{$Context->RightCategories}; for my $right (keys %available_rights) { - push @{$categories{$right_categories{$right}}}, $right; + my $category = $right_categories{$right} || 'Miscellaneous'; # loc + push @{$categories{$category}}, $right; } } @@ -89,15 +90,22 @@ my %category_desc = ( 'Status' => loc('Status changes'), ); -my %catsort = ( General => 1, Staff => 2, Admin => 3, Status => 4 ); +my %catsort = ( General => 1, Staff => 2, Admin => 3, Status => 4, Miscellaneous => 999 ); +my $i = 5; +for my $category ( sort keys %categories ) { + next if $catsort{$category}; + $catsort{$category} = $i++; +} $acldesc ||= join '-', ($Principal ? $Principal->PrincipalId : 'addprincipal'), ref($Context), $Context->Id; + +$available_rights{$_} = loc( $available_rights{$_} ) for keys %available_rights;
% for my $category (sort { $catsort{$a} <=> $catsort{$b} } keys %categories) { @@ -110,10 +118,10 @@ $acldesc ||= join '-', ($Principal ? $Principal->PrincipalId : 'addprincipal'), id="SetRights-<% $acldesc %>-<% $right %>" value="<% $right %>" <% $current_rights{$right} ? 'checked' : '' %> /> -
- - + +
-

Customize the RT theme

+

<&|/l&>Customize the RT theme

  1. @@ -105,14 +105,14 @@
-

Custom CSS (Advanced)

+

<&|/l&>Custom CSS (Advanced)


- - - - + + + +
@@ -138,14 +138,24 @@ jQuery(function($) { .text(v[0])); }); - $("style#sitecss").text($('#user_css').val()); + function update_sitecss(text) { + if (!text) + text = $('#user_css').val(); + + // IE 8 doesn't let us update the innerHTML of ").appendTo('head'); + } + + update_sitecss(); $('#try').click(function() { - $("style#sitecss").text($('#user_css').val()); + update_sitecss(); }); $('#reset').click(function() { setTimeout(function() { - $("style#sitecss").text($('#user_css').val()); + update_sitecss(); }, 1000); }); @@ -181,7 +191,7 @@ jQuery(function($) { } } $('#user_css').val(css); - $("style#sitecss").text(css); + update_sitecss(css); } $('#color-picker').farbtastic(function(color){ change_color(color, this.hsl[2] > <% $text_threshold %> ? '#000' : '#fff') }); diff --git a/share/html/Admin/Tools/index.html b/share/html/Admin/Tools/index.html index d3532bc..458e72e 100644 --- a/share/html/Admin/Tools/index.html +++ b/share/html/Admin/Tools/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/CustomFields.html b/share/html/Admin/Users/CustomFields.html index cca0606..b57cfa5 100644 --- a/share/html/Admin/Users/CustomFields.html +++ b/share/html/Admin/Users/CustomFields.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/DashboardsInMenu.html b/share/html/Admin/Users/DashboardsInMenu.html index 47063e0..b5a41c2 100644 --- a/share/html/Admin/Users/DashboardsInMenu.html +++ b/share/html/Admin/Users/DashboardsInMenu.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/History.html b/share/html/Admin/Users/History.html index 6cf05fb..246c901 100644 --- a/share/html/Admin/Users/History.html +++ b/share/html/Admin/Users/History.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/Keys.html b/share/html/Admin/Users/Keys.html index 9150bed..bf99303 100644 --- a/share/html/Admin/Users/Keys.html +++ b/share/html/Admin/Users/Keys.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/Memberships.html b/share/html/Admin/Users/Memberships.html index 0f71e3a..3f8a57c 100644 --- a/share/html/Admin/Users/Memberships.html +++ b/share/html/Admin/Users/Memberships.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/Modify.html b/share/html/Admin/Users/Modify.html index 2585c8c..ba9379c 100644 --- a/share/html/Admin/Users/Modify.html +++ b/share/html/Admin/Users/Modify.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/Users/MyRT.html b/share/html/Admin/Users/MyRT.html index 7825a69..f22885f 100644 --- a/share/html/Admin/Users/MyRT.html +++ b/share/html/Admin/Users/MyRT.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) @@ -98,7 +98,8 @@ for my $object (@objs) { else { my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id; my $type = ($SearchType eq 'Ticket') - ? 'Saved Search' : $SearchType; # loc + ? 'Saved Search' # loc + : $SearchType; push @items, ["saved-$oid", loc($type).": $loc_desc"]; } } diff --git a/share/html/Admin/Users/index.html b/share/html/Admin/Users/index.html index a0d38df..916a251 100644 --- a/share/html/Admin/Users/index.html +++ b/share/html/Admin/Users/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/autohandler b/share/html/Admin/autohandler index faf7237..73aa47d 100644 --- a/share/html/Admin/autohandler +++ b/share/html/Admin/autohandler @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Admin/index.html b/share/html/Admin/index.html index 20e165d..9d3be92 100644 --- a/share/html/Admin/index.html +++ b/share/html/Admin/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/Display.html b/share/html/Approvals/Display.html index daf0f9d..bb1810c 100644 --- a/share/html/Approvals/Display.html +++ b/share/html/Approvals/Display.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/Elements/Approve b/share/html/Approvals/Elements/Approve index af061d0..5c32f2c 100644 --- a/share/html/Approvals/Elements/Approve +++ b/share/html/Approvals/Elements/Approve @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/Elements/PendingMyApproval b/share/html/Approvals/Elements/PendingMyApproval index a4ec8ae..96d3e86 100644 --- a/share/html/Approvals/Elements/PendingMyApproval +++ b/share/html/Approvals/Elements/PendingMyApproval @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/Elements/ShowDependency b/share/html/Approvals/Elements/ShowDependency index e8cda34..8b5a060 100644 --- a/share/html/Approvals/Elements/ShowDependency +++ b/share/html/Approvals/Elements/ShowDependency @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/autohandler b/share/html/Approvals/autohandler index 8a6df13..c981528 100644 --- a/share/html/Approvals/autohandler +++ b/share/html/Approvals/autohandler @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Approvals/index.html b/share/html/Approvals/index.html index 9afd967..cc964d8 100644 --- a/share/html/Approvals/index.html +++ b/share/html/Approvals/index.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Delete.html b/share/html/Articles/Article/Delete.html index fc695c6..22dc303 100644 --- a/share/html/Articles/Article/Delete.html +++ b/share/html/Articles/Article/Delete.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Display.html b/share/html/Articles/Article/Display.html index 1b455b9..77a1e43 100644 --- a/share/html/Articles/Article/Display.html +++ b/share/html/Articles/Article/Display.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Edit.html b/share/html/Articles/Article/Edit.html index cba9133..609450b 100644 --- a/share/html/Articles/Article/Edit.html +++ b/share/html/Articles/Article/Edit.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/EditBasics b/share/html/Articles/Article/Elements/EditBasics index ab12b39..705cb0d 100644 --- a/share/html/Articles/Article/Elements/EditBasics +++ b/share/html/Articles/Article/Elements/EditBasics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/EditCustomFields b/share/html/Articles/Article/Elements/EditCustomFields index d9f7b4f..e3aaf3e 100644 --- a/share/html/Articles/Article/Elements/EditCustomFields +++ b/share/html/Articles/Article/Elements/EditCustomFields @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/EditLinks b/share/html/Articles/Article/Elements/EditLinks index 24c3e1a..35c8af1 100644 --- a/share/html/Articles/Article/Elements/EditLinks +++ b/share/html/Articles/Article/Elements/EditLinks @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/EditTopics b/share/html/Articles/Article/Elements/EditTopics index e5f9fad..5310301 100644 --- a/share/html/Articles/Article/Elements/EditTopics +++ b/share/html/Articles/Article/Elements/EditTopics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/LinkEntryInstructions b/share/html/Articles/Article/Elements/LinkEntryInstructions index 8e6cc4e..2351263 100644 --- a/share/html/Articles/Article/Elements/LinkEntryInstructions +++ b/share/html/Articles/Article/Elements/LinkEntryInstructions @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/Preformatted b/share/html/Articles/Article/Elements/Preformatted index f77564b..c98b9c5 100644 --- a/share/html/Articles/Article/Elements/Preformatted +++ b/share/html/Articles/Article/Elements/Preformatted @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/SearchByCustomField b/share/html/Articles/Article/Elements/SearchByCustomField index b866986..188995d 100644 --- a/share/html/Articles/Article/Elements/SearchByCustomField +++ b/share/html/Articles/Article/Elements/SearchByCustomField @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/SelectSavedSearches b/share/html/Articles/Article/Elements/SelectSavedSearches index 8bf070a..57ab8d1 100644 --- a/share/html/Articles/Article/Elements/SelectSavedSearches +++ b/share/html/Articles/Article/Elements/SelectSavedSearches @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/SelectSearchPrivacy b/share/html/Articles/Article/Elements/SelectSearchPrivacy index 01bd592..8fa3822 100644 --- a/share/html/Articles/Article/Elements/SelectSearchPrivacy +++ b/share/html/Articles/Article/Elements/SelectSearchPrivacy @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/ShowLinks b/share/html/Articles/Article/Elements/ShowLinks index 4d5aa30..a638736 100644 --- a/share/html/Articles/Article/Elements/ShowLinks +++ b/share/html/Articles/Article/Elements/ShowLinks @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/ShowSavedSearches b/share/html/Articles/Article/Elements/ShowSavedSearches index 4f08d68..9d5f5bf 100644 --- a/share/html/Articles/Article/Elements/ShowSavedSearches +++ b/share/html/Articles/Article/Elements/ShowSavedSearches @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/ShowSearchCriteria b/share/html/Articles/Article/Elements/ShowSearchCriteria index e5b5958..33eccce 100644 --- a/share/html/Articles/Article/Elements/ShowSearchCriteria +++ b/share/html/Articles/Article/Elements/ShowSearchCriteria @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/Elements/ShowTopics b/share/html/Articles/Article/Elements/ShowTopics index 2c805a7..cf62afa 100644 --- a/share/html/Articles/Article/Elements/ShowTopics +++ b/share/html/Articles/Article/Elements/ShowTopics @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/ExtractFromTicket.html b/share/html/Articles/Article/ExtractFromTicket.html index a7b15d6..9d49390 100644 --- a/share/html/Articles/Article/ExtractFromTicket.html +++ b/share/html/Articles/Article/ExtractFromTicket.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) diff --git a/share/html/Articles/Article/ExtractIntoClass.html b/share/html/Articles/Article/ExtractIntoClass.html index b64a5a9..e2ddfcd 100644 --- a/share/html/Articles/Article/ExtractIntoClass.html +++ b/share/html/Articles/Article/ExtractIntoClass.html @@ -2,7 +2,7 @@ %# %# COPYRIGHT: %# -%# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) @@ -55,7 +55,7 @@ % $Classes->LimitToEnabled(); % while (my $Class = $Classes->Next) {
  • <%$Class->Name%>: -<%$Class->Description%> +<%$Class->Description || ''%>