Upgrade to 4.0.10.
authorMikal Kolbein Gule <m.k.gule@usit.uio.no>
Tue, 19 Feb 2013 10:22:21 +0000 (11:22 +0100)
committerMikal Kolbein Gule <m.k.gule@usit.uio.no>
Tue, 19 Feb 2013 10:22:21 +0000 (11:22 +0100)
851 files changed:
bin/rt
bin/rt-mailgate
docs/README
docs/UPGRADING-4.0
docs/customizing/articles_introduction.pod
docs/hacking.pod
docs/web_deployment.pod
etc/RT_Config.pm
lib/RT.pm
lib/RT/ACE.pm
lib/RT/ACL.pm
lib/RT/Action.pm
lib/RT/Action/AutoOpen.pm
lib/RT/Action/Autoreply.pm
lib/RT/Action/CreateTickets.pm
lib/RT/Action/EscalatePriority.pm
lib/RT/Action/ExtractSubjectTag.pm
lib/RT/Action/LinearEscalate.pm
lib/RT/Action/Notify.pm
lib/RT/Action/NotifyAsComment.pm
lib/RT/Action/NotifyGroup.pm
lib/RT/Action/NotifyGroupAsComment.pm
lib/RT/Action/RecordComment.pm
lib/RT/Action/RecordCorrespondence.pm
lib/RT/Action/SendEmail.pm
lib/RT/Action/SetPriority.pm
lib/RT/Action/SetStatus.pm
lib/RT/Action/UserDefined.pm
lib/RT/Approval.pm
lib/RT/Approval/Rule.pm
lib/RT/Approval/Rule/Created.pm
lib/RT/Approval/Rule/NewPending.pm
lib/RT/Approval/Rule/Passed.pm
lib/RT/Approval/Rule/Rejected.pm
lib/RT/Article.pm
lib/RT/Articles.pm
lib/RT/Attachment.pm
lib/RT/Attachments.pm
lib/RT/Attribute.pm
lib/RT/Attributes.pm
lib/RT/Base.pm
lib/RT/CachedGroupMember.pm
lib/RT/CachedGroupMembers.pm
lib/RT/Class.pm
lib/RT/Classes.pm
lib/RT/Condition.pm
lib/RT/Condition/AnyTransaction.pm
lib/RT/Condition/BeforeDue.pm
lib/RT/Condition/CloseTicket.pm
lib/RT/Condition/Overdue.pm
lib/RT/Condition/OwnerChange.pm
lib/RT/Condition/PriorityChange.pm
lib/RT/Condition/PriorityExceeds.pm
lib/RT/Condition/QueueChange.pm
lib/RT/Condition/ReopenTicket.pm
lib/RT/Condition/StatusChange.pm
lib/RT/Condition/UserDefined.pm
lib/RT/Config.pm
lib/RT/Crypt/GnuPG.pm
lib/RT/CurrentUser.pm
lib/RT/CustomField.pm
lib/RT/CustomFieldValue.pm
lib/RT/CustomFieldValues.pm
lib/RT/CustomFieldValues/External.pm
lib/RT/CustomFieldValues/Groups.pm
lib/RT/CustomFields.pm
lib/RT/Dashboard.pm
lib/RT/Dashboard/Mailer.pm
lib/RT/Dashboards.pm
lib/RT/Date.pm
lib/RT/EmailParser.pm
lib/RT/Generated.pm
lib/RT/Generated.pm.in
lib/RT/Graph/Tickets.pm
lib/RT/Group.pm
lib/RT/GroupMember.pm
lib/RT/GroupMembers.pm
lib/RT/Groups.pm
lib/RT/Handle.pm
lib/RT/I18N.pm
lib/RT/I18N/cs.pm
lib/RT/I18N/i_default.pm
lib/RT/I18N/ru.pm
lib/RT/Installer.pm
lib/RT/Interface/CLI.pm
lib/RT/Interface/Email.pm
lib/RT/Interface/Email/Auth/GnuPG.pm
lib/RT/Interface/Email/Auth/MailFrom.pm
lib/RT/Interface/REST.pm
lib/RT/Interface/Web.pm
lib/RT/Interface/Web/Handler.pm
lib/RT/Interface/Web/Menu.pm
lib/RT/Interface/Web/QueryBuilder.pm
lib/RT/Interface/Web/QueryBuilder/Tree.pm
lib/RT/Interface/Web/Request.pm
lib/RT/Interface/Web/Session.pm
lib/RT/Lifecycle.pm
lib/RT/Link.pm
lib/RT/Links.pm
lib/RT/ObjectClass.pm
lib/RT/ObjectClasses.pm
lib/RT/ObjectCustomField.pm
lib/RT/ObjectCustomFieldValue.pm
lib/RT/ObjectCustomFieldValues.pm
lib/RT/ObjectCustomFields.pm
lib/RT/ObjectTopic.pm
lib/RT/ObjectTopics.pm
lib/RT/Plugin.pm
lib/RT/Pod/HTML.pm
lib/RT/Pod/HTMLBatch.pm
lib/RT/Pod/Search.pm
lib/RT/Principal.pm
lib/RT/Principals.pm
lib/RT/Queue.pm
lib/RT/Queues.pm
lib/RT/Record.pm
lib/RT/Reminders.pm
lib/RT/Report/Tickets.pm
lib/RT/Report/Tickets/Entry.pm
lib/RT/Rule.pm
lib/RT/Ruleset.pm
lib/RT/SQL.pm
lib/RT/SavedSearch.pm
lib/RT/SavedSearches.pm
lib/RT/Scrip.pm
lib/RT/ScripAction.pm
lib/RT/ScripActions.pm
lib/RT/ScripCondition.pm
lib/RT/ScripConditions.pm
lib/RT/Scrips.pm
lib/RT/Search.pm
lib/RT/Search/ActiveTicketsInQueue.pm
lib/RT/Search/FromSQL.pm
lib/RT/Search/Googleish.pm
lib/RT/SearchBuilder.pm
lib/RT/SharedSetting.pm
lib/RT/SharedSettings.pm
lib/RT/Shredder.pm
lib/RT/Shredder/ACE.pm
lib/RT/Shredder/Attachment.pm
lib/RT/Shredder/CachedGroupMember.pm
lib/RT/Shredder/Constants.pm
lib/RT/Shredder/CustomField.pm
lib/RT/Shredder/CustomFieldValue.pm
lib/RT/Shredder/Dependencies.pm
lib/RT/Shredder/Dependency.pm
lib/RT/Shredder/Exceptions.pm
lib/RT/Shredder/Group.pm
lib/RT/Shredder/GroupMember.pm
lib/RT/Shredder/Link.pm
lib/RT/Shredder/ObjectCustomFieldValue.pm
lib/RT/Shredder/POD.pm
lib/RT/Shredder/Plugin.pm
lib/RT/Shredder/Plugin/Attachments.pm
lib/RT/Shredder/Plugin/Base.pm
lib/RT/Shredder/Plugin/Base/Dump.pm
lib/RT/Shredder/Plugin/Base/Search.pm
lib/RT/Shredder/Plugin/Objects.pm
lib/RT/Shredder/Plugin/SQLDump.pm
lib/RT/Shredder/Plugin/Summary.pm
lib/RT/Shredder/Plugin/Tickets.pm
lib/RT/Shredder/Plugin/Users.pm
lib/RT/Shredder/Principal.pm
lib/RT/Shredder/Queue.pm
lib/RT/Shredder/Record.pm
lib/RT/Shredder/Scrip.pm
lib/RT/Shredder/ScripAction.pm
lib/RT/Shredder/ScripCondition.pm
lib/RT/Shredder/Template.pm
lib/RT/Shredder/Ticket.pm
lib/RT/Shredder/Transaction.pm
lib/RT/Shredder/User.pm
lib/RT/Squish.pm
lib/RT/Squish/CSS.pm
lib/RT/Squish/JS.pm
lib/RT/System.pm
lib/RT/Template.pm
lib/RT/Templates.pm
lib/RT/Test.pm
lib/RT/Test/Apache.pm
lib/RT/Test/Email.pm
lib/RT/Test/GnuPG.pm
lib/RT/Test/Web.pm
lib/RT/Ticket.pm
lib/RT/Tickets.pm
lib/RT/Tickets_SQL.pm
lib/RT/Topic.pm
lib/RT/Topics.pm
lib/RT/Transaction.pm
lib/RT/Transactions.pm
lib/RT/URI.pm
lib/RT/URI/a.pm
lib/RT/URI/base.pm
lib/RT/URI/fsck_com_article.pm
lib/RT/URI/fsck_com_rt.pm
lib/RT/URI/t.pm
lib/RT/User.pm
lib/RT/Users.pm
lib/RT/Util.pm
sbin/rt-attributes-viewer
sbin/rt-clean-sessions
sbin/rt-dump-metadata
sbin/rt-email-dashboards
sbin/rt-email-digest
sbin/rt-email-group-admin
sbin/rt-fulltext-indexer
sbin/rt-preferences-viewer
sbin/rt-server
sbin/rt-server.fcgi
sbin/rt-session-viewer
sbin/rt-setup-database
sbin/rt-setup-fulltext-index
sbin/rt-shredder
sbin/rt-test-dependencies
sbin/rt-validate-aliases
sbin/rt-validator
sbin/standalone_httpd
share/html/Admin/Articles/Classes/CustomFields.html
share/html/Admin/Articles/Classes/GroupRights.html
share/html/Admin/Articles/Classes/Modify.html
share/html/Admin/Articles/Classes/Objects.html
share/html/Admin/Articles/Classes/Topics.html
share/html/Admin/Articles/Classes/UserRights.html
share/html/Admin/Articles/Classes/index.html
share/html/Admin/Articles/Elements/Topics
share/html/Admin/Articles/index.html
share/html/Admin/CustomFields/GroupRights.html
share/html/Admin/CustomFields/Modify.html
share/html/Admin/CustomFields/Objects.html
share/html/Admin/CustomFields/UserRights.html
share/html/Admin/CustomFields/index.html
share/html/Admin/Elements/AddCustomFieldValue
share/html/Admin/Elements/ConfigureMyRT
share/html/Admin/Elements/CreateUserCalled
share/html/Admin/Elements/EditCustomField
share/html/Admin/Elements/EditCustomFieldValues
share/html/Admin/Elements/EditCustomFieldValuesSource
share/html/Admin/Elements/EditCustomFields
share/html/Admin/Elements/EditQueueWatcherGroup
share/html/Admin/Elements/EditQueueWatchers
share/html/Admin/Elements/EditRights
share/html/Admin/Elements/EditRightsCategoryTabs
share/html/Admin/Elements/EditScrip
share/html/Admin/Elements/EditScrips
share/html/Admin/Elements/EditTemplates
share/html/Admin/Elements/EditUserComments
share/html/Admin/Elements/Header
share/html/Admin/Elements/ListGlobalCustomFields
share/html/Admin/Elements/ListGlobalScrips
share/html/Admin/Elements/ModifyTemplate
share/html/Admin/Elements/PickCustomFields
share/html/Admin/Elements/PickObjects
share/html/Admin/Elements/Portal
share/html/Admin/Elements/QueueRightsForUser
share/html/Admin/Elements/SelectCustomField
share/html/Admin/Elements/SelectCustomFieldLookupType
share/html/Admin/Elements/SelectCustomFieldRenderType
share/html/Admin/Elements/SelectCustomFieldType
share/html/Admin/Elements/SelectGroups
share/html/Admin/Elements/SelectModifyGroup
share/html/Admin/Elements/SelectModifyQueue
share/html/Admin/Elements/SelectModifyUser
share/html/Admin/Elements/SelectNewGroupMembers
share/html/Admin/Elements/SelectRights
share/html/Admin/Elements/SelectScrip
share/html/Admin/Elements/SelectScripAction
share/html/Admin/Elements/SelectScripCondition
share/html/Admin/Elements/SelectSingleOrMultiple
share/html/Admin/Elements/SelectStage
share/html/Admin/Elements/SelectTemplate
share/html/Admin/Elements/SelectUsers
share/html/Admin/Elements/ShowKeyInfo
share/html/Admin/Global/CustomFields/Class-Article.html
share/html/Admin/Global/CustomFields/Groups.html
share/html/Admin/Global/CustomFields/Queue-Tickets.html
share/html/Admin/Global/CustomFields/Queue-Transactions.html
share/html/Admin/Global/CustomFields/Queues.html
share/html/Admin/Global/CustomFields/Users.html
share/html/Admin/Global/CustomFields/index.html
share/html/Admin/Global/GroupRights.html
share/html/Admin/Global/MyRT.html
share/html/Admin/Global/Scrip.html
share/html/Admin/Global/Scrips.html
share/html/Admin/Global/Template.html
share/html/Admin/Global/Templates.html
share/html/Admin/Global/Topics.html
share/html/Admin/Global/UserRights.html
share/html/Admin/Global/index.html
share/html/Admin/Groups/GroupRights.html
share/html/Admin/Groups/History.html
share/html/Admin/Groups/Members.html
share/html/Admin/Groups/Modify.html
share/html/Admin/Groups/UserRights.html
share/html/Admin/Groups/index.html
share/html/Admin/Queues/CustomField.html
share/html/Admin/Queues/CustomFields.html
share/html/Admin/Queues/GroupRights.html
share/html/Admin/Queues/History.html
share/html/Admin/Queues/Modify.html
share/html/Admin/Queues/People.html
share/html/Admin/Queues/Scrip.html
share/html/Admin/Queues/Scrips.html
share/html/Admin/Queues/Template.html
share/html/Admin/Queues/Templates.html
share/html/Admin/Queues/UserRights.html
share/html/Admin/Queues/index.html
share/html/Admin/Tools/Configuration.html
share/html/Admin/Tools/Queries.html
share/html/Admin/Tools/Shredder/Dumps/dhandler
share/html/Admin/Tools/Shredder/Elements/DumpFileLink
share/html/Admin/Tools/Shredder/Elements/Error/NoRights
share/html/Admin/Tools/Shredder/Elements/Error/NoStorage
share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment
share/html/Admin/Tools/Shredder/Elements/Object/RT--Ticket
share/html/Admin/Tools/Shredder/Elements/Object/RT--User
share/html/Admin/Tools/Shredder/Elements/ObjectCheckBox
share/html/Admin/Tools/Shredder/Elements/PluginArguments
share/html/Admin/Tools/Shredder/Elements/PluginHelp
share/html/Admin/Tools/Shredder/Elements/SelectObjects
share/html/Admin/Tools/Shredder/Elements/SelectPlugin
share/html/Admin/Tools/Shredder/autohandler
share/html/Admin/Tools/Shredder/index.html
share/html/Admin/Tools/Theme.html
share/html/Admin/Tools/index.html
share/html/Admin/Users/CustomFields.html
share/html/Admin/Users/GnuPG.html
share/html/Admin/Users/History.html
share/html/Admin/Users/Memberships.html
share/html/Admin/Users/Modify.html
share/html/Admin/Users/MyRT.html
share/html/Admin/Users/index.html
share/html/Admin/autohandler
share/html/Admin/index.html
share/html/Approvals/Display.html
share/html/Approvals/Elements/Approve
share/html/Approvals/Elements/PendingMyApproval
share/html/Approvals/Elements/ShowDependency
share/html/Approvals/autohandler
share/html/Approvals/index.html
share/html/Articles/Article/Delete.html
share/html/Articles/Article/Display.html
share/html/Articles/Article/Edit.html
share/html/Articles/Article/Elements/EditBasics
share/html/Articles/Article/Elements/EditCustomFields
share/html/Articles/Article/Elements/EditLinks
share/html/Articles/Article/Elements/EditTopics
share/html/Articles/Article/Elements/LinkEntryInstructions
share/html/Articles/Article/Elements/Preformatted
share/html/Articles/Article/Elements/SearchByCustomField
share/html/Articles/Article/Elements/SelectSavedSearches
share/html/Articles/Article/Elements/SelectSearchPrivacy
share/html/Articles/Article/Elements/ShowHistory
share/html/Articles/Article/Elements/ShowLinks
share/html/Articles/Article/Elements/ShowSavedSearches
share/html/Articles/Article/Elements/ShowSearchCriteria
share/html/Articles/Article/Elements/ShowTopics
share/html/Articles/Article/ExtractFromTicket.html
share/html/Articles/Article/ExtractIntoClass.html
share/html/Articles/Article/ExtractIntoTopic.html
share/html/Articles/Article/History.html
share/html/Articles/Article/PreCreate.html
share/html/Articles/Article/Search.html
share/html/Articles/Elements/BeforeMessageBox
share/html/Articles/Elements/CheckSkipCreate
share/html/Articles/Elements/CreateArticle
share/html/Articles/Elements/GotoArticle
share/html/Articles/Elements/IncludeArticle
share/html/Articles/Elements/NewestArticles
share/html/Articles/Elements/QuickSearch
share/html/Articles/Elements/SelectClass
share/html/Articles/Elements/ShowTopic
share/html/Articles/Elements/ShowTopicLink
share/html/Articles/Elements/UpdatedArticles
share/html/Articles/Topics.html
share/html/Articles/index.html
share/html/Dashboards/Elements/DashboardsForObject
share/html/Dashboards/Elements/Deleted
share/html/Dashboards/Elements/HiddenSearches
share/html/Dashboards/Elements/ListOfDashboards
share/html/Dashboards/Elements/SelectPrivacy
share/html/Dashboards/Elements/ShowDashboards
share/html/Dashboards/Elements/ShowPortlet/component
share/html/Dashboards/Elements/ShowPortlet/dashboard
share/html/Dashboards/Elements/ShowPortlet/search
share/html/Dashboards/Modify.html
share/html/Dashboards/Queries.html
share/html/Dashboards/Render.html
share/html/Dashboards/Subscription.html
share/html/Dashboards/dhandler
share/html/Dashboards/index.html
share/html/Download/CustomFieldValue/dhandler
share/html/Elements/BevelBoxRaisedEnd
share/html/Elements/BevelBoxRaisedStart
share/html/Elements/CSRF
share/html/Elements/Callback
share/html/Elements/Checkbox
share/html/Elements/CollectionAsTable/Header
share/html/Elements/CollectionAsTable/ParseFormat
share/html/Elements/CollectionAsTable/Row
share/html/Elements/CollectionList
share/html/Elements/CollectionListPaging
share/html/Elements/ColumnMap
share/html/Elements/CreateTicket
share/html/Elements/Dashboards
share/html/Elements/EditCustomField
share/html/Elements/EditCustomFieldAutocomplete
share/html/Elements/EditCustomFieldBinary
share/html/Elements/EditCustomFieldCombobox
share/html/Elements/EditCustomFieldDate
share/html/Elements/EditCustomFieldDateTime
share/html/Elements/EditCustomFieldFreeform
share/html/Elements/EditCustomFieldIPAddress
share/html/Elements/EditCustomFieldIPAddressRange
share/html/Elements/EditCustomFieldImage
share/html/Elements/EditCustomFieldSelect
share/html/Elements/EditCustomFieldText
share/html/Elements/EditCustomFieldWikitext
share/html/Elements/EditLinks
share/html/Elements/EditPassword
share/html/Elements/EditTimeValue
share/html/Elements/EmailInput
share/html/Elements/Error
share/html/Elements/Footer
share/html/Elements/Framekiller
share/html/Elements/GnuPG/KeyIssues
share/html/Elements/GnuPG/SelectKeyForEncryption
share/html/Elements/GnuPG/SelectKeyForSigning
share/html/Elements/GnuPG/SignEncryptWidget
share/html/Elements/GotoTicket
share/html/Elements/Header
share/html/Elements/HeaderJavascript
share/html/Elements/ListActions
share/html/Elements/ListMenu
share/html/Elements/Login
share/html/Elements/LoginRedirectWarning
share/html/Elements/Logo
share/html/Elements/MakeClicky
share/html/Elements/Menu
share/html/Elements/MessageBox
share/html/Elements/MyAdminQueues
share/html/Elements/MyRT
share/html/Elements/MyReminders
share/html/Elements/MyRequests
share/html/Elements/MySupportQueues
share/html/Elements/MyTickets
share/html/Elements/PageLayout
share/html/Elements/PersonalQuickbar
share/html/Elements/QueriesAsComment
share/html/Elements/QueryString
share/html/Elements/QueueSummaryByLifecycle
share/html/Elements/QueueSummaryByStatus
share/html/Elements/QuickCreate
share/html/Elements/Quicksearch
share/html/Elements/RT__Article/ColumnMap
share/html/Elements/RT__Class/ColumnMap
share/html/Elements/RT__CustomField/ColumnMap
share/html/Elements/RT__Dashboard/ColumnMap
share/html/Elements/RT__Group/ColumnMap
share/html/Elements/RT__Queue/ColumnMap
share/html/Elements/RT__SavedSearch/ColumnMap
share/html/Elements/RT__Scrip/ColumnMap
share/html/Elements/RT__Template/ColumnMap
share/html/Elements/RT__Ticket/ColumnMap
share/html/Elements/RT__User/ColumnMap
share/html/Elements/Refresh
share/html/Elements/RefreshHomepage
share/html/Elements/SavedSearches
share/html/Elements/ScrubHTML
share/html/Elements/Section
share/html/Elements/SelectAttachmentField
share/html/Elements/SelectBoolean
share/html/Elements/SelectCustomFieldOperator
share/html/Elements/SelectCustomFieldValue
share/html/Elements/SelectDate
share/html/Elements/SelectDateRelation
share/html/Elements/SelectDateType
share/html/Elements/SelectEqualityOperator
share/html/Elements/SelectGroups
share/html/Elements/SelectIPRelation
share/html/Elements/SelectLang
share/html/Elements/SelectLinkType
share/html/Elements/SelectMatch
share/html/Elements/SelectNewTicketQueue
share/html/Elements/SelectOwner
share/html/Elements/SelectOwnerAutocomplete
share/html/Elements/SelectOwnerDropdown
share/html/Elements/SelectPriority
share/html/Elements/SelectQueue
share/html/Elements/SelectResultsPerPage
share/html/Elements/SelectSortOrder
share/html/Elements/SelectStatus
share/html/Elements/SelectTicketSortBy
share/html/Elements/SelectTicketTypes
share/html/Elements/SelectTimeUnits
share/html/Elements/SelectTimezone
share/html/Elements/SelectUsers
share/html/Elements/SelectWatcherType
share/html/Elements/SetupSessionCookie
share/html/Elements/ShowCustomFieldBinary
share/html/Elements/ShowCustomFieldDate
share/html/Elements/ShowCustomFieldDateTime
share/html/Elements/ShowCustomFieldImage
share/html/Elements/ShowCustomFieldText
share/html/Elements/ShowCustomFieldWikitext
share/html/Elements/ShowCustomFields
share/html/Elements/ShowLink
share/html/Elements/ShowLinks
share/html/Elements/ShowMemberships
share/html/Elements/ShowRelationLabel
share/html/Elements/ShowReminders
share/html/Elements/ShowSearch
share/html/Elements/ShowUser
share/html/Elements/ShowUserConcise
share/html/Elements/ShowUserEmailFrequency
share/html/Elements/ShowUserVerbose
share/html/Elements/SimpleSearch
share/html/Elements/Submit
share/html/Elements/Tabs
share/html/Elements/TicketList
share/html/Elements/TitleBox
share/html/Elements/TitleBoxEnd
share/html/Elements/TitleBoxStart
share/html/Elements/ValidateCustomFields
share/html/Elements/WidgetBar
share/html/Helpers/Autocomplete/CustomFieldValues
share/html/Helpers/Autocomplete/Groups
share/html/Helpers/Autocomplete/Owners
share/html/Helpers/Autocomplete/Users
share/html/Helpers/TicketHistory
share/html/Helpers/Toggle/ShowRequestor
share/html/Helpers/Toggle/TicketBookmark
share/html/Install/Basics.html
share/html/Install/DatabaseDetails.html
share/html/Install/DatabaseType.html
share/html/Install/Elements/Errors
share/html/Install/Elements/Wrapper
share/html/Install/Finish.html
share/html/Install/Global.html
share/html/Install/Initialize.html
share/html/Install/Sendmail.html
share/html/Install/autohandler
share/html/Install/index.html
share/html/NoAuth/Helpers/CustomLogo/dhandler
share/html/NoAuth/Login.html
share/html/NoAuth/Logout.html
share/html/NoAuth/Reminder.html
share/html/NoAuth/RichText/autohandler
share/html/NoAuth/RichText/dhandler
share/html/NoAuth/css/aileron/InHeader
share/html/NoAuth/css/aileron/base.css
share/html/NoAuth/css/aileron/boxes.css
share/html/NoAuth/css/aileron/forms.css
share/html/NoAuth/css/aileron/images/dhandler
share/html/NoAuth/css/aileron/layout.css
share/html/NoAuth/css/aileron/login.css
share/html/NoAuth/css/aileron/main.css
share/html/NoAuth/css/aileron/misc.css
share/html/NoAuth/css/aileron/msie.css
share/html/NoAuth/css/aileron/msie6.css
share/html/NoAuth/css/aileron/nav.css
share/html/NoAuth/css/aileron/ticket-lists.css
share/html/NoAuth/css/aileron/ticket-search.css
share/html/NoAuth/css/aileron/ticket.css
share/html/NoAuth/css/autohandler
share/html/NoAuth/css/ballard/InHeader
share/html/NoAuth/css/ballard/base.css
share/html/NoAuth/css/ballard/boxes.css
share/html/NoAuth/css/ballard/images/dhandler
share/html/NoAuth/css/ballard/layout.css
share/html/NoAuth/css/ballard/main.css
share/html/NoAuth/css/ballard/misc.css
share/html/NoAuth/css/ballard/msie.css
share/html/NoAuth/css/ballard/msie6.css
share/html/NoAuth/css/ballard/nav.css
share/html/NoAuth/css/ballard/ticket-lists.css
share/html/NoAuth/css/ballard/ticket-search.css
share/html/NoAuth/css/ballard/ticket.css
share/html/NoAuth/css/base/admin.css
share/html/NoAuth/css/base/articles.css
share/html/NoAuth/css/base/collection.css
share/html/NoAuth/css/base/forms.css
share/html/NoAuth/css/base/history-folding.css
share/html/NoAuth/css/base/jquery-ui-timepicker-addon.css
share/html/NoAuth/css/base/jquery-ui.css
share/html/NoAuth/css/base/login.css
share/html/NoAuth/css/base/main.css
share/html/NoAuth/css/base/misc.css
share/html/NoAuth/css/base/nav.css
share/html/NoAuth/css/base/portlets.css
share/html/NoAuth/css/base/rights-editor.css
share/html/NoAuth/css/base/theme-editor.css
share/html/NoAuth/css/base/ticket-form.css
share/html/NoAuth/css/base/ticket.css
share/html/NoAuth/css/base/tools.css
share/html/NoAuth/css/dhandler
share/html/NoAuth/css/print.css
share/html/NoAuth/css/web2/InHeader
share/html/NoAuth/css/web2/base.css
share/html/NoAuth/css/web2/boxes.css
share/html/NoAuth/css/web2/images/dhandler
share/html/NoAuth/css/web2/layout.css
share/html/NoAuth/css/web2/main.css
share/html/NoAuth/css/web2/misc.css
share/html/NoAuth/css/web2/msie.css
share/html/NoAuth/css/web2/msie6.css
share/html/NoAuth/css/web2/nav.css
share/html/NoAuth/css/web2/ticket-lists.css
share/html/NoAuth/css/web2/ticket-search.css
share/html/NoAuth/css/web2/ticket.css
share/html/NoAuth/iCal/dhandler
share/html/NoAuth/images/autohandler
share/html/NoAuth/js/autohandler
share/html/NoAuth/js/cascaded.js
share/html/NoAuth/js/combobox.js
share/html/NoAuth/js/dhandler
share/html/NoAuth/js/history-folding.js
share/html/NoAuth/js/jquery-ui-patch-datepicker.js
share/html/NoAuth/js/jquery_noconflict.js
share/html/NoAuth/js/late.js
share/html/NoAuth/js/titlebox-state.js
share/html/NoAuth/js/userautocomplete.js
share/html/NoAuth/js/util.js
share/html/NoAuth/rss/dhandler
share/html/Prefs/MyRT.html
share/html/Prefs/Other.html
share/html/Prefs/Quicksearch.html
share/html/Prefs/Search.html
share/html/Prefs/SearchOptions.html
share/html/REST/1.0/Forms/attachment/default
share/html/REST/1.0/Forms/group/customfields
share/html/REST/1.0/Forms/group/default
share/html/REST/1.0/Forms/group/ns
share/html/REST/1.0/Forms/queue/customfields
share/html/REST/1.0/Forms/queue/default
share/html/REST/1.0/Forms/queue/ns
share/html/REST/1.0/Forms/queue/ticketcustomfields
share/html/REST/1.0/Forms/ticket/attachments
share/html/REST/1.0/Forms/ticket/comment
share/html/REST/1.0/Forms/ticket/default
share/html/REST/1.0/Forms/ticket/history
share/html/REST/1.0/Forms/ticket/links
share/html/REST/1.0/Forms/ticket/merge
share/html/REST/1.0/Forms/ticket/take
share/html/REST/1.0/Forms/transaction/default
share/html/REST/1.0/Forms/user/default
share/html/REST/1.0/Forms/user/ns
share/html/REST/1.0/NoAuth/mail-gateway
share/html/REST/1.0/autohandler
share/html/REST/1.0/dhandler
share/html/REST/1.0/logout
share/html/REST/1.0/search/dhandler
share/html/REST/1.0/search/ticket
share/html/REST/1.0/ticket/comment
share/html/REST/1.0/ticket/link
share/html/REST/1.0/ticket/merge
share/html/Search/Article.html
share/html/Search/Build.html
share/html/Search/Bulk.html
share/html/Search/Chart
share/html/Search/Chart.html
share/html/Search/Edit.html
share/html/Search/Elements/Article
share/html/Search/Elements/BuildFormatString
share/html/Search/Elements/Chart
share/html/Search/Elements/ConditionRow
share/html/Search/Elements/DisplayOptions
share/html/Search/Elements/EditFormat
share/html/Search/Elements/EditQuery
share/html/Search/Elements/EditSearches
share/html/Search/Elements/EditSort
share/html/Search/Elements/Graph
share/html/Search/Elements/NewListActions
share/html/Search/Elements/PickBasics
share/html/Search/Elements/PickCFs
share/html/Search/Elements/PickCriteria
share/html/Search/Elements/ResultsRSSView
share/html/Search/Elements/SearchPrivacy
share/html/Search/Elements/SearchesForObject
share/html/Search/Elements/SelectAndOr
share/html/Search/Elements/SelectChartType
share/html/Search/Elements/SelectGroup
share/html/Search/Elements/SelectGroupBy
share/html/Search/Elements/SelectLinks
share/html/Search/Elements/SelectPersonType
share/html/Search/Elements/SelectSearchObject
share/html/Search/Elements/SelectSearchesForObjects
share/html/Search/Graph.html
share/html/Search/Results.html
share/html/Search/Results.rdf
share/html/Search/Results.tsv
share/html/Search/Simple.html
share/html/SelfService/Article/Display.html
share/html/SelfService/Article/Search.html
share/html/SelfService/Article/autohandler
share/html/SelfService/Attachment/dhandler
share/html/SelfService/Closed.html
share/html/SelfService/Create.html
share/html/SelfService/CreateTicketInQueue.html
share/html/SelfService/Display.html
share/html/SelfService/Elements/GotoTicket
share/html/SelfService/Elements/Header
share/html/SelfService/Elements/MyRequests
share/html/SelfService/Elements/SearchArticle
share/html/SelfService/Error.html
share/html/SelfService/Prefs.html
share/html/SelfService/Update.html
share/html/SelfService/index.html
share/html/Ticket/Attachment/WithHeaders/dhandler
share/html/Ticket/Attachment/dhandler
share/html/Ticket/Create.html
share/html/Ticket/Display.html
share/html/Ticket/Elements/AddAttachments
share/html/Ticket/Elements/AddWatchers
share/html/Ticket/Elements/Bookmark
share/html/Ticket/Elements/BulkLinks
share/html/Ticket/Elements/ClickToShowHistory
share/html/Ticket/Elements/EditBasics
share/html/Ticket/Elements/EditCustomFields
share/html/Ticket/Elements/EditDates
share/html/Ticket/Elements/EditPeople
share/html/Ticket/Elements/EditTransactionCustomFields
share/html/Ticket/Elements/EditWatchers
share/html/Ticket/Elements/FindAttachments
share/html/Ticket/Elements/FindTransactions
share/html/Ticket/Elements/FoldStanzaJS
share/html/Ticket/Elements/LoadTextAttachments
share/html/Ticket/Elements/PreviewScrips
share/html/Ticket/Elements/Reminders
share/html/Ticket/Elements/ShowAttachments
share/html/Ticket/Elements/ShowBasics
share/html/Ticket/Elements/ShowCustomFields
share/html/Ticket/Elements/ShowDates
share/html/Ticket/Elements/ShowDependencies
share/html/Ticket/Elements/ShowGnuPGStatus
share/html/Ticket/Elements/ShowGroupMembers
share/html/Ticket/Elements/ShowHistory
share/html/Ticket/Elements/ShowMembers
share/html/Ticket/Elements/ShowMessageHeaders
share/html/Ticket/Elements/ShowMessageStanza
share/html/Ticket/Elements/ShowParents
share/html/Ticket/Elements/ShowPeople
share/html/Ticket/Elements/ShowPriority
share/html/Ticket/Elements/ShowQueue
share/html/Ticket/Elements/ShowRequestor
share/html/Ticket/Elements/ShowRequestorExtraInfo
share/html/Ticket/Elements/ShowRequestorTickets
share/html/Ticket/Elements/ShowRequestorTicketsActive
share/html/Ticket/Elements/ShowRequestorTicketsAll
share/html/Ticket/Elements/ShowRequestorTicketsInactive
share/html/Ticket/Elements/ShowSimplifiedRecipients
share/html/Ticket/Elements/ShowSummary
share/html/Ticket/Elements/ShowTime
share/html/Ticket/Elements/ShowTransaction
share/html/Ticket/Elements/ShowTransactionAttachments
share/html/Ticket/Elements/ShowUpdateStatus
share/html/Ticket/Elements/ShowUserEntry
share/html/Ticket/Elements/UpdateCc
share/html/Ticket/Forward.html
share/html/Ticket/GnuPG.html
share/html/Ticket/Graphs/Elements/EditGraphProperties
share/html/Ticket/Graphs/Elements/ShowGraph
share/html/Ticket/Graphs/Elements/ShowLegends
share/html/Ticket/Graphs/dhandler
share/html/Ticket/Graphs/index.html
share/html/Ticket/History.html
share/html/Ticket/Modify.html
share/html/Ticket/ModifyAll.html
share/html/Ticket/ModifyDates.html
share/html/Ticket/ModifyLinks.html
share/html/Ticket/ModifyPeople.html
share/html/Ticket/Reminders.html
share/html/Ticket/ShowEmailRecord.html
share/html/Ticket/Update.html
share/html/Ticket/autohandler
share/html/Tools/MyDay.html
share/html/Tools/MyReminders.html
share/html/Tools/Offline.html
share/html/Tools/index.html
share/html/User/Prefs.html
share/html/Widgets/BulkEdit
share/html/Widgets/BulkProcess
share/html/Widgets/ComboBox
share/html/Widgets/FinalizeWidgetArguments
share/html/Widgets/Form/Boolean
share/html/Widgets/Form/Integer
share/html/Widgets/Form/Select
share/html/Widgets/Form/String
share/html/Widgets/SavedSearch
share/html/Widgets/SelectionBox
share/html/Widgets/TitleBox
share/html/Widgets/TitleBoxEnd
share/html/Widgets/TitleBoxStart
share/html/autohandler
share/html/dhandler
share/html/index.html
share/html/l
share/html/l_unsafe
share/html/m/_elements/footer
share/html/m/_elements/full_site_link
share/html/m/_elements/header
share/html/m/_elements/menu
share/html/m/_elements/raw_style
share/html/m/_elements/ticket_list
share/html/m/_elements/ticket_menu
share/html/m/_elements/wrapper
share/html/m/dhandler
share/html/m/index.html
share/html/m/logout
share/html/m/style.css
share/html/m/ticket/autohandler
share/html/m/ticket/create
share/html/m/ticket/history
share/html/m/ticket/reply
share/html/m/ticket/select_create_queue
share/html/m/ticket/show
share/html/m/tickets/search
share/po/bg.po
share/po/cs.po
share/po/da.po
share/po/de.po
share/po/el.po
share/po/en.po
share/po/en_GB.po
share/po/es.po
share/po/et.po
share/po/fi.po
share/po/fr.po
share/po/he.po
share/po/hr.po
share/po/hu.po
share/po/id.po
share/po/is.po
share/po/it.po
share/po/ja.po
share/po/lt.po
share/po/lv.po
share/po/mk.po
share/po/nb.po
share/po/nl.po
share/po/nn.po
share/po/pl.po
share/po/pt.po
share/po/pt_BR.po
share/po/pt_PT.po
share/po/rt.pot
share/po/ru.po
share/po/sl.po
share/po/sv.po
share/po/tr.po
share/po/zh_CN.po
share/po/zh_TW.po

diff --git a/bin/rt b/bin/rt
index bc2fde0..87aac38 100755 (executable)
--- a/bin/rt
+++ b/bin/rt
@@ -3,7 +3,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -50,6 +50,7 @@
 # Abhijit Menon-Sen <ams@wiw.org>
 
 use strict;
+use warnings;
 
 if ( $ARGV[0] && $ARGV[0] =~ /^(?:--help|-h)$/ ) {
     require Pod::Usage;
@@ -119,9 +120,9 @@ sub DEBUG { warn @_ if $config{debug} >= shift }
 # (XXX: Ask Autrijus how i18n changes these definitions.)
 
 my $name    = '[\w.-]+';
-my $CF_name = '[\sa-z0-9_ :()/-]+';
+my $CF_name = '[^,]+?';
 my $field   = '(?i:[a-z][a-z0-9_-]*|C(?:ustom)?F(?:ield)?-'.$CF_name.'|CF\.\{'.$CF_name.'\})';
-my $label   = '[a-zA-Z0-9@_.+-]+';
+my $label   = '[^,\\/]+';
 my $labels  = "(?:$label,)*$label";
 my $idlist  = '(?:(?:\d+-)?\d+,)*(?:\d+-)?\d+';
 
@@ -967,12 +968,8 @@ sub take {
 sub grant {
     my ($cmd) = @_;
 
-    my $revoke = 0;
-    while (@ARGV) {
-    }
-
-    $revoke = 1 if $cmd->{action} eq 'revoke';
-    return 0;
+    whine "$cmd is unimplemented.";
+    return 1;
 }
 
 # Client <-> Server communication.
@@ -1909,8 +1906,6 @@ Text:
         ticket/1-3,5-7/history
 
         user/ams
-        user/ams/rights
-        user/ams,rai,1/rights
 
     For more information:
 
@@ -2028,20 +2023,6 @@ Text:
         - edit
         - create
 
-    In addition, the following type-specific actions exist:
-
-        - grant
-        - revoke
-
-    Attributes:
-
-        The following attributes can be used with "rt show" or "rt edit"
-        to retrieve or edit other information associated with users and
-        groups:
-
-        rights                  Global rights granted to this user.
-        rights/<queue>          Queue rights for this user.
-
 --
 
 Title: queue
@@ -2384,12 +2365,6 @@ Text:
 
 --
 
-Title: grant
-Title: revoke
-Text:
-
---
-
 Title: query
 Text:
 
index c07f6ab..105affd 100755 (executable)
@@ -3,7 +3,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 37a6aff..ac16a0c 100644 (file)
@@ -299,7 +299,7 @@ fix them.  To report a bug, send email to <rt-bugs@bestpractical.com>.
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index ad8d87b..f884c52 100644 (file)
@@ -148,3 +148,28 @@ the following Mason templates, this feature will not function correctly:
     share/html/Search/Elements/BuildFormatString
     share/html/Search/Elements/PickCFs
     share/html/Search/Elements/PickCriteria
+
+=head1 UPGRADING FROM 4.0.8 AND EARLIER
+
+=head2 Data upgrades
+
+Previously, the default lifecycle was stored in Queues.Lifecycle as
+NULL. To simplify code, RT now stores the string 'default' to match the
+name of the Lifecycle.
+
+The 3.9.2 upgrade step removed all enabled Personal Groups, but missed
+any disabled groups. We catch and clean up the disabled Personal groups
+during the 4.0.9 upgrade step.
+
+=head2 Javascript Changes
+
+If you have set a custom @JSFiles in RT_SiteConfig.pm, you will need to
+amend this to include the new jquery.cookie.js file added to
+RT_Config.pm.  If you are using an extension that requires manually
+tweaking @JSFiles, please contact the developer and ask them to use
+RT->AddJavaScript in their extension to avoid these upgrade problems.
+
+If you have @JSFiles set in your RT_SiteConfig.pm but it appears to be
+the same as RT_Config.pm (no local js files added) you can safely remove
+the whole setting from RT_SiteConfig.pm and allow our default to be
+used.
index ea49b05..73b5c33 100644 (file)
@@ -11,7 +11,7 @@ RT.  They are organized into classes and topics.
 The user interface to Articles is available from the Tools -> Articles
 menu.  Admin functionality can be found under Tools -> Configuration ->
 Articles.  Once configured, articles will become available for searching
-on the Reply/Comment page on tickets.  There are configuration variables
+on the Reply/Comment page on tickets.  There are L</"Configuration Options">
 to make Articles available on ticket creation.
 
 =head2 Basics
@@ -30,20 +30,24 @@ Classes are equivalent to RT's queues.  They can be created by going
 to Tools -> Configuration -> Articles -> Classes -> New Class.  Articles
 are assigned to one Class.  When you create Custom Fields for use with
 Articles, they will be applied Globally or to a Class, like Custom
-Fields are applied to a Queue in RT.  Each class also controls what
-information is included into a reply (such as the Class header and
-footer) and the Article.
+Fields are applied to a Queue in RT.
 
-Classes need to be Applied, just like a Custom Field by using the
-Applied To link.  You can apply them globally or on a queue-by-queue
-basis.
+A common use for Articles is to store frequently
+used replies for requestors, like troubleshooting steps or how to sign
+up for a new account. When you insert Article text, you may or may not
+want to include the Article name and summary, in addition to the content,
+when inserting the Article in a reply. You can control this behavior on
+the Class configuration page.
 
-hotlist.
+Classes need to be Applied, just like a Custom Field, by using the
+Applies To link on the Modify Class page (Tools -> Configuration ->
+Articles -> Classes, select the class to modify).  You can apply
+them globally or on a queue-by-queue basis.
 
 =head3 Topics
 
 You can also use Topics to organize your Articles.  While editing a
-Class, there is a Topic tab for Class specific Topics.  You can create
+Class, there is a Topics tab for Class-specific Topics.  You can create
 global Topics from the Global tab under Tools -> Configuration.
 
 When editing Topics, type the name (and optionally description) of the
@@ -53,9 +57,9 @@ tree of Topics should show up when creating or modifying articles in
 the class. These can be arbitrarily nested.
 
 Global Topics will be available for all Articles, regardless of their
-Class.  Articles can belong to both global and class-specific Topics.
+Class.  Articles can belong to both global and Class-specific Topics.
 
-Articles topics can be set from the 'Modify' screen for the article --
+Article topics can be set from the Modify screen for the article --
 simply select as many topics as you desire from the list at the bottom
 of the screen.
 
@@ -63,18 +67,20 @@ of the screen.
 
 Articles don't have a single "body" section for each
 article. Everything is a custom field (except for name, summary and
-some other basic metadata). So, you need to create some custom
-fields to hold the Article body and other data.  These Custom Fields
-should have "Applies To" be "RTFM Articles".
+some other basic metadata). So to put information on an
+Article, you need to create some custom fields to hold the Article
+body and other data.  When you create these new Custom Fields, set
+the Applies To field to Articles.
 
-Once you've created your custom fields, go into your classes and click
-on "Custom Fields" and add the Custom Fields you want to each class.
+Once you've created your Custom Fields, go into your Classes, click
+on Custom Fields, and add the Custom Fields you want to each Class.
 Alternatively, use the Applies To link from each Custom Field.
 
 =head2 Creating Articles
 
-You can create an article from scratch by going to Tools -> Articles ->
+You can create an Article from scratch by going to Tools -> Articles ->
 New Article and then picking which Class to create the Article under.
+You must have a Class to assign the new Article to.
 The Summary, Description and Custom Fields will all be searchable when
 including an Article and you can control what Custom Fields end up in
 your Ticket from the Class configuration page.
@@ -84,11 +90,11 @@ your Ticket from the Class configuration page.
 You can extract the body of a ticket into an article. Within RT, you
 should now see an "Extract to article" button in the upper right hand
 corner of RT's UI when working with tickets. When you click that
-button, RT will ask you which Class to create your new article in.
-Once you click on a class name, the Ticket's transactions will be
+button, RT will ask you which Class to create your new Article in.
+Once you click on a Class name, the Ticket's transactions will be
 displayed, along with a set of select boxes. For each transaction, you
 can pick which Custom Field that transaction should be extracted to.
-From there on in, it's just regular article creation.
+From there on in, it's just regular Article creation.
 
 =head2 Including an Article
 
@@ -97,14 +103,14 @@ is a UI widget that lets you search for and include Articles in
 your reply.  (They're editable, of course).  
 
 Articles can be included by searching for them, knowing the Id of the
-article, using the Article Hotlist and using the Queue specific
+article, using the Article Hotlist and using the Queue-specific
 dropdown.
 
-=head2 Queue Specific List of Articles 
+=head2 Queue-Specific List of Articles 
 
-You can use Topics to organize a set of Queue specific Articles.
+You can use Topics to organize a set of Queue-specific Articles.
 Simply create a global Topic called 'Queues' and then create Topics
-under Queues named after each of your Queues.  Within each Queue named
+under Queues named after each of your Queues.  Within each Queue-named
 Topic, create some Topics and then assign Articles to those
 sub-topics.  This creates a hierarchy like this:
 
@@ -118,38 +124,44 @@ offered a choice of Topic 1 and Topic 2 along with the searching.
 After choosing Topic 1 or Topic 2, you will be given a list of
 relevant articles to choose.
 
-Alternately, you can now implement this by applying a single class to
-your queue and using the L<Article Hotlist> feature described below.
+Alternately, you can now implement this by applying a single Class to
+your Queue and using the L</"Article Hotlist"> feature described below.
 
 =head2 Article Hotlist
 
-If you enable "All articles in this class are on dropdown on ticket
-reply page" option, there will be a dropdown on the Create or Update
-page which allows users to quickly include Articles.
+The Modify Class page has a checkbox labelled "All Articles in this
+class should be listed in a dropdown of the ticket reply page".
+If you select this for a Class, a dropdown will be available on the
+Ticket Create or Update page which allows users to quickly include
+Articles in this Class.
+
+The Class needs to be set up and Applied for the dropdown to appear
+(see L</"Classes">).
 
 =head2 SelfService Interface
 
 If you grant the Unprivileged user group the right ShowArticle, they
 will get a Search box at the top of their interface.  This allows users
-to look for answer to questions before creating a Ticket.
+to look through your Articles for answers to questions before creating
+a Ticket.
 
-=head1 Configuration options
+=head1 Configuration Options
 
 =head2 ArticleOnTicketCreate
 
 Set this to a true value to display the Article include interface on the
 Ticket Create page in addition to the Reply/Comment page (Create.html
-in addition to Update.html)
+in addition to Update.html).
 
 =head2 HideArticleSearchOnReplyCreate
 
 On Ticket Reply (and Create if you set the above config var)
-RTFM normally displays a search box and an include box (for
-inputting an article id) and configurable dropdowns
-of articles.  These can be configured using Global Topics or
+RT's Article system normally displays a search box and an include box
+(for inputting an article id) and configurable dropdowns
+of Articles.  These can be configured using Global Topics or
 on the Class page.
 
-If you set this to a true value, RTFM will only display
-dropdowns and hide the search boxes
+If you set this to a true value, RT will only display
+dropdowns and hide the search boxes.
 
 =cut
index 396c562..7c50ee9 100644 (file)
@@ -38,7 +38,9 @@ For example, a bugfix branched from C<4.0-trunk> might be named
 C<4.0/fail-taint-mode-early>.  A feature branched from C<master> when
 there exists a C<4.0-trunk> but no C<4.2-trunk> might be named
 C<4.2/rename-LogToScreen>.  For consistency, branches should use dashes,
-not underscores, to separate words.
+not underscores, to separate words.  Branches which are destined for
+4.2, but which are branched from 4.0 (to provide for easy extraction as
+a 4.0 extension) should be named 4.2-on-4.0/branch-name.
 
 Branches should be reviewed by another developer before being merged.
 Reviewers should make sure that the branch accomplishes what it claims
index 5d2cd4c..355f6ce 100644 (file)
@@ -113,6 +113,10 @@ preference are ignored.  We suggest the C<prefork> MPM or FastCGI
 deployment if your privileged users are in a different timezone than the
 one the server is configured for.
 
+B<NOTE>: RT 3.8 and below suggested use of C<SetHandler perl-script>;
+this is incorrect for RT 4, and will lead to difficulties sending
+outgoing mail from RT.  Ensure that you use C<SetHandler modperl>.
+
     <VirtualHost rt.example.com>
         ### Optional apache logs for RT
         # ErrorLog /opt/rt4/var/log/apache2.error
index 226c2f6..f2c52db 100644 (file)
@@ -460,6 +460,23 @@ Set($ExtractSubjectTagNoMatch, ( ${RT::EmailSubjectTagRegex}
        ? qr/\[(?:${RT::EmailSubjectTagRegex}) #\d+\]/
        : qr/\[\Q$RT::rtname\E #\d+\]/));
 
+=item C<$CheckMoreMSMailHeaders>
+
+Some email clients create a plain text version of HTML-formatted
+email to help other clients that read only plain text.
+Unfortunately, the plain text parts sometimes end up with
+doubled newlines and these can then end up in RT. This
+is most often seen in MS Outlook.
+
+Enable this option to have RT check for additional mail headers
+and attempt to identify email from MS Outlook. When detected,
+RT will then clean up double newlines. Note that it may
+clean up intentional double newlines as well.
+
+=cut
+
+Set( $CheckMoreMSMailHeaders, 0);
+
 =back
 
 
@@ -873,6 +890,7 @@ Set(@JSFiles, qw/
     jquery-ui-1.8.4.custom.min.js
     jquery-ui-timepicker-addon.js
     jquery-ui-patch-datepicker.js
+    jquery.cookie.js
     titlebox-state.js
     util.js
     userautocomplete.js
index 063f7f7..1a59e43 100644 (file)
--- a/lib/RT.pm
+++ b/lib/RT.pm
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -312,6 +312,16 @@ sub InitLogging {
     InitSignalHandlers();
 }
 
+{   # Work around bug in Log::Dispatch < 2.30, wherein the short forms
+    # of ->warn, ->err, and ->crit do not usefully propagate out, unlike
+    # ->warning, ->error, and ->critical
+    package Log::Dispatch;
+    no warnings 'redefine';
+    sub warn { shift->warning(@_) }
+    sub err  { shift->error(@_) }
+    sub crit { shift->critical(@_) }
+}
+
 sub InitSignalHandlers {
 
 # Signal handlers
@@ -329,6 +339,11 @@ sub InitSignalHandlers {
             unshift @_, $RT::Logger, qw(level warning message);
             goto &Log::Dispatch::log;
         }
+        # Return value is used only by RT::Test to filter warnings from
+        # reaching the Test::NoWarnings catcher.  If Log::Dispatch::log() ever
+        # starts returning 'IGNORE', we'll need to switch to something more
+        # clever.  I don't expect that to happen.
+        return 'IGNORE';
     };
 
 #When we call die, trap it and log->crit with the value of the die.
index ae3eda4..c752aa2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -285,7 +285,8 @@ sub Create {
                        ObjectId      => $args{'ObjectId'},
                    );
     if ( $self->Id ) {
-        return ( 0, $self->loc('That principal already has that right') );
+        return ( 0, $self->loc('[_1] already has that right',
+                    $princ_obj->Object->Name) );
     }
 
     my $id = $self->SUPER::Create( PrincipalId   => $princ_obj->id,
index 49a7f1d..d1e0df5 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 31c89ae..395805b 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 5f96e06..8566c62 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index cde874e..89b7536 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -87,7 +87,7 @@ sub SetRecipients {
 
 =head2 SetReturnAddress
 
-Set this message\'s return address to the apropriate queue address
+Set this message's return address to the apropriate queue address
 
 =cut
 
index 29fef5e..33950b1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -56,10 +56,7 @@ use MIME::Entity;
 
 =head1 NAME
 
- RT::Action::CreateTickets
-
-Create one or more tickets according to an externally supplied template.
-
+RT::Action::CreateTickets - Create one or more tickets according to an externally supplied template
 
 =head1 SYNOPSIS
 
@@ -72,18 +69,14 @@ Create one or more tickets according to an externally supplied template.
 
 =head1 DESCRIPTION
 
+The CreateTickets ScripAction allows you to create automated workflows in RT,
+creating new tickets in response to actions and conditions from other
+tickets.
 
-Using the "CreateTickets" ScripAction and mandatory dependencies, RT now has 
-the ability to model complex workflow. When a ticket is created in a queue
-that has a "CreateTickets" scripaction, that ScripAction parses its "Template"
-
-
-
-=head2 FORMAT
-
-CreateTickets uses the template as a template for an ordered set of tickets 
-to create. The basic format is as follows:
+=head2 Format
 
+CreateTickets uses the RT template configured in the scrip as a template
+for an ordered set of tickets to create. The basic format is as follows:
 
  ===Create-Ticket: identifier
  Param: Value
@@ -98,19 +91,24 @@ to create. The basic format is as follows:
  Content: Blah
  ENDOFCONTENT
 
-
-Each ===Create-Ticket: section is evaluated as its own 
-Text::Template object, which means that you can embed snippets
-of perl inside the Text::Template using {} delimiters, but that 
-such sections absolutely can not span a ===Create-Ticket boundary.
-
-After each ticket is created, it's stuffed into a hash called %Tickets
-so as to be available during the creation of other tickets during the
-same ScripAction, using the key 'create-identifier', where
-C<identifier> is the id you put after C<===Create-Ticket:>.  The hash
+As shown, you can put one or more C<===Create-Ticket:> sections in
+a template. Each C<===Create-Ticket:> section is evaluated as its own
+L<Text::Template> object, which means that you can embed snippets
+of Perl inside the L<Text::Template> using C<{}> delimiters, but that
+such sections absolutely can not span a C<===Create-Ticket:> boundary.
+
+Note that each C<Value> must come right after the C<Param> on the same
+line. The C<Content:> param can extend over multiple lines, but the text
+of the first line must start right after C<Content:>. Don't try to start
+your C<Content:> section with a newline.
+
+After each ticket is created, it's stuffed into a hash called C<%Tickets>
+making it available during the creation of other tickets during the
+same ScripAction. The hash key for each ticket is C<create-[identifier]>,
+where C<[identifier]> is the value you put after C<===Create-Ticket:>.  The hash
 is prepopulated with the ticket which triggered the ScripAction as
-$Tickets{'TOP'}; you can also access that ticket using the shorthand
-TOP.
+C<$Tickets{'TOP'}>. You can also access that ticket using the shorthand
+C<TOP>.
 
 A simple example:
 
@@ -121,22 +119,20 @@ A simple example:
  so they can finish their work
  ENDOFCONTENT
 
-
-
-A convoluted example
+A convoluted example:
 
  ===Create-Ticket: approval
  { # Find out who the administrators of the group called "HR" 
    # of which the creator of this ticket is a member
     my $name = "HR";
-   
+
     my $groups = RT::Groups->new(RT->SystemUser);
     $groups->LimitToUserDefinedGroups();
     $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name");
     $groups->WithMember($TransactionObj->CreatorObj->Id);
+
     my $groupid = $groups->First->Id;
+
     my $adminccs = RT::Users->new(RT->SystemUser);
     $adminccs->WhoHaveRight(
        Right => "AdminGroup",
@@ -145,10 +141,10 @@ A convoluted example
        IncludeSuperusers => 0,
        IncludeSubgroupMembers => 0,
     );
-     my @admins;
+
+     our @admins;
      while (my $admin = $adminccs->Next) {
-         push (@admins, $admin->EmailAddress); 
+         push (@admins, $admin->EmailAddress);
      }
  }
  Queue: ___Approvals
@@ -170,50 +166,51 @@ A convoluted example
  Refers-To: {$Tickets{"create-approval"}->Id}
  Queue: ___Approvals
  Content-Type: text/plain
- Content: 
- Your approval is requred for this ticket, too.
+ Content: Your approval is requred for this ticket, too.
  ENDOFCONTENT
-=head2 Acceptable fields
 
-A complete list of acceptable fields for this beastie:
+As shown above, you can include a block with Perl code to set up some
+values for the new tickets. If you want to access a variable in the
+template section after the block, you must scope it with C<our> rather
+than C<my>. Just as with other RT templates, you can also include
+Perl code in the template sections using C<{}>.
 
+=head2 Acceptable Fields
+
+A complete list of acceptable fields:
 
     *  Queue           => Name or id# of a queue
        Subject         => A text string
-     ! Status          => A valid status. defaults to 'new'
+     ! Status          => A valid status. Defaults to 'new'
        Due             => Dates can be specified in seconds since the epoch
                           to be handled literally or in a semi-free textual
                           format which RT will attempt to parse.
-                        
-                          
-                          
-       Starts          => 
-       Started         => 
-       Resolved        => 
-       Owner           => Username or id of an RT user who can and should own 
+       Starts          =>
+       Started         =>
+       Resolved        =>
+       Owner           => Username or id of an RT user who can and should own
                           this ticket; forces the owner if necessary
    +   Requestor       => Email address
-   +   Cc              => Email address 
-   +   AdminCc         => Email address 
+   +   Cc              => Email address
+   +   AdminCc         => Email address
    +   RequestorGroup  => Group name
    +   CcGroup         => Group name
    +   AdminCcGroup    => Group name
-       TimeWorked      => 
-       TimeEstimated   => 
-       TimeLeft        => 
-       InitialPriority => 
-       FinalPriority   => 
-       Type            => 
-    +! DependsOn       => 
+       TimeWorked      =>
+       TimeEstimated   =>
+       TimeLeft        =>
+       InitialPriority =>
+       FinalPriority   =>
+       Type            =>
+    +! DependsOn       =>
     +! DependedOnBy    =>
     +! RefersTo        =>
-    +! ReferredToBy    => 
+    +! ReferredToBy    =>
     +! Members         =>
-    +! MemberOf        => 
-       Content         => content. Can extend to multiple lines. Everything
+    +! MemberOf        =>
+       Content         => Content. Can extend to multiple lines. Everything
                           within a template after a Content: header is treated
-                          as content until we hit a line containing only 
+                          as content until we hit a line containing only
                           ENDOFCONTENT
        ContentType     => the content-type of the Content field.  Defaults to
                           'text/plain'
@@ -225,31 +222,22 @@ A complete list of acceptable fields for this beastie:
        CF-name           => custom field value
        CustomField-name  => custom field value
 
-Fields marked with an * are required.
+Fields marked with an C<*> are required.
 
-Fields marked with a + may have multiple values, simply
+Fields marked with a C<+> may have multiple values, simply
 by repeating the fieldname on a new line with an additional value.
 
-Fields marked with a ! are postponed to be processed after all
-tickets in the same actions are created.  Except for 'Status', those
-field can also take a ticket name within the same action (i.e.
-the identifiers after ===Create-Ticket), instead of raw Ticket ID
+Fields marked with a C<!> have processing postponed until after all
+tickets in the same actions are created.  Except for C<Status>, those
+fields can also take a ticket name within the same action (i.e.
+the identifiers after C<===Create-Ticket:>), instead of raw ticket ID
 numbers.
 
-When parsed, field names are converted to lowercase and have -s stripped.
-Refers-To, RefersTo, refersto, refers-to and r-e-f-er-s-tO will all 
-be treated as the same thing.
-
-
+When parsed, field names are converted to lowercase and have hyphens stripped.
+C<Refers-To>, C<RefersTo>, C<refersto>, C<refers-to> and C<r-e-f-er-s-tO> will
+all be treated as the same thing.
 
-
-=head1 AUTHOR
-
-Jesse Vincent <jesse@bestpractical.com> 
-
-=head1 SEE ALSO
-
-perl(1).
+=head1 METHODS
 
 =cut
 
@@ -537,12 +525,16 @@ sub UpdateByTemplate {
     return @results;
 }
 
-=head2 Parse  TEMPLATE_CONTENT, DEFAULT_QUEUE, DEFAULT_REQEUESTOR ACTIVE
+=head2 Parse
+
+Takes (in order) template content, a default queue, a default requestor, and
+active (a boolean flag).
 
-Parse a template from TEMPLATE_CONTENT
+Parses a template in the template content, defaulting queue and requestor if
+unspecified in the template to the values provided as arguments.
 
-If $active is set to true, then we'll use Text::Template to parse the templates,
-allowing you to embed active perl in your templates.
+If the active flag is true, then we'll use L<Text::Template> to parse the
+templates, allowing you to embed active Perl in your templates.
 
 =cut
 
@@ -576,9 +568,9 @@ sub Parse {
 
 Parses mulitline templates. Things like:
 
- ===Create-Ticket ... 
+ ===Create-Ticket ...
 
-Takes the same arguments as Parse
+Takes the same arguments as L</Parse>.
 
 =cut
 
@@ -833,9 +825,10 @@ sub ParseLines {
 }
 
 
-=head2 _ParseXSVTemplate 
+=head2 _ParseXSVTemplate
 
-Parses a tab or comma delimited template. Should only ever be called by Parse
+Parses a tab or comma delimited template. Should only ever be called by
+L</Parse>.
 
 =cut
 
index 97d408c..ec60458 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -78,6 +78,7 @@ package RT::Action::EscalatePriority;
 use base 'RT::Action';
 
 use strict;
+use warnings;
 
 #Do what we need to do and send it out.
 
index a4d6458..72147b4 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Action::ExtractSubjectTag;
 use base 'RT::Action';
 use strict;
+use warnings;
 
 sub Describe {
     my $self = shift;
index 0a0825e..13913e6 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index f1aef40..3553cbc 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index b62f555..0016a36 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 5e7076f..1dece60 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 1511890..cf6952a 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 62832a5..a384af3 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Action::RecordComment;
 use base 'RT::Action';
 use strict;
+use warnings;
 
 =head1 NAME
 
index 2faa560..212281c 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Action::RecordCorrespondence;
 use base 'RT::Action';
 use strict;
+use warnings;
 
 =head1 NAME
 
index 2a7a2e3..ab0f307 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 783d57d..2043532 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -50,6 +50,7 @@ package RT::Action::SetPriority;
 use base 'RT::Action';
 
 use strict;
+use warnings;
 
 #Do what we need to do and send it out.
 
index f52d401..be00396 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 1bad2be..b259323 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -50,6 +50,7 @@ package RT::Action::UserDefined;
 use base 'RT::Action';
 
 use strict;
+use warnings;
 
 =head2 Prepare
 
index 6a519c1..dc60222 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 85526c1..6892f41 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index cd4519c..8fcaeb2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index d2ba3ac..97d3cfb 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 000a8dc..acc4916 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index b22df5c..0a02568 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 678aa11..589a6b8 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -611,15 +611,6 @@ sub CustomFieldLookupType {
     "RT::Class-RT::Article";
 }
 
-# _LookupId is the id of the toplevel type object the customfield is joined to
-# in this case, that's an RT::Class.
-
-sub _LookupId {
-    my $self = shift;
-    return $self->ClassObj->id;
-
-}
-
 =head2 LoadByInclude Field Value
 
 Takes the name of a form field from "Include Article"
index 47d0ebe..d69eabf 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index f1d9a63..35387eb 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -266,7 +266,7 @@ sub ParentObj {
 =head2 Children
 
 Returns an L<RT::Attachments> object which is preloaded with
-all attachments objects with this attachment\'s Id as their
+all attachments objects with this attachment's Id as their
 C<Parent>.
 
 =cut
index 2bdbc24..5b087a4 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 15bd912..a0edb15 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index fcbd0b1..9c18c1a 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 2aae60e..403c318 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 4c05852..b334d4d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index f76fc5d..4d8f356 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 3906b9f..5720e2a 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 37dc411..60122c7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 3ca4f96..3826c56 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 73eea2b..2c9129c 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -50,6 +50,7 @@ package RT::Condition::AnyTransaction;
 use base 'RT::Condition';
 
 use strict;
+use warnings;
 
 
 =head2 IsApplicable
index 11c40e6..8df73ca 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -52,6 +52,7 @@ use base 'RT::Condition';
 use RT::Date;
 
 use strict;
+use warnings;
 
 sub IsApplicable {
     my $self = shift;
index 60d5bbe..bdeaf2d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 3bf79a1..547aea2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -59,6 +59,7 @@ Returns true if the ticket we're operating on is overdue
 package RT::Condition::Overdue;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 
 =head2 IsApplicable
index 4643791..8500548 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::OwnerChange;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 
 =head2 IsApplicable
index aa00e60..a600453 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::PriorityChange;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 
 =head2 IsApplicable
index 17943cf..a28d6df 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::PriorityExceeds;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 =head2 IsApplicable
 
index 69eea18..ba7a8a4 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::QueueChange;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 =head2 IsApplicable
 
index 7072221..a057e40 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 10d882e..e84915d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::StatusChange;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 =head2 DESCRIPTION
 
index 8ed5e5c..1abee67 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -49,6 +49,7 @@
 package RT::Condition::UserDefined;
 use base 'RT::Condition';
 use strict;
+use warnings;
 
 
 =head2 IsApplicable
index ba338bb..7fe7b7b 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -435,10 +435,13 @@ our %META = (
             Description => 'Date format',                            #loc
             Callback => sub { my $ret = { Values => [], ValuesLabel => {}};
                               my $date = RT::Date->new($HTML::Mason::Commands::session{'CurrentUser'});
-                              $date->Set;
+                              $date->SetToNow;
                               foreach my $value ($date->Formatters) {
                                  push @{$ret->{Values}}, $value;
-                                 $ret->{ValuesLabel}{$value} = $date->$value();
+                                 $ret->{ValuesLabel}{$value} = $date->Get(
+                                     Format     => $value,
+                                     Timezone   => 'user',
+                                 );
                               }
                               return $ret;
             },
@@ -1219,13 +1222,19 @@ sub SetFromConfig {
             # Otherwie 5.10 goes boom. maybe we should skip any
             # reference
             next if ref($entry) eq 'SCALAR' || ref($entry) eq 'REF';
-            my $entry_ref = *{$entry}{ ref($ref) };
+
+            my $ref_type = ref($ref);
+
+            # regex/arrayref/hashref/coderef are stored in SCALAR glob
+            $ref_type = 'SCALAR' if $ref_type eq 'REF';
+
+            my $entry_ref = *{$entry}{ $ref_type };
             next unless $entry_ref;
 
             # if references are equal then we've found
             if ( $entry_ref == $ref ) {
                 $last_pack = $pack;
-                return ( $REF_SYMBOLS{ ref($ref) } || '*' ) . $pack . $k;
+                return ( $REF_SYMBOLS{ $ref_type } || '*' ) . $pack . $k;
             }
         }
         return '';
index 2330478..6164a42 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -905,11 +905,25 @@ sub FindProtectedParts {
         # sense) unnecessarily applies a base64 transfer encoding to PGP
         # mail (whose content is already base64-encoded).
         if ( $entity->bodyhandle->is_encoded and $entity->head->mime_encoding ) {
-            pipe( my ($read_decoded, $write_decoded) );
             my $decoder = MIME::Decoder->new( $entity->head->mime_encoding );
             if ($decoder) {
-                eval { $decoder->decode($io, $write_decoded) };
-                $io = $read_decoded;
+                local $@;
+                eval {
+                    my $buf = '';
+                    open my $fh, '>', \$buf
+                        or die "Couldn't open scalar for writing: $!";
+                    binmode $fh, ":raw";
+                    $decoder->decode($io, $fh);
+                    close $fh or die "Couldn't close scalar: $!";
+
+                    open $fh, '<', \$buf
+                        or die "Couldn't re-open scalar for reading: $!";
+                    binmode $fh, ":raw";
+                    $io = $fh;
+                    1;
+                } or do {
+                    $RT::Logger->error("Couldn't decode body: $@");
+                }
             }
         }
 
index 7d24779..fa0d4ca 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -240,9 +240,12 @@ sub loc {
     my $handle = $self->LanguageHandle;
 
     if (@_ == 1) {
-        # pre-scan the lexicon hashes to return _AUTO keys verbatim,
-        # to keep locstrings containing '[' and '~' from tripping over Maketext
-        return $_[0] unless grep exists $_->{$_[0]}, @{ $handle->_lex_refs };
+        # If we have no [_1] replacements, and the key does not appear
+        # in the lexicon, unescape (using ~) and return it verbatim, as
+        # an optimization.
+        my $unescaped = $_[0];
+        $unescaped =~ s!~(.)!$1!g;
+        return $unescaped unless grep exists $_->{$_[0]}, @{ $handle->_lex_refs };
     }
 
     return $handle->maketext(@_);
index 2002d4e..14babff 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -1649,14 +1649,13 @@ sub ValuesForObject {
     my $object = shift;
 
     my $values = RT::ObjectCustomFieldValues->new($self->CurrentUser);
-    unless ($self->CurrentUserHasRight('SeeCustomField')) {
+    unless ($self->id and $self->CurrentUserHasRight('SeeCustomField')) {
         # Return an empty object if they have no rights to see
+        $values->Limit( FIELD => "id", VALUE => 0, SUBCLAUSE => "ACL" );
         return ($values);
     }
-    
-    
+
     $values->LimitToCustomField($self->Id);
-    $values->LimitToEnabled();
     $values->LimitToObject($object);
 
     return ($values);
@@ -1673,6 +1672,7 @@ Examples:
     'RT::Queue-RT::Ticket-RT::Transaction' => "Ticket Transactions",    # loc
     'RT::User'                             => "Users",                  # loc
     'RT::Group'                            => "Groups",                 # loc
+    'RT::Queue'                            => "Queues",                 # loc
 
 This is a class method. 
 
index 26df55a..6dffc34 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 90a1637..e3380b7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 6112514..f76fd51 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 2519e29..feeeadb 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index d4a5bc7..017018e 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 2e2bbc4..80a68be 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 40b53b1..0ad2fb2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -59,6 +59,7 @@ use RT::Dashboard;
 use RT::Interface::Web::Handler;
 use RT::Interface::Web;
 use File::Temp 'tempdir';
+use HTML::Scrubber;
 
 sub MailDashboards {
     my $self = shift;
@@ -248,6 +249,8 @@ SUMMARY
         }
     }
 
+    $content = ScrubContent($content);
+
     $RT::Logger->debug("Got ".length($content)." characters of output.");
 
     $content = HTML::RewriteAttributes::Links->rewrite(
@@ -463,6 +466,33 @@ sub BuildEmail {
 }
 
 {
+    my $scrubber;
+
+    sub _scrubber {
+        unless ($scrubber) {
+            $scrubber = HTML::Scrubber->new;
+            # Allow everything by default, except JS attributes ...
+            $scrubber->default(
+                1 => {
+                    '*' => 1,
+                    map { ("on$_" => 0) }
+                         qw(blur change click dblclick error focus keydown keypress keyup load
+                            mousedown mousemove mouseout mouseover mouseup reset select submit unload)
+                }
+            );
+            # ... and <script>s
+            $scrubber->deny('script');
+        }
+        return $scrubber;
+    }
+
+    sub ScrubContent {
+        my $content = shift;
+        return _scrubber->scrub($content);
+    }
+}
+
+{
     my %cache;
 
     sub HourDowDomIn {
@@ -560,8 +590,9 @@ sub GetResource {
 {
     package RT::Dashboard::FakeRequest;
     sub new { bless {}, shift }
-    sub header_out { shift }
-    sub headers_out { shift }
+    sub header_out { return undef }
+    sub headers_out { wantarray ? () : {} }
+    sub err_headers_out { wantarray ? () : {} }
     sub content_type {
         my $self = shift;
         $self->{content_type} = shift if @_;
index 5d10205..f9cbbe8 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -70,6 +70,7 @@ package RT::Dashboards;
 use RT::Dashboard;
 
 use strict;
+use warnings;
 use base 'RT::SharedSettings';
 
 sub RecordClass {
index ed094d0..d362197 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 4cf4184..d4a261e 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -131,8 +131,6 @@ sub SmartParseMIMEEntityFromScalar {
         }
     };
 
-    $self->RescueOutlook;
-
     #If for some reason we weren't able to parse the message using a temp file
     # try it with a scalar
     if ( $@ || !$self->Entity ) {
@@ -286,7 +284,7 @@ sub _PostProcessNewEntity {
 
 Takes a hashref object containing QueueObj, Head and CurrentUser objects.
 Returns a list of all email addresses in the To and Cc 
-headers b<except> the current Queue\'s email addresses, the CurrentUser\'s 
+headers b<except> the current Queue's email addresses, the CurrentUser's 
 email address and anything that the RT->Config->Get('RTAddressRegexp') matches.
 
 =cut
@@ -568,50 +566,91 @@ return 1 if it does find the problem in the entity and get it fixed.
 sub RescueOutlook {
     my $self = shift;
     my $mime = $self->Entity();
-    return unless $mime;
 
-    my $mailer = $mime->head->get('X-Mailer');
-    # 12.0 is outlook 2007, 14.0 is 2010
-    if ( $mailer && $mailer =~ /Microsoft(?:.*?)Outlook 1[2-4]\./ ) {
-        my $text_part;
-        if ( $mime->head->get('Content-Type') =~ m{multipart/mixed} ) {
-            my $first = $mime->parts(0);
-            if ( $first->head->get('Content-Type') =~ m{multipart/alternative} )
+    return unless $mime && $self->LooksLikeMSEmail($mime);
+
+    my $text_part;
+    if ( $mime->head->get('Content-Type') =~ m{multipart/mixed} ) {
+        my $first = $mime->parts(0);
+        if ( $first->head->get('Content-Type') =~ m{multipart/alternative} )
+        {
+            my $inner_first = $first->parts(0);
+            if ( $inner_first->head->get('Content-Type') =~ m{text/plain} )
             {
-                my $inner_first = $first->parts(0);
-                if ( $inner_first->head->get('Content-Type') =~ m{text/plain} )
-                {
-                    $text_part = $inner_first;
-                }
+                $text_part = $inner_first;
             }
         }
-        elsif ( $mime->head->get('Content-Type') =~ m{multipart/alternative} ) {
-            my $first = $mime->parts(0);
-            if ( $first->head->get('Content-Type') =~ m{text/plain} ) {
-                $text_part = $first;
-            }
+    }
+    elsif ( $mime->head->get('Content-Type') =~ m{multipart/alternative} ) {
+        my $first = $mime->parts(0);
+        if ( $first->head->get('Content-Type') =~ m{text/plain} ) {
+            $text_part = $first;
         }
+    }
 
-        if ($text_part) {
-
-            # use the unencoded string
-            my $content = $text_part->bodyhandle->as_string;
-            if ( $content =~ s/\n\n/\n/g ) {
-                # only write only if we did change the content
-                if ( my $io = $text_part->open("w") ) {
-                    $io->print($content);
-                    $io->close;
-                    return 1;
-                }
-                else {
-                    $RT::Logger->error("can't write to body");
-                }
+    # Add base64 since we've seen examples of double newlines with
+    # this type too. Need an example of a multi-part base64 to
+    # handle that permutation if it exists.
+    elsif ( $mime->head->get('Content-Transfer-Encoding') =~ m{base64} ) {
+        $text_part = $mime;    # Assuming single part, already decoded.
+    }
+
+    if ($text_part) {
+
+        # use the unencoded string
+        my $content = $text_part->bodyhandle->as_string;
+        if ( $content =~ s/\n\n/\n/g ) {
+
+            # Outlook puts a space on extra newlines, remove it
+            $content =~ s/\ +$//mg;
+
+            # only write only if we did change the content
+            if ( my $io = $text_part->open("w") ) {
+                $io->print($content);
+                $io->close;
+                $RT::Logger->debug(
+                    "Removed extra newlines from MS Outlook message.");
+                return 1;
+            }
+            else {
+                $RT::Logger->error("Can't write to body to fix newlines");
             }
         }
     }
+
     return;
 }
 
+=head1 LooksLikeMSEmail
+
+Try to determine if the current email may have
+come from MS Outlook or gone through Exchange, and therefore
+may have extra newlines added.
+
+=cut
+
+sub LooksLikeMSEmail {
+    my $self = shift;
+    my $mime = shift;
+
+    my $mailer = $mime->head->get('X-Mailer');
+
+    # 12.0 is outlook 2007, 14.0 is 2010
+    return 1 if ( $mailer && $mailer =~ /Microsoft(?:.*?)Outlook 1[2-4]\./ );
+
+    if ( RT->Config->Get('CheckMoreMSMailHeaders') ) {
+
+        # Check for additional headers that might
+        # indicate this came from Outlook or through Exchange.
+        # A sample we received had the headers X-MS-Has-Attach: and
+        # X-MS-Tnef-Correlator: and both had no value.
+
+        my @tags = $mime->head->tags();
+        return 1 if grep { /^X-MS-/ } @tags;
+    }
+
+    return 0;    # Doesn't look like MS email.
+}
 
 sub DESTROY {
     my $self = shift;
index 4c8a5db..7cb73d1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -50,7 +50,7 @@ package RT;
 use warnings;
 use strict;
 
-our $VERSION = '4.0.8';
+our $VERSION = '4.0.10';
 
 
 
index ac15bde..91aa840 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index b839824..753ff20 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index b367b2f..0c6028c 100644 (file)
@@ -3,7 +3,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -51,7 +51,7 @@
 
 =head1 NAME
 
-  RT::Group - RT\'s group object
+  RT::Group - RT's group object
 
 =head1 SYNOPSIS
 
index 8df4a73..e3c5e1d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 0b56c02..52244bd 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 1bb571b..e47c01c 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -391,7 +391,7 @@ sub ForWhichCurrentUserHasRight {
 
 =head2 LimitToEnabled
 
-Only find items that haven\'t been disabled
+Only find items that haven't been disabled
 
 =cut
 
@@ -449,7 +449,7 @@ sub Next {
 sub _DoSearch {
     my $self = shift;
     
-    #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
+    #unless we really want to find disabled rows, make sure we're only finding enabled ones.
     unless($self->{'find_disabled_rows'}) {
        $self->LimitToEnabled();
     }
index 03c262b..f03f393 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index e453cfa..0e75b9f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -209,16 +209,27 @@ sub SetMIMEEntityToEncoding {
     # do the same for parts first of all
     SetMIMEEntityToEncoding( $_, $enc, $preserve_words ) foreach $entity->parts;
 
-    my $charset = _FindOrGuessCharset($entity) or return;
+    my $head = $entity->head;
+
+    my $charset = _FindOrGuessCharset($entity);
+    if ( $charset ) {
+        unless( Encode::find_encoding($charset) ) {
+            $RT::Logger->warning("Encoding '$charset' is not supported");
+            $charset = undef;
+        }
+    }
+    unless ( $charset ) {
+        $head->replace( "X-RT-Original-Content-Type" => $head->mime_attr('Content-Type') );
+        $head->mime_attr('Content-Type' => 'application/octet-stream');
+        return;
+    }
 
     SetMIMEHeadToEncoding(
-       $entity->head,
+       $head,
        _FindOrGuessCharset($entity, 1) => $enc,
        $preserve_words
     );
 
-    my $head = $entity->head;
-
     # If this is a textual entity, we'd need to preserve its original encoding
     $head->replace( "X-RT-Original-Encoding" => $charset )
        if $head->mime_attr('content-type.charset') or IsTextualContentType($head->mime_type);
@@ -293,18 +304,30 @@ sub DecodeMIMEWordsToEncoding {
         $str = MIME::Field::ParamVal->parse($str)->stringify;
     }
 
+    # Pre-parse by removing all whitespace between encoded words
+    my $encoded_word = qr/
+                 =\?            # =?
+                 ([^?]+?)       # charset
+                 (?:\*[^?]+)?   # optional '*language'
+                 \?             # ?
+                 ([QqBb])       # encoding
+                 \?             # ?
+                 ([^?]+)        # encoded string
+                 \?=            # ?=
+                 /x;
+    $str =~ s/($encoded_word)\s+(?=$encoded_word)/$1/g;
+
+    # Also merge quoted-printable sections together, in case multiple
+    # octets of a single encoded character were split between chunks.
+    # Though not valid according to RFC 2047, this has been seen in the
+    # wild.
+    1 while $str =~ s/(=\?[^?]+\?[Qq]\?)([^?]+)\?=\1([^?]+)\?=/$1$2$3?=/i;
+
     # XXX TODO: use decode('MIME-Header', ...) and Encode::Alias to replace our
     # custom MIME word decoding and charset canonicalization.  We can't do this
     # until we parse before decode, instead of the other way around.
     my @list = $str =~ m/(.*?)          # prefix
-                         =\?            # =?
-                         ([^?]+?)       # charset
-                         (?:\*[^?]+)?   # optional '*language'
-                         \?             # ?
-                         ([QqBb])       # encoding
-                         \?             # ?
-                         ([^?]+)        # encoded string
-                         \?=            # ?=
+                         $encoded_word
                          ([^=]*)        # trailing
                         /xgcs;
 
@@ -336,7 +359,14 @@ sub DecodeMIMEWordsToEncoding {
 
             # now we have got a decoded subject, try to convert into the encoding
             if ( $charset ne $to_charset || $charset =~ /^utf-?8(?:-strict)?$/i ) {
-                Encode::from_to( $enc_str, $charset, $to_charset );
+                if ( Encode::find_encoding($charset) ) {
+                    Encode::from_to( $enc_str, $charset, $to_charset );
+                } else {
+                    $RT::Logger->warning("Charset '$charset' is not supported");
+                    $enc_str =~ s/[^[:print:]]/\357\277\275/g;
+                    Encode::from_to( $enc_str, 'UTF-8', $to_charset )
+                        unless $to_charset eq 'utf-8';
+                }
             }
 
             # XXX TODO: RT doesn't currently do the right thing with mime-encoded headers
index 58631b6..faea9d7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index c220bc0..2b48c62 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index 1635a18..a98636f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index d12abb6..d876e10 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -97,6 +97,7 @@ my %Meta = (
         },
     },
     DatabaseAdmin => {
+        SkipWrite       => 1,
         Widget          => '/Widgets/Form/String',
         WidgetArguments => {
             Default => 1,
@@ -106,6 +107,7 @@ my %Meta = (
         },
     },
     DatabaseAdminPassword => {
+        SkipWrite       => 1,
         Widget          => '/Widgets/Form/String',
         WidgetArguments => {
             Description => 'DBA password',  #loc
@@ -149,6 +151,7 @@ my %Meta = (
         },
     },
     Password => {
+        SkipWrite       => 1,
         Widget          => '/Widgets/Form/String',
         WidgetArguments => {
             Description => 'Administrative password', #loc
@@ -274,10 +277,10 @@ sub SaveConfig {
       $RT::Installer->{InstallConfig}{rtname};
 
     if ( open my $fh, '>', $file ) {
-        for ( keys %{ $RT::Installer->{InstallConfig} } ) {
+        for ( sort keys %{ $RT::Installer->{InstallConfig} } ) {
 
             # we don't want to store root's password in config.
-            next if $_ eq 'Password';
+            next if $class->Meta($_) and $class->Meta($_)->{SkipWrite};
 
             $RT::Installer->{InstallConfig}{$_} = ''
               unless defined $RT::Installer->{InstallConfig}{$_};
index bcdc13c..c1a6f4f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -48,6 +48,7 @@
 
 package RT::Interface::CLI;
 use strict;
+use warnings;
 use RT;
 
 use base 'Exporter';
@@ -92,7 +93,7 @@ our @EXPORT_OK = qw(CleanEnv GetCurrentUser GetMessageContent debug loc);
 
 =head2 CleanEnv
 
-Removes some of the nastiest nasties from the user\'s environment.
+Removes some of the nastiest nasties from the user's environment.
 
 =cut
 
index 38157c2..ddf27da 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -149,6 +149,9 @@ sub CheckForSuspiciousSender {
 
     my ( $From, $junk ) = ParseSenderAddressFromHead($head);
 
+    # If unparseable (non-ASCII), $From can come back undef
+    return undef if not defined $From;
+
     if (   ( $From =~ /^mailer-daemon\@/i )
         or ( $From =~ /^postmaster\@/i )
         or ( $From eq "" ))
@@ -1059,7 +1062,7 @@ sub CreateUser {
 
 Takes a hash containing QueueObj, Head and CurrentUser objects.
 Returns a list of all email addresses in the To and Cc
-headers b<except> the current Queue\'s email addresses, the CurrentUser\'s
+headers b<except> the current Queue's email addresses, the CurrentUser's
 email address  and anything that the configuration sub RT::IsRTAddress matches.
 
 =cut
@@ -1086,23 +1089,34 @@ sub ParseCcAddressesFromHead {
 
 =head2 ParseSenderAddressFromHead HEAD
 
-Takes a MIME::Header object. Returns a tuple: (user@host, friendly name)
-of the From (evaluated in order of Reply-To:, From:, Sender)
+Takes a MIME::Header object. Returns (user@host, friendly name, errors)
+where the first two values are the From (evaluated in order of
+Reply-To:, From:, Sender).
+
+A list of error messages may be returned even when a Sender value is
+found, since it could be a parse error for another (checked earlier)
+sender field. In this case, the errors aren't fatal, but may be useful
+to investigate the parse failure.
 
 =cut
 
 sub ParseSenderAddressFromHead {
     my $head = shift;
+    my @sender_headers = ('Reply-To', 'From', 'Sender');
+    my @errors;  # Accumulate any errors
 
     #Figure out who's sending this message.
-    foreach my $header ('Reply-To', 'From', 'Sender') {
+    foreach my $header ( @sender_headers ) {
         my $addr_line = $head->get($header) || next;
         my ($addr, $name) = ParseAddressFromHeader( $addr_line );
         # only return if the address is not empty
-        return ($addr, $name) if $addr;
+        return ($addr, $name, @errors) if $addr;
+
+        chomp $addr_line;
+        push @errors, "$header: $addr_line";
     }
 
-    return (undef, undef);
+    return (undef, undef, @errors);
 }
 
 =head2 ParseErrorsToAddressFromHead HEAD
@@ -1430,6 +1444,7 @@ sub Gateway {
     }
     @mail_plugins = grep !$skip_plugin{"$_"}, @mail_plugins;
     $parser->_DecodeBodies;
+    $parser->RescueOutlook;
     $parser->_PostProcessNewEntity;
 
     my $head = $Message->head;
@@ -1461,6 +1476,10 @@ sub Gateway {
 
     $args{'ticket'} ||= ExtractTicketId( $Message );
 
+    # ExtractTicketId may have been overridden, and edited the Subject
+    my $NewSubject = $Message->head->get('Subject');
+    chomp $NewSubject;
+
     $SystemTicket = RT::Ticket->new( RT->SystemUser );
     $SystemTicket->Load( $args{'ticket'} ) if ( $args{'ticket'} ) ;
     if ( $SystemTicket->id ) {
@@ -1545,9 +1564,11 @@ sub Gateway {
             );
         }
 
+        $head->replace('X-RT-Interface' => 'Email');
+
         my ( $id, $Transaction, $ErrStr ) = $Ticket->Create(
             Queue     => $SystemQueueObj->Id,
-            Subject   => $Subject,
+            Subject   => $NewSubject,
             Requestor => \@Requestors,
             Cc        => \@Cc,
             MIMEObj   => $Message
index 87a523d..c14bcf0 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
index e733bda..bfe4939 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
 #          &