Page MenuHomestyx hydra

No OneTemporary

diff --git a/conf/default.conf.php b/conf/default.conf.php
index e128e4062a..ebbf3f5bc7 100644
--- a/conf/default.conf.php
+++ b/conf/default.conf.php
@@ -1,600 +1,601 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
return array(
// The root URI which Phabricator is installed on.
// Example: "http://phabricator.example.com/"
'phabricator.base-uri' => null,
// If you have multiple environments, provide the production environment URI
// here so that emails, etc., generated in development/sandbox environments
// contain the right links.
'phabricator.production-uri' => null,
// Setting this to 'true' will invoke a special setup mode which helps guide
// you through setting up Phabricator.
'phabricator.setup' => false,
// The default PHID for users who haven't uploaded a profile image. It should
// be 50x50px.
'user.default-profile-image-phid' => 'PHID-FILE-4d61229816cfe6f2b2a3',
// -- DarkConsole ----------------------------------------------------------- //
// DarkConsole is a administrative debugging/profiling tool built into
// Phabricator. You can leave it disabled unless you're developing against
// Phabricator.
// Determines whether or not DarkConsole is available. DarkConsole exposes
// some data like queries and stack traces, so you should be careful about
// turning it on in production (although users can not normally see it, even
// if the deployment configuration enables it).
'darkconsole.enabled' => false,
// Always enable DarkConsole, even for logged out users. This potentially
// exposes sensitive information to users, so make sure untrusted users can
// not access an install running in this mode. You should definitely leave
// this off in production. It is only really useful for using DarkConsole
// utilties to debug or profile logged-out pages. You must set
// 'darkconsole.enabled' to use this option.
'darkconsole.always-on' => false,
// Allows you to mask certain configuration values from appearing in the
// "Config" tab of DarkConsole.
'darkconsole.config-mask' => array(
'mysql.pass',
'amazon-ses.secret-key',
'recaptcha.private-key',
'phabricator.csrf-key',
'facebook.application-secret',
'github.application-secret',
),
// -- MySQL --------------------------------------------------------------- //
// The username to use when connecting to MySQL.
'mysql.user' => 'root',
// The password to use when connecting to MySQL.
'mysql.pass' => '',
// The MySQL server to connect to. If you want to connect to a different
// port than the default (which is 3306), specify it in the hostname
// (e.g., db.example.com:1234).
'mysql.host' => 'localhost',
// -- Email ----------------------------------------------------------------- //
// Some Phabricator tools send email notifications, e.g. when Differential
// revisions are updated or Maniphest tasks are changed. These options allow
// you to configure how email is delivered.
// You can test your mail setup by going to "MetaMTA" in the web interface,
// clicking "Send New Message", and then composing a message.
// Default address to send mail "From".
'metamta.default-address' => 'noreply@example.com',
// Domain used to generate Message-IDs.
'metamta.domain' => 'example.com',
// When a user takes an action which generates an email notification (like
// commenting on a Differential revision), Phabricator can either send that
// mail "From" the user's email address (like "alincoln@logcabin.com") or
// "From" the 'metamta.default-address' address. The user experience is
// generally better if Phabricator uses the user's real address as the "From"
// since the messages are easier to organize when they appear in mail clients,
// but this will only work if the server is authorized to send email on behalf
// of the "From" domain. Practically, this means:
// - If you are doing an install for Example Corp and all the users will
// have corporate @corp.example.com addresses and any hosts Phabricator
// is running on are authorized to send email from corp.example.com,
// you can enable this to make the user experience a little better.
// - If you are doing an install for an open source project and your
// users will be registering via Facebook and using personal email
// addresses, you MUST NOT enable this or virtually all of your outgoing
// email will vanish into SFP blackholes.
// - If your install is anything else, you're much safer leaving this
// off since the risk in turning it on is that your outgoing mail will
// mostly never arrive.
'metamta.can-send-as-user' => false,
// Adapter class to use to transmit mail to the MTA. The default uses
// PHPMailerLite, which will invoke "sendmail". This is appropriate
// if sendmail actually works on your host, but if you haven't configured mail
// it may not be so great. You can also use Amazon SES, by changing this to
// 'PhabricatorMailImplementationAmazonSESAdapter', signing up for SES, and
// filling in your 'amazon-ses.access-key' and 'amazon-ses.secret-key' below.
'metamta.mail-adapter' =>
'PhabricatorMailImplementationPHPMailerLiteAdapter',
// When email is sent, try to hand it off to the MTA immediately. This may
// be worth disabling if your MTA infrastructure is slow or unreliable. If you
// disable this option, you must run the 'metamta_mta.php' daemon or mail
// won't be handed off to the MTA. If you're using Amazon SES it can be a
// little slugish sometimes so it may be worth disabling this and moving to
// the daemon after you've got your install up and running. If you have a
// properly configured local MTA it should not be necessary to disable this.
'metamta.send-immediately' => true,
// If you're using Amazon SES to send email, provide your AWS access key
// and AWS secret key here. To set up Amazon SES with Phabricator, you need
// to:
// - Make sure 'metamta.mail-adapter' is set to:
// "PhabricatorMailImplementationAmazonSESAdapter"
// - Make sure 'metamta.can-send-as-user' is false.
// - Make sure 'metamta.default-address' is configured to something sensible.
// - Make sure 'metamta.default-address' is a validated SES "From" address.
'amazon-ses.access-key' => null,
'amazon-ses.secret-key' => null,
// If you're using Sendgrid to send email, provide your access credentials
// here. This will use the REST API. You can also use Sendgrid as a normal
// SMTP service.
'sendgrid.api-user' => null,
'sendgrid.api-key' => null,
// You can configure a reply handler domain so that email sent from Maniphest
// will have a special "Reply To" address like "T123+82+af19f@example.com"
// that allows recipients to reply by email and interact with tasks. For
// instructions on configurating reply handlers, see the article
// "Configuring Inbound Email" in the Phabricator documentation. By default,
// this is set to 'null' and Phabricator will use a generic 'noreply@' address
// or the address of the acting user instead of a special reply handler
// address (see 'metamta.default-address'). If you set a domain here,
// Phabricator will begin generating private reply handler addresses. See
// also 'metamta.maniphest.reply-handler' to further configure behavior.
// This key should be set to the domain part after the @, like "example.com".
'metamta.maniphest.reply-handler-domain' => null,
// You can follow the instructions in "Configuring Inbound Email" in the
// Phabricator documentation and set 'metamta.maniphest.reply-handler-domain'
// to support updating Maniphest tasks by email. If you want more advanced
// customization than this provides, you can override the reply handler
// class with an implementation of your own. This will allow you to do things
// like have a single public reply handler or change how private reply
// handlers are generated and validated.
// This key should be set to a loadable subclass of
// PhabricatorMailReplyHandler (and possibly of ManiphestReplyHandler).
'metamta.maniphest.reply-handler' => 'ManiphestReplyHandler',
// Prefix prepended to mail sent by Maniphest. You can change this to
// distinguish between testing and development installs, for example.
'metamta.maniphest.subject-prefix' => '[Maniphest]',
// See 'metamta.maniphest.reply-handler-domain'. This does the same thing,
// but allows email replies via Differential.
'metamta.differential.reply-handler-domain' => null,
// See 'metamta.maniphest.reply-handler'. This does the same thing, but
// affects Differential.
'metamta.differential.reply-handler' => 'DifferentialReplyHandler',
// Prefix prepended to mail sent by Differential.
'metamta.differential.subject-prefix' => '[Differential]',
// By default, Phabricator generates unique reply-to addresses and sends a
// separate email to each recipient when you enable reply handling. This is
// more secure than using "From" to establish user identity, but can mean
// users may receive multiple emails when they are on mailing lists. Instead,
// you can use a single, non-unique reply to address and authenticate users
// based on the "From" address by setting this to 'true'. This trades away
// a little bit of security for convenience, but it's reasonable in many
// installs. Object interactions are still protected using hashes in the
// single public email address, so objects can not be replied to blindly.
'metamta.public-replies' => false,
// You can configure an email address like "bugs@phabricator.example.com"
// which will automatically create Maniphest tasks when users send email
// to it. This relies on the "From" address to authenticate users, so it is
// is not completely secure. To set this up, enter a complete email
// address like "bugs@phabricator.example.com" and then configure mail to
// that address so it routed to Phabricator (if you've already configured
// reply handlers, you're probably already done). See "Configuring Inbound
// Email" in the documentation for more information.
'metamta.maniphest.public-create-email' => null,
// -- Auth ------------------------------------------------------------------ //
// Can users login with a username/password, or by following the link from
// a password reset email? You can disable this and configure one or more
// OAuth providers instead.
'auth.password-auth-enabled' => true,
// Maximum number of simultaneous web sessions each user is permitted to have.
// Setting this to "1" will prevent a user from logging in on more than one
// browser at the same time.
'auth.sessions.web' => 5,
// Maximum number of simultaneous Conduit sessions each user is permitted
// to have.
'auth.sessions.conduit' => 3,
// Set this true to enable the Settings -> SSH Public Keys panel, which will
// allow users to associated SSH public keys with their accounts. This is only
// really useful if you're setting up services over SSH and want to use
// Phabricator for authentication; in most situations you can leave this
// disabled.
'auth.sshkeys.enabled' => false,
// -- Accounts -------------------------------------------------------------- //
// Is basic account information (email, real name, profile picture) editable?
// If you set up Phabricator to automatically synchronize account information
// from some other authoritative system, you can disable this to ensure
// information remains consistent across both systems.
'account.editable' => true,
// -- Facebook ------------------------------------------------------------ //
// Can users use Facebook credentials to login to Phabricator?
'facebook.auth-enabled' => false,
// Can users use Facebook credentials to create new Phabricator accounts?
'facebook.registration-enabled' => true,
// Are Facebook accounts permanently linked to Phabricator accounts, or can
// the user unlink them?
'facebook.auth-permanent' => false,
// The Facebook "Application ID" to use for Facebook API access.
'facebook.application-id' => null,
// The Facebook "Application Secret" to use for Facebook API access.
'facebook.application-secret' => null,
// -- Github ---------------------------------------------------------------- //
// Can users use Github credentials to login to Phabricator?
'github.auth-enabled' => false,
// Can users use Github credentials to create new Phabricator accounts?
'github.registration-enabled' => true,
// Are Github accounts permanently linked to Phabricator accounts, or can
// the user unlink them?
'github.auth-permanent' => false,
// The Github "Client ID" to use for Github API access.
'github.application-id' => null,
// The Github "Secret" to use for Github API access.
'github.application-secret' => null,
// -- Recaptcha ------------------------------------------------------------- //
// Is Recaptcha enabled? If disabled, captchas will not appear.
'recaptcha.enabled' => false,
// Your Recaptcha public key, obtained from Recaptcha.
'recaptcha.public-key' => null,
// Your Recaptcha private key, obtained from Recaptcha.
'recaptcha.private-key' => null,
// -- Misc ------------------------------------------------------------------ //
// This is hashed with other inputs to generate CSRF tokens. If you want, you
// can change it to some other string which is unique to your install. This
// will make your install more secure in a vague, mostly theoretical way. But
// it will take you like 3 seconds of mashing on your keyboard to set it up so
// you might as well.
'phabricator.csrf-key' => '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3',
// This is hashed with other inputs to generate mail tokens. If you want, you
// can change it to some other string which is unique to your install. In
// particular, you will want to do this if you accidentally send a bunch of
// mail somewhere you shouldn't have, to invalidate all old reply-to
// addresses.
'phabricator.mail-key' => '5ce3e7e8787f6e40dfae861da315a5cdf1018f12',
// Version string displayed in the footer. You probably should leave this
// alone.
'phabricator.version' => 'UNSTABLE',
// PHP requires that you set a timezone in your php.ini before using date
// functions, or it will emit a warning. If this isn't possible (for instance,
// because you are using HPHP) you can set some valid constant for
// date_default_timezone_set() here and Phabricator will set it on your
// behalf, silencing the warning.
'phabricator.timezone' => null,
// -- Files ----------------------------------------------------------------- //
// Lists which uploaded file types may be viewed in the browser. If a file
// has a mime type which does not appear in this list, it will always be
// downloaded instead of displayed. This is a security consideration: if a
// user uploads a file of type "text/html" and it is displayed as
// "text/html", they can easily execute XSS attacks. This is also a usability
// consideration, since browsers tend to freak out when viewing enormous
// binary files.
//
// The keys in this array are viewable mime types; the values are the mime
// types they will be delivered as when they are viewed in the browser.
'files.viewable-mime-types' => array(
'image/jpeg' => 'image/jpeg',
'image/jpg' => 'image/jpg',
'image/png' => 'image/png',
'image/gif' => 'image/gif',
'text/plain' => 'text/plain; charset=utf-8',
),
// Phabricator can proxy images from other servers so you can paste the URI
// to a funny picture of a cat into the comment box and have it show up as an
// image. However, this means the webserver Phabricator is running on will
// make HTTP requests to arbitrary URIs. If the server has access to internal
// resources, this could be a security risk. You should only enable it if you
// are installed entirely a VPN and VPN access is required to access
// Phabricator, or if the webserver has no special access to anything. If
// unsure, it is safer to leave this disabled.
'files.enable-proxy' => false,
// -- Storage --------------------------------------------------------------- //
// Phabricator allows users to upload files, and can keep them in various
// storage engines. This section allows you to configure which engines
// Phabricator will use, and how it will use them.
// The largest filesize Phabricator will store in the MySQL BLOB storage
// engine, which just uses a database table to store files. While this isn't a
// best practice, it's really easy to set up. This is hard-limited by the
// value of 'max_allowed_packet' in MySQL (since this often defaults to 1MB,
// the default here is slightly smaller than 1MB). Set this to 0 to disable
// use of the MySQL blob engine.
'storage.mysql-engine.max-size' => 1000000,
// Phabricator provides a local disk storage engine, which just writes files
// to some directory on local disk. The webserver must have read/write
// permissions on this directory. This is straightforward and suitable for
// most installs, but will not scale past one web frontend unless the path
// is actually an NFS mount, since you'll end up with some of the files
// written to each web frontend and no way for them to share. To use the
// local disk storage engine, specify the path to a directory here. To
// disable it, specify null.
'storage.local-disk.path' => null,
// If you want to store files in Amazon S3, specify an AWS access and secret
// key here and a bucket name below.
'amazon-s3.access-key' => null,
'amazon-s3.secret-key' => null,
// Set this to a valid Amazon S3 bucket to store files there. You must also
// configure S3 access keys above.
'storage.s3.bucket' => null,
// Phabricator uses a storage engine selector to choose which storage engine
// to use when writing file data. If you add new storage engines or want to
// provide very custom rules (e.g., write images to one storage engine and
// other files to a different one), you can provide an alternate
// implementation here. The default engine will use choose MySQL, Local Disk,
// and S3, in that order, if they have valid configurations above and a file
// fits within configured limits.
'storage.engine-selector' => 'PhabricatorDefaultFileStorageEngineSelector',
// -- Search ---------------------------------------------------------------- //
// Phabricator uses a search engine selector to choose which search engine
// to use when indexing and reconstructing documents, and when executing
// queries. You can override the engine selector to provide a new selector
// class which can select some custom engine you implement, if you want to
// store your documents in some search engine which does not have default
// support.
'search.engine-selector' => 'PhabricatorDefaultSearchEngineSelector',
// -- Differential ---------------------------------------------------------- //
'differential.revision-custom-detail-renderer' => null,
// Array for custom remarkup rules. The array should have a list of
// class names of classes that extend PhutilRemarkupRule
'differential.custom-remarkup-rules' => null,
// Array for custom remarkup block rules. The array should have a list of
// class names of classes that extend PhutilRemarkupEngineBlockRule
'differential.custom-remarkup-block-rules' => null,
// Set display word-wrap widths for Differential. Specify a dictionary of
// regular expressions mapping to column widths. The filename will be matched
// against each regexp in order until one matches. The default configuration
// uses a width of 100 for Java and 80 for other languages. Note that 80 is
// the greatest column width of all time. Changes here will not be immediately
// reflected in old revisions unless you purge the render cache.
'differential.wordwrap' => array(
'/\.java$/' => 100,
'/.*/' => 80,
),
// Class for appending custom fields to be included in the commit
// messages generated by "arc amend". Should inherit
// DifferentialCommitMessageModifier
'differential.modify-commit-message-class' => null,
// List of file regexps were whitespace is meaningful and should not
// use 'ignore-all' by default
'differential.whitespace-matters' => array(
'/\.py$/',
),
'differential.field-selector' => 'DifferentialDefaultFieldSelector',
// -- Maniphest ------------------------------------------------------------- //
'maniphest.enabled' => true,
- // Array of custom fields for Maniphest tasks. The array should contain
- // arrays of field specifications keyed with 'type', 'label', 'caption',
- // 'required' and whatever specific options exist for the given field
- // type.
+ // Array of custom fields for Maniphest tasks. For details on adding custom
+ // fields to Maniphest, see "Maniphest User Guide: Adding Custom Fields".
'maniphest.custom-fields' => array(),
+ // Class which drives custom field construction. See "Maniphest User Guide:
+ // Adding Custom Fields" in the documentation for more information.
+ 'maniphest.custom-task-extensions-class' => 'ManiphestDefaultTaskExtensions',
// -- Remarkup -------------------------------------------------------------- //
// If you enable this, linked YouTube videos will be embeded inline. This has
// mild security implications (you'll leak referrers to YouTube) and is pretty
// silly (but sort of awesome).
'remarkup.enable-embedded-youtube' => false,
// -- Garbage Collection ---------------------------------------------------- //
// Phabricator generates various logs and caches in the database which can
// be garbage collected after a while to make the total data size more
// manageable. To run garbage collection, launch a
// PhabricatorGarbageCollector daemon.
// Since the GC daemon can issue large writes and table scans, you may want to
// run it only during off hours or make sure it is scheduled so it doesn't
// overlap with backups. This determines when the daemon can start running
// each day.
'gcdaemon.run-at' => '12 AM',
// How many seconds after 'gcdaemon.run-at' the daemon may collect garbage
// for. By default it runs continuously, but you can set it to run for a
// limited period of time. For instance, if you do backups at 3 AM, you might
// run garbage collection for an hour beforehand. This is not a high-precision
// limit so you may want to leave some room for the GC to actually stop, and
// if you set it to something like 3 seconds you're on your own.
'gcdaemon.run-for' => 24 * 60 * 60,
// These 'ttl' keys configure how much old data the GC daemon keeps around.
// Objects older than the ttl will be collected. Set any value to 0 to store
// data indefinitely.
'gcdaemon.ttl.herald-transcripts' => 30 * (24 * 60 * 60),
'gcdaemon.ttl.daemon-logs' => 7 * (24 * 60 * 60),
'gcdaemon.ttl.differential-parse-cache' => 14 * (24 * 60 * 60),
// -- Feed ------------------------------------------------------------------ //
// If you set this to true, you can embed Phabricator activity feeds in other
// pages using iframes. These feeds are completely public, and a login is not
// required to view them! This is intended for things like open source
// projects that want to expose an activity feed on the project homepage.
'feed.public' => false,
// -- Customization --------------------------------------------------------- //
// Paths to additional phutil libraries to load.
'load-libraries' => array(),
'aphront.default-application-configuration-class' =>
'AphrontDefaultApplicationConfiguration',
'controller.oauth-registration' =>
'PhabricatorOAuthDefaultRegistrationController',
// Directory that phd (the Phabricator daemon control script) should use to
// track running daemons.
'phd.pid-directory' => '/var/tmp/phd',
// This value is an input to the hash function when building resource hashes.
// It has no security value, but if you accidentally poison user caches (by
// pushing a bad patch or having something go wrong with a CDN, e.g.) you can
// change this to something else and rebuild the Celerity map to break user
// caches. Unless you are doing Celerity development, it is exceptionally
// unlikely that you need to modify this.
'celerity.resource-hash' => 'd9455ea150622ee044f7931dabfa52aa',
// In a development environment, it is desirable to force static resources
// (CSS and JS) to be read from disk on every request, so that edits to them
// appear when you reload the page even if you haven't updated the resource
// maps. This setting ensures requests will be verified against the state on
// disk. Generally, you should leave this off in production (caching behavior
// and performance improve with it off) but turn it on in development. (These
// settings are the defaults.)
'celerity.force-disk-reads' => false,
// -- Pygments ------------------------------------------------------------ //
// Phabricator can highlight PHP by default, but if you want syntax
// highlighting for other languages you should install the python package
// 'Pygments', make sure the 'pygmentize' script is available in the
// $PATH of the webserver, and then enable this.
'pygments.enabled' => false,
// In places that we display a dropdown to syntax-highlight code,
// this is where that list is defined.
// Syntax is 'lexer-name' => 'Display Name',
'pygments.dropdown-choices' => array(
'apacheconf' => 'Apache Configuration',
'bash' => 'Bash Scripting',
'brainfuck' => 'Brainf*ck',
'c' => 'C',
'cpp' => 'C++',
'css' => 'CSS',
'diff' => 'Diff',
'django' => 'Django Templating',
'erb' => 'Embedded Ruby/ERB',
'erlang' => 'Erlang',
'html' => 'HTML',
'infer' => 'Infer from title (extension)',
'java' => 'Java',
'js' => 'Javascript',
'mysql' => 'MySQL',
'perl' => 'Perl',
'php' => 'PHP',
'text' => 'Plain Text',
'python' => 'Python',
'rainbow' => 'Rainbow',
'remarkup' => 'Remarkup',
'ruby' => 'Ruby',
'xml' => 'XML',
),
'pygments.dropdown-default' => 'infer',
// This is an override list of regular expressions which allows you to choose
// what language files are highlighted as. If your projects have certain rules
// about filenames or use unusual or ambiguous language extensions, you can
// create a mapping here. This is an ordered dictionary of regular expressions
// which will be tested against the filename. They should map to either an
// explicit language as a string value, or a numeric index into the captured
// groups as an integer.
'syntax.filemap' => array(
// Example: Treat all '*.xyz' files as PHP.
// '@\\.xyz$@' => 'php',
// Example: Treat 'httpd.conf' as 'apacheconf'.
// '@/httpd\\.conf$@' => 'apacheconf',
// Example: Treat all '*.x.bak' file as '.x'. NOTE: we map to capturing
// group 1 by specifying the mapping as "1".
// '@\\.([^.]+)\\.bak$@' => 1,
),
);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index b3e2ac530e..1a655fd589 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,1191 +1,1193 @@
<?php
/**
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
* @generated
*/
phutil_register_library_map(array(
'class' =>
array(
'Aphront304Response' => 'aphront/response/304',
'Aphront400Response' => 'aphront/response/400',
'Aphront404Response' => 'aphront/response/404',
'AphrontAjaxResponse' => 'aphront/response/ajax',
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
'AphrontAttachedFileView' => 'view/control/attachedfile',
'AphrontCSRFException' => 'aphront/exception/csrf',
'AphrontCalendarMonthView' => 'applications/calendar/view/month',
'AphrontContextBarView' => 'view/layout/contextbar',
'AphrontController' => 'aphront/controller',
'AphrontCrumbsView' => 'view/layout/crumbs',
'AphrontDatabaseConnection' => 'storage/connection/base',
'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration',
'AphrontDefaultApplicationController' => 'aphront/default/controller',
'AphrontDialogResponse' => 'aphront/response/dialog',
'AphrontDialogView' => 'view/dialog',
'AphrontErrorView' => 'view/form/error',
'AphrontException' => 'aphront/exception/base',
'AphrontFilePreviewView' => 'view/layout/filepreview',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
'AphrontFormDividerControl' => 'view/form/control/divider',
'AphrontFormDragAndDropUploadControl' => 'view/form/control/draganddropupload',
'AphrontFormFileControl' => 'view/form/control/file',
'AphrontFormLayoutView' => 'view/form/layout',
'AphrontFormMarkupControl' => 'view/form/control/markup',
'AphrontFormPasswordControl' => 'view/form/control/password',
'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha',
'AphrontFormSelectControl' => 'view/form/control/select',
'AphrontFormStaticControl' => 'view/form/control/static',
'AphrontFormSubmitControl' => 'view/form/control/submit',
'AphrontFormTextAreaControl' => 'view/form/control/textarea',
'AphrontFormTextControl' => 'view/form/control/text',
'AphrontFormToggleButtonsControl' => 'view/form/control/togglebuttons',
'AphrontFormTokenizerControl' => 'view/form/control/tokenizer',
'AphrontFormView' => 'view/form/base',
'AphrontHeadsupActionListView' => 'view/layout/headsup/actionlist',
'AphrontHeadsupActionView' => 'view/layout/headsup/action',
'AphrontIsolatedDatabaseConnection' => 'storage/connection/isolated',
'AphrontIsolatedDatabaseConnectionTestCase' => 'storage/connection/isolated/__tests__',
'AphrontKeyboardShortcutsAvailableView' => 'view/widget/keyboardshortcuts',
'AphrontListFilterView' => 'view/layout/listfilter',
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
'AphrontNullView' => 'view/null',
'AphrontPageView' => 'view/page/base',
'AphrontPagerView' => 'view/control/pager',
'AphrontPanelView' => 'view/layout/panel',
'AphrontQueryAccessDeniedException' => 'storage/exception/accessdenied',
'AphrontQueryConnectionException' => 'storage/exception/connection',
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
'AphrontQueryCountException' => 'storage/exception/count',
'AphrontQueryDuplicateKeyException' => 'storage/exception/duplicatekey',
'AphrontQueryException' => 'storage/exception/base',
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
'AphrontQueryParameterException' => 'storage/exception/parameter',
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
'AphrontRedirectException' => 'aphront/exception/redirect',
'AphrontRedirectResponse' => 'aphront/response/redirect',
'AphrontReloadResponse' => 'aphront/response/reload',
'AphrontRequest' => 'aphront/request',
'AphrontRequestFailureView' => 'view/page/failure',
'AphrontResponse' => 'aphront/response/base',
'AphrontSideNavView' => 'view/layout/sidenav',
'AphrontTableView' => 'view/control/table',
'AphrontTokenizerTemplateView' => 'view/control/tokenizer',
'AphrontTypeaheadTemplateView' => 'view/control/typeahead',
'AphrontURIMapper' => 'aphront/mapper',
'AphrontView' => 'view/base',
'AphrontWebpageResponse' => 'aphront/response/webpage',
'CelerityAPI' => 'infrastructure/celerity/api',
'CelerityResourceController' => 'infrastructure/celerity/controller',
'CelerityResourceMap' => 'infrastructure/celerity/map',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/response',
'ConduitAPIMethod' => 'applications/conduit/method/base',
'ConduitAPIRequest' => 'applications/conduit/protocol/request',
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect',
'ConduitAPI_conduit_getcertificate_Method' => 'applications/conduit/method/conduit/getcertificate',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/conduit/ping',
'ConduitAPI_daemon_launched_Method' => 'applications/conduit/method/daemon/launched',
'ConduitAPI_daemon_log_Method' => 'applications/conduit/method/daemon/log',
'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff',
'ConduitAPI_differential_createrevision_Method' => 'applications/conduit/method/differential/createrevision',
'ConduitAPI_differential_find_Method' => 'applications/conduit/method/differential/find',
'ConduitAPI_differential_getalldiffs_Method' => 'applications/conduit/method/differential/getalldiffs',
'ConduitAPI_differential_getcommitmessage_Method' => 'applications/conduit/method/differential/getcommitmessage',
'ConduitAPI_differential_getcommitpaths_Method' => 'applications/conduit/method/differential/getcommitpaths',
'ConduitAPI_differential_getdiff_Method' => 'applications/conduit/method/differential/getdiff',
'ConduitAPI_differential_getrevision_Method' => 'applications/conduit/method/differential/getrevision',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'applications/conduit/method/differential/getrevisionfeedback',
'ConduitAPI_differential_markcommitted_Method' => 'applications/conduit/method/differential/markcommitted',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/conduit/method/differential/parsecommitmessage',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty',
'ConduitAPI_differential_updaterevision_Method' => 'applications/conduit/method/differential/updaterevision',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'applications/conduit/method/differential/updatetaskrevisionassoc',
'ConduitAPI_differential_updateunitresults_Method' => 'applications/conduit/method/differential/updateunitresults',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/conduit/method/diffusion/getcommits',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/conduit/method/diffusion/getrecentcommitsbypath',
'ConduitAPI_feed_publish_Method' => 'applications/conduit/method/feed/publish',
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
'ConduitAPI_file_info_Method' => 'applications/conduit/method/file/info',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_maniphest_info_Method' => 'applications/conduit/method/maniphest/info',
'ConduitAPI_paste_Method' => 'applications/conduit/method/paste/base',
'ConduitAPI_paste_create_Method' => 'applications/conduit/method/paste/create',
'ConduitAPI_paste_info_Method' => 'applications/conduit/method/paste/info',
'ConduitAPI_path_getowners_Method' => 'applications/conduit/method/path/getowners',
'ConduitAPI_slowvote_info_Method' => 'applications/conduit/method/slowvote/info',
'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find',
'ConduitAPI_user_whoami_Method' => 'applications/conduit/method/user/whoami',
'ConduitException' => 'applications/conduit/protocol/exception',
'DarkConsole' => 'aphront/console/api',
'DarkConsoleConfigPlugin' => 'aphront/console/plugin/config',
'DarkConsoleController' => 'aphront/console/controller',
'DarkConsoleCore' => 'aphront/console/core',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api',
'DarkConsolePlugin' => 'aphront/console/plugin/base',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DatabaseConfigurationProvider' => 'applications/base/storage/configuration',
'DifferentialAction' => 'applications/differential/constants/action',
'DifferentialAddCommentView' => 'applications/differential/view/addcomment',
'DifferentialAuxiliaryField' => 'applications/differential/storage/auxiliaryfield',
'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/blamerev',
'DifferentialCCWelcomeMail' => 'applications/differential/mail/ccwelcome',
'DifferentialChangeType' => 'applications/differential/constants/changetype',
'DifferentialChangeset' => 'applications/differential/storage/changeset',
'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview',
'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview',
'DifferentialChangesetParser' => 'applications/differential/parser/changeset',
'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview',
'DifferentialComment' => 'applications/differential/storage/comment',
'DifferentialCommentEditor' => 'applications/differential/editor/comment',
'DifferentialCommentMail' => 'applications/differential/mail/comment',
'DifferentialCommentPreviewController' => 'applications/differential/controller/commentpreview',
'DifferentialCommentSaveController' => 'applications/differential/controller/commentsave',
'DifferentialCommitMessage' => 'applications/differential/parser/commitmessage',
'DifferentialCommitMessageData' => 'applications/differential/data/commitmessage',
'DifferentialCommitMessageField' => 'applications/differential/data/commitmessage',
'DifferentialCommitMessageModifier' => 'applications/differential/data/commitmessage',
'DifferentialCommitMessageParserException' => 'applications/differential/parser/commitmessage/exception',
'DifferentialController' => 'applications/differential/controller/base',
'DifferentialDAO' => 'applications/differential/storage/base',
'DifferentialDefaultFieldSelector' => 'applications/differential/field/selector/default',
'DifferentialDiff' => 'applications/differential/storage/diff',
'DifferentialDiffContentMail' => 'applications/differential/mail/diffcontent',
'DifferentialDiffCreateController' => 'applications/differential/controller/diffcreate',
'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty',
'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents',
'DifferentialDiffViewController' => 'applications/differential/controller/diffview',
'DifferentialExceptionMail' => 'applications/differential/mail/exception',
'DifferentialFieldSelector' => 'applications/differential/field/selector/base',
'DifferentialFieldSpecification' => 'applications/differential/field/specification/base',
'DifferentialFieldSpecificationIncompleteException' => 'applications/differential/field/exception/incomplete',
'DifferentialFieldValidationException' => 'applications/differential/field/exception/validation',
'DifferentialHunk' => 'applications/differential/storage/hunk',
'DifferentialInlineComment' => 'applications/differential/storage/inlinecomment',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/inlinecommentedit',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/inlinecommentpreview',
'DifferentialInlineCommentView' => 'applications/differential/view/inlinecomment',
'DifferentialLintStatus' => 'applications/differential/constants/lintstatus',
'DifferentialMail' => 'applications/differential/mail/base',
'DifferentialNewDiffMail' => 'applications/differential/mail/newdiff',
'DifferentialPrimaryPaneView' => 'applications/differential/view/primarypane',
'DifferentialReplyHandler' => 'applications/differential/replyhandler',
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/revertplan',
'DifferentialReviewRequestMail' => 'applications/differential/mail/reviewrequest',
'DifferentialRevision' => 'applications/differential/storage/revision',
'DifferentialRevisionCommentListView' => 'applications/differential/view/revisioncommentlist',
'DifferentialRevisionCommentView' => 'applications/differential/view/revisioncomment',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem',
'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/customrenderer',
'DifferentialRevisionDetailView' => 'applications/differential/view/revisiondetail',
'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit',
'DifferentialRevisionEditor' => 'applications/differential/editor/revision',
'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist',
'DifferentialRevisionListData' => 'applications/differential/data/revisionlist',
'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory',
'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview',
'DifferentialSubscribeController' => 'applications/differential/controller/subscribe',
'DifferentialTasksAttacher' => 'applications/differential/tasks',
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'DifferentialUnitTestResult' => 'applications/differential/constants/unittestresult',
'DifferentialViewTime' => 'applications/differential/storage/viewtime',
'DiffusionBranchInformation' => 'applications/diffusion/data/branch',
'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base',
'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable',
'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
'DiffusionChangeController' => 'applications/diffusion/controller/change',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable',
'DiffusionCommitController' => 'applications/diffusion/controller/commit',
'DiffusionCommitListController' => 'applications/diffusion/controller/commitlist',
'DiffusionController' => 'applications/diffusion/controller/base',
'DiffusionDiffController' => 'applications/diffusion/controller/diff',
'DiffusionDiffQuery' => 'applications/diffusion/query/diff/base',
'DiffusionFileContent' => 'applications/diffusion/data/filecontent',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
'DiffusionGitBranchQuery' => 'applications/diffusion/query/branch/git',
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
'DiffusionGitDiffQuery' => 'applications/diffusion/query/diff/git',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/git',
'DiffusionGitPathIDQuery' => 'applications/diffusion/query/pathid/base',
'DiffusionGitRequest' => 'applications/diffusion/request/git',
'DiffusionHistoryController' => 'applications/diffusion/controller/history',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
'DiffusionHistoryTableView' => 'applications/diffusion/view/historytable',
'DiffusionHomeController' => 'applications/diffusion/controller/home',
'DiffusionLastModifiedController' => 'applications/diffusion/controller/lastmodified',
'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/base',
'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/base',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/pathcomplete',
'DiffusionPathValidateController' => 'applications/diffusion/controller/pathvalidate',
'DiffusionRepositoryController' => 'applications/diffusion/controller/repository',
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
'DiffusionRequest' => 'applications/diffusion/request/base',
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
'DiffusionSvnDiffQuery' => 'applications/diffusion/query/diff/svn',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn',
'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/svn',
'DiffusionSvnRequest' => 'applications/diffusion/request/svn',
'DiffusionView' => 'applications/diffusion/view/base',
'HeraldAction' => 'applications/herald/storage/action',
'HeraldActionConfig' => 'applications/herald/config/action',
'HeraldApplyTranscript' => 'applications/herald/storage/transcript/apply',
'HeraldCommitAdapter' => 'applications/herald/adapter/commit',
'HeraldCondition' => 'applications/herald/storage/condition',
'HeraldConditionConfig' => 'applications/herald/config/condition',
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/condition',
'HeraldContentTypeConfig' => 'applications/herald/config/contenttype',
'HeraldController' => 'applications/herald/controller/base',
'HeraldDAO' => 'applications/herald/storage/base',
'HeraldDeleteController' => 'applications/herald/controller/delete',
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/differential',
'HeraldDryRunAdapter' => 'applications/herald/adapter/dryrun',
'HeraldEffect' => 'applications/herald/engine/effect',
'HeraldEngine' => 'applications/herald/engine/engine',
'HeraldFieldConfig' => 'applications/herald/config/field',
'HeraldHomeController' => 'applications/herald/controller/home',
'HeraldInvalidConditionException' => 'applications/herald/engine/engine/exception',
'HeraldInvalidFieldException' => 'applications/herald/engine/engine/exception',
'HeraldNewController' => 'applications/herald/controller/new',
'HeraldObjectAdapter' => 'applications/herald/adapter/base',
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/object',
'HeraldRecursiveConditionsException' => 'applications/herald/engine/engine/exception',
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/repetitionpolicy',
'HeraldRule' => 'applications/herald/storage/rule',
'HeraldRuleController' => 'applications/herald/controller/rule',
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule',
'HeraldTestConsoleController' => 'applications/herald/controller/test',
'HeraldTranscript' => 'applications/herald/storage/transcript/base',
'HeraldTranscriptController' => 'applications/herald/controller/transcript',
'HeraldTranscriptListController' => 'applications/herald/controller/transcriptlist',
'HeraldValueTypeConfig' => 'applications/herald/config/valuetype',
'Javelin' => 'infrastructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao',
'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAOException' => 'storage/lisk/dao/__tests__',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/default',
'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/base',
'ManiphestAuxiliaryFieldTypeException' => 'applications/maniphest/auxiliaryfield/typeexception',
'ManiphestAuxiliaryFieldValidationException' => 'applications/maniphest/auxiliaryfield/validationexception',
'ManiphestConstants' => 'applications/maniphest/constants/base',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/task',
'ManiphestReplyHandler' => 'applications/maniphest/replyhandler',
'ManiphestTask' => 'applications/maniphest/storage/task',
'ManiphestTaskAuxiliaryStorage' => 'applications/maniphest/storage/auxiliary',
'ManiphestTaskDescriptionChangeController' => 'applications/maniphest/controller/descriptionchange',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/taskdetail',
'ManiphestTaskEditController' => 'applications/maniphest/controller/taskedit',
+ 'ManiphestTaskExtensions' => 'applications/maniphest/extensions/base',
'ManiphestTaskListController' => 'applications/maniphest/controller/tasklist',
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
'ManiphestTaskOwner' => 'applications/maniphest/constants/owner',
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
'ManiphestTaskProject' => 'applications/maniphest/storage/taskproject',
'ManiphestTaskQuery' => 'applications/maniphest/query',
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
'ManiphestTaskSubscriber' => 'applications/maniphest/storage/subscriber',
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
'ManiphestTransactionDetailView' => 'applications/maniphest/view/transactiondetail',
'ManiphestTransactionEditor' => 'applications/maniphest/editor/transaction',
'ManiphestTransactionListView' => 'applications/maniphest/view/transactionlist',
'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/transactionpreview',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave',
'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype',
'ManiphestView' => 'applications/maniphest/view/base',
'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAuthController' => 'applications/auth/controller/base',
'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/browse',
'PhabricatorCalendarController' => 'applications/calendar/controller/base',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/token',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
'PhabricatorConduitController' => 'applications/conduit/controller/base',
'PhabricatorConduitDAO' => 'applications/conduit/storage/base',
'PhabricatorConduitLogController' => 'applications/conduit/controller/log',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/token',
'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorCountdownController' => 'applications/countdown/controller/base',
'PhabricatorCountdownDAO' => 'applications/countdown/storage/base',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/delete',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/edit',
'PhabricatorCountdownListController' => 'applications/countdown/controller/list',
'PhabricatorCountdownViewController' => 'applications/countdown/controller/view',
'PhabricatorDaemon' => 'infrastructure/daemon/base',
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/combined',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/daemonlogevents',
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/loglist',
'PhabricatorDaemonLogListView' => 'applications/daemon/view/daemonloglist',
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/default',
'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/default',
'PhabricatorDifferenceEngine' => 'infrastructure/diff/engine',
'PhabricatorDirectoryCategory' => 'applications/directory/storage/category',
'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete',
'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit',
'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist',
'PhabricatorDirectoryController' => 'applications/directory/controller/base',
'PhabricatorDirectoryDAO' => 'applications/directory/storage/base',
'PhabricatorDirectoryItem' => 'applications/directory/storage/item',
'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete',
'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit',
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
'PhabricatorDisabledUserController' => 'applications/auth/controller/disabled',
'PhabricatorDraft' => 'applications/draft/storage/draft',
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
'PhabricatorEmailLoginController' => 'applications/auth/controller/email',
'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken',
'PhabricatorEnv' => 'infrastructure/env',
'PhabricatorFeedConstants' => 'applications/feed/constants/base',
'PhabricatorFeedController' => 'applications/feed/controller/base',
'PhabricatorFeedDAO' => 'applications/feed/storage/base',
'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/publicstream',
'PhabricatorFeedQuery' => 'applications/feed/query',
'PhabricatorFeedStory' => 'applications/feed/story/base',
'PhabricatorFeedStoryData' => 'applications/feed/storage/story',
'PhabricatorFeedStoryDifferential' => 'applications/feed/story/differential',
'PhabricatorFeedStoryPhriction' => 'applications/feed/story/phriction',
'PhabricatorFeedStoryPublisher' => 'applications/feed/publisher',
'PhabricatorFeedStoryReference' => 'applications/feed/storage/storyreference',
'PhabricatorFeedStoryStatus' => 'applications/feed/story/status',
'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/story',
'PhabricatorFeedStoryUnknown' => 'applications/feed/story/unknown',
'PhabricatorFeedStoryView' => 'applications/feed/view/story',
'PhabricatorFeedStreamController' => 'applications/feed/controller/stream',
'PhabricatorFeedView' => 'applications/feed/view/base',
'PhabricatorFile' => 'applications/files/storage/file',
'PhabricatorFileController' => 'applications/files/controller/base',
'PhabricatorFileDAO' => 'applications/files/storage/base',
'PhabricatorFileDropUploadController' => 'applications/files/controller/dropupload',
'PhabricatorFileImageMacro' => 'applications/files/storage/imagemacro',
'PhabricatorFileListController' => 'applications/files/controller/list',
'PhabricatorFileMacroDeleteController' => 'applications/files/controller/macrodelete',
'PhabricatorFileMacroEditController' => 'applications/files/controller/macroedit',
'PhabricatorFileMacroListController' => 'applications/files/controller/macrolist',
'PhabricatorFileProxyController' => 'applications/files/controller/proxy',
'PhabricatorFileProxyImage' => 'applications/files/storage/proxyimage',
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
'PhabricatorFileStorageEngine' => 'applications/files/engine/base',
'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/base',
'PhabricatorFileTransformController' => 'applications/files/controller/transform',
'PhabricatorFileURI' => 'applications/files/uri',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/garbagecollector',
'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/goodfornothing',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorHelpController' => 'applications/help/controller/base',
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/keyboardshortcut',
'PhabricatorIRCBot' => 'infrastructure/daemon/irc/bot',
'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/base',
'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/message',
'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/objectname',
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/protocol',
'PhabricatorImageTransformer' => 'applications/files/transform',
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/javelin',
'PhabricatorLintEngine' => 'infrastructure/lint/engine',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/localdisk',
'PhabricatorLoginController' => 'applications/auth/controller/login',
'PhabricatorLogoutController' => 'applications/auth/controller/logout',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/amazonses',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/sendgrid',
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/test',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/base',
'PhabricatorMarkupEngine' => 'applications/markup/engine',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base',
'PhabricatorMetaMTADaemon' => 'applications/metamta/daemon/mta',
'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/parser',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/parser/__tests__',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail',
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/mail/__tests__',
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist',
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit',
'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists',
'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/receive',
'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/receivedlist',
'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/receivedmail',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send',
'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/sendgridreceive',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/mysql',
'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/default',
'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/oauthdiagnostics',
'PhabricatorOAuthFailureView' => 'applications/auth/view/oauthfailure',
'PhabricatorOAuthLoginController' => 'applications/auth/controller/oauth',
'PhabricatorOAuthProvider' => 'applications/auth/oauth/provider/base',
'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/facebook',
'PhabricatorOAuthProviderGithub' => 'applications/auth/oauth/provider/github',
'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/base',
'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/unlink',
'PhabricatorObjectGraph' => 'applications/phid/graph',
'PhabricatorObjectHandle' => 'applications/phid/handle',
'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/base',
'PhabricatorObjectHandleData' => 'applications/phid/handle/data',
'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/status',
'PhabricatorObjectSelectorDialog' => 'view/control/objectselector',
'PhabricatorOwnersController' => 'applications/owners/controller/base',
'PhabricatorOwnersDAO' => 'applications/owners/storage/base',
'PhabricatorOwnersDeleteController' => 'applications/owners/controller/delete',
'PhabricatorOwnersDetailController' => 'applications/owners/controller/detail',
'PhabricatorOwnersEditController' => 'applications/owners/controller/edit',
'PhabricatorOwnersListController' => 'applications/owners/controller/list',
'PhabricatorOwnersOwner' => 'applications/owners/storage/owner',
'PhabricatorOwnersPackage' => 'applications/owners/storage/package',
'PhabricatorOwnersPath' => 'applications/owners/storage/path',
'PhabricatorPHID' => 'applications/phid/storage/phid',
'PhabricatorPHIDConstants' => 'applications/phid/constants',
'PhabricatorPHIDController' => 'applications/phid/controller/base',
'PhabricatorPHIDDAO' => 'applications/phid/storage/base',
'PhabricatorPHIDListController' => 'applications/phid/controller/list',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup',
'PhabricatorPaste' => 'applications/paste/storage/paste',
'PhabricatorPasteController' => 'applications/paste/controller/base',
'PhabricatorPasteCreateController' => 'applications/paste/controller/create',
'PhabricatorPasteDAO' => 'applications/paste/storage/base',
'PhabricatorPasteListController' => 'applications/paste/controller/list',
'PhabricatorPasteViewController' => 'applications/paste/controller/view',
'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list',
'PhabricatorPeopleLogsController' => 'applications/people/controller/logs',
'PhabricatorPeopleProfileController' => 'applications/people/controller/profile',
'PhabricatorProfileView' => 'view/layout/profile',
'PhabricatorProject' => 'applications/project/storage/project',
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
'PhabricatorProjectController' => 'applications/project/controller/base',
'PhabricatorProjectCreateController' => 'applications/project/controller/create',
'PhabricatorProjectDAO' => 'applications/project/storage/base',
'PhabricatorProjectListController' => 'applications/project/controller/list',
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
'PhabricatorProjectStatus' => 'applications/project/constants/status',
'PhabricatorProjectSubproject' => 'applications/project/storage/subproject',
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/refresh',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleDifferentialHandle' => 'infrastructure/markup/remarkup/markuprule/handle/differential',
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
'PhabricatorRemarkupRuleEmbedFile' => 'infrastructure/markup/remarkup/markuprule/embedobject',
'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/remarkup/markuprule/imagemacro',
'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/remarkup/markuprule/maniphest',
'PhabricatorRemarkupRuleManiphestHandle' => 'infrastructure/markup/remarkup/markuprule/handle/maniphest',
'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/remarkup/markuprule/mention',
'PhabricatorRemarkupRuleObjectHandle' => 'infrastructure/markup/remarkup/markuprule/handle',
'PhabricatorRemarkupRuleObjectName' => 'infrastructure/markup/remarkup/markuprule/objectname',
'PhabricatorRemarkupRulePaste' => 'infrastructure/markup/remarkup/markuprule/paste',
'PhabricatorRemarkupRulePhriction' => 'infrastructure/markup/remarkup/markuprule/phriction',
'PhabricatorRemarkupRuleProxyImage' => 'infrastructure/markup/remarkup/markuprule/proxyimage',
'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/remarkup/markuprule/youtube',
'PhabricatorRepository' => 'applications/repository/storage/repository',
'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/arcanistproject',
'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/arcansistprojectedit',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/commit',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/base',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/commitdata',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/base',
'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/herald',
'PhabricatorRepositoryCommitMessageDetailParser' => 'applications/repository/parser/base',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/base',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/base',
'PhabricatorRepositoryCommitTaskDaemon' => 'applications/repository/daemon/committask',
'PhabricatorRepositoryController' => 'applications/repository/controller/base',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryDaemon' => 'applications/repository/daemon/base',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'applications/repository/parser/default',
'PhabricatorRepositoryDeleteController' => 'applications/repository/controller/delete',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/git',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/git',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/git',
'PhabricatorRepositoryGitFetchDaemon' => 'applications/repository/daemon/gitfetch',
'PhabricatorRepositoryGitHubNotification' => 'applications/repository/storage/githubnotification',
'PhabricatorRepositoryGitHubPostReceiveController' => 'applications/repository/controller/github-post-receive',
'PhabricatorRepositoryListController' => 'applications/repository/controller/list',
'PhabricatorRepositoryShortcut' => 'applications/repository/storage/shortcut',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/svn',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/svn',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/svn',
'PhabricatorRepositoryType' => 'applications/repository/constants/repositorytype',
'PhabricatorS3FileStorageEngine' => 'applications/files/engine/s3',
'PhabricatorSQLPatchList' => 'infrastructure/setup/sql',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/abstractdocument',
'PhabricatorSearchAttachController' => 'applications/search/controller/attach',
'PhabricatorSearchBaseController' => 'applications/search/controller/base',
'PhabricatorSearchCommitIndexer' => 'applications/search/index/indexer/repository',
'PhabricatorSearchController' => 'applications/search/controller/search',
'PhabricatorSearchDAO' => 'applications/search/storage/base',
'PhabricatorSearchDifferentialIndexer' => 'applications/search/index/indexer/differential',
'PhabricatorSearchDocument' => 'applications/search/storage/document/document',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/field',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/indexer/base',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/relationship',
'PhabricatorSearchEngine' => 'applications/search/engine/base',
'PhabricatorSearchEngineMySQL' => 'applications/search/engine/mysql',
'PhabricatorSearchEngineSelector' => 'applications/search/selector/base',
'PhabricatorSearchField' => 'applications/search/constants/field',
'PhabricatorSearchIndexController' => 'applications/search/controller/index',
'PhabricatorSearchManiphestIndexer' => 'applications/search/index/indexer/maniphest',
'PhabricatorSearchPhrictionIndexer' => 'applications/search/index/indexer/phriction',
'PhabricatorSearchQuery' => 'applications/search/storage/query',
'PhabricatorSearchRelationship' => 'applications/search/constants/relationship',
'PhabricatorSearchResultView' => 'applications/search/view/searchresult',
'PhabricatorSearchSelectController' => 'applications/search/controller/select',
'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/user',
'PhabricatorSetup' => 'infrastructure/setup',
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/choice',
'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/comment',
'PhabricatorSlowvoteController' => 'applications/slowvote/controller/base',
'PhabricatorSlowvoteCreateController' => 'applications/slowvote/controller/create',
'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/base',
'PhabricatorSlowvoteListController' => 'applications/slowvote/controller/list',
'PhabricatorSlowvoteOption' => 'applications/slowvote/storage/option',
'PhabricatorSlowvotePoll' => 'applications/slowvote/storage/poll',
'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/poll',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorStatusController' => 'applications/status/base',
'PhabricatorSyntaxHighlighter' => 'applications/markup/syntax',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
'PhabricatorTestCase' => 'infrastructure/testing/testcase',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/cursor',
'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/base',
'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/event',
'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/eventdata',
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
'PhabricatorTimer' => 'applications/countdown/storage/timer',
'PhabricatorTransformedFile' => 'applications/files/storage/transformed',
'PhabricatorTrivialTestCase' => 'infrastructure/testing/testcase/__tests__',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
'PhabricatorUIExample' => 'applications/uiexample/examples/base',
'PhabricatorUIExampleController' => 'applications/uiexample/controller/base',
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/render',
'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/listfilter',
'PhabricatorUIPagerExample' => 'applications/uiexample/examples/pager',
'PhabricatorUser' => 'applications/people/storage/user',
'PhabricatorUserAccountSettingsPanelController' => 'applications/people/controller/settings/panels/account',
'PhabricatorUserConduitSettingsPanelController' => 'applications/people/controller/settings/panels/conduit',
'PhabricatorUserDAO' => 'applications/people/storage/base',
'PhabricatorUserEmailSettingsPanelController' => 'applications/people/controller/settings/panels/email',
'PhabricatorUserLog' => 'applications/people/storage/log',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
'PhabricatorUserOAuthSettingsPanelController' => 'applications/people/controller/settings/panels/oauth',
'PhabricatorUserPreferenceSettingsPanelController' => 'applications/people/controller/settings/panels/preferences',
'PhabricatorUserPreferences' => 'applications/people/storage/preferences',
'PhabricatorUserProfile' => 'applications/people/storage/profile',
'PhabricatorUserProfileSettingsPanelController' => 'applications/people/controller/settings/panels/profile',
'PhabricatorUserSSHKey' => 'applications/people/storage/usersshkey',
'PhabricatorUserSSHKeysSettingsPanelController' => 'applications/people/controller/settings/panels/sshkeys',
'PhabricatorUserSettingsController' => 'applications/people/controller/settings',
'PhabricatorUserSettingsPanelController' => 'applications/people/controller/settings/panels/base',
'PhabricatorWorker' => 'infrastructure/daemon/workers/worker',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/base',
'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/task',
'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/taskdata',
'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/workertaskdetail',
'PhabricatorXHPASTViewController' => 'applications/xhpastview/controller/base',
'PhabricatorXHPASTViewDAO' => 'applications/xhpastview/storage/base',
'PhabricatorXHPASTViewFrameController' => 'applications/xhpastview/controller/viewframe',
'PhabricatorXHPASTViewFramesetController' => 'applications/xhpastview/controller/viewframeset',
'PhabricatorXHPASTViewInputController' => 'applications/xhpastview/controller/viewinput',
'PhabricatorXHPASTViewPanelController' => 'applications/xhpastview/controller/viewpanel',
'PhabricatorXHPASTViewParseTree' => 'applications/xhpastview/storage/parsetree',
'PhabricatorXHPASTViewRunController' => 'applications/xhpastview/controller/run',
'PhabricatorXHPASTViewStreamController' => 'applications/xhpastview/controller/viewstream',
'PhabricatorXHPASTViewTreeController' => 'applications/xhpastview/controller/viewtree',
'PhabricatorXHProfController' => 'applications/xhprof/controller/base',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
'PhrictionActionConstants' => 'applications/phriction/constants/action',
'PhrictionConstants' => 'applications/phriction/constants/base',
'PhrictionContent' => 'applications/phriction/storage/content',
'PhrictionController' => 'applications/phriction/controller/base',
'PhrictionDAO' => 'applications/phriction/storage/base',
'PhrictionDiffController' => 'applications/phriction/controller/diff',
'PhrictionDocument' => 'applications/phriction/storage/document',
'PhrictionDocumentController' => 'applications/phriction/controller/document',
'PhrictionDocumentPreviewController' => 'applications/phriction/controller/documentpreview',
'PhrictionDocumentTestCase' => 'applications/phriction/storage/document/__tests__',
'PhrictionEditController' => 'applications/phriction/controller/edit',
'PhrictionHistoryController' => 'applications/phriction/controller/history',
'PhrictionListController' => 'applications/phriction/controller/list',
),
'function' =>
array(
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
'_qsprintf_check_type' => 'storage/qsprintf',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api',
'celerity_register_resource_map' => 'infrastructure/celerity/map',
'javelin_render_tag' => 'infrastructure/javelin/markup',
'phabricator_date' => 'view/utils',
'phabricator_datetime' => 'view/utils',
'phabricator_format_relative_time' => 'view/utils',
'phabricator_format_timestamp' => 'view/utils',
'phabricator_format_units_generic' => 'view/utils',
'phabricator_render_form' => 'infrastructure/javelin/markup',
'phabricator_time' => 'view/utils',
'qsprintf' => 'storage/qsprintf',
'queryfx' => 'storage/queryfx',
'queryfx_all' => 'storage/queryfx',
'queryfx_one' => 'storage/queryfx',
'require_celerity_resource' => 'infrastructure/celerity/api',
'vqsprintf' => 'storage/qsprintf',
'vqueryfx' => 'storage/queryfx',
'vqueryfx_all' => 'storage/queryfx',
'xsprintf_query' => 'storage/qsprintf',
),
'requires_class' =>
array(
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront404Response' => 'AphrontResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontAttachedFileView' => 'AphrontView',
'AphrontCSRFException' => 'AphrontException',
'AphrontCalendarMonthView' => 'AphrontView',
'AphrontContextBarView' => 'AphrontView',
'AphrontCrumbsView' => 'AphrontView',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDefaultApplicationController' => 'AphrontController',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontFilePreviewView' => 'AphrontView',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormLayoutView' => 'AphrontView',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontHeadsupActionListView' => 'AphrontView',
'AphrontHeadsupActionView' => 'AphrontView',
'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
'AphrontListFilterView' => 'AphrontView',
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
'AphrontNullView' => 'AphrontView',
'AphrontPageView' => 'AphrontView',
'AphrontPagerView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontQueryAccessDeniedException' => 'AphrontQueryRecoverableException',
'AphrontQueryConnectionException' => 'AphrontQueryException',
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
'AphrontQueryCountException' => 'AphrontQueryException',
'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontReloadResponse' => 'AphrontRedirectResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontWebpageResponse' => 'AphrontResponse',
'CelerityResourceController' => 'AphrontController',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getalldiffs_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updatetaskrevisionassoc_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_publish_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_maniphest_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_create_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_paste_info_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_path_getowners_Method' => 'ConduitAPIMethod',
'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_whoami_Method' => 'ConduitAPIMethod',
'DarkConsoleConfigPlugin' => 'DarkConsolePlugin',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DifferentialAddCommentView' => 'AphrontView',
'DifferentialAuxiliaryField' => 'DifferentialDAO',
'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' => 'DifferentialDAO',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO',
'DifferentialDefaultFieldSelector' => 'DifferentialFieldSelector',
'DifferentialDiff' => 'DifferentialDAO',
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
'DifferentialDiffProperty' => 'DifferentialDAO',
'DifferentialDiffTableOfContentsView' => 'AphrontView',
'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialExceptionMail' => 'DifferentialMail',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialInlineComment' => 'DifferentialDAO',
'DifferentialInlineCommentEditController' => 'DifferentialController',
'DifferentialInlineCommentPreviewController' => 'DifferentialController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialPrimaryPaneView' => 'AphrontView',
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSubscribeController' => 'DifferentialController',
'DifferentialViewTime' => 'DifferentialDAO',
'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommitChangeTableView' => 'DiffusionView',
'DiffusionCommitController' => 'DiffusionController',
'DiffusionCommitListController' => 'DiffusionController',
'DiffusionController' => 'PhabricatorController',
'DiffusionDiffController' => 'DiffusionController',
'DiffusionGitBranchQuery' => 'DiffusionBranchQuery',
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionGitDiffQuery' => 'DiffusionDiffQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHomeController' => 'DiffusionController',
'DiffusionLastModifiedController' => 'DiffusionController',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionRepositoryController' => 'DiffusionController',
'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionSvnDiffQuery' => 'DiffusionDiffQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
'DiffusionView' => 'AphrontView',
'HeraldAction' => 'HeraldDAO',
'HeraldApplyTranscript' => 'HeraldDAO',
'HeraldCommitAdapter' => 'HeraldObjectAdapter',
'HeraldCondition' => 'HeraldDAO',
'HeraldController' => 'PhabricatorController',
'HeraldDAO' => 'PhabricatorLiskDAO',
'HeraldDeleteController' => 'HeraldController',
'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter',
'HeraldDryRunAdapter' => 'HeraldObjectAdapter',
'HeraldHomeController' => 'HeraldController',
'HeraldNewController' => 'HeraldController',
'HeraldRule' => 'HeraldDAO',
'HeraldRuleController' => 'HeraldController',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTranscript' => 'HeraldDAO',
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController',
'LiskIsolationTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestDAO' => 'LiskDAO',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'ManiphestAuxiliaryFieldSpecification',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
+ 'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions',
'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
'ManiphestTask' => 'ManiphestDAO',
'ManiphestTaskAuxiliaryStorage' => 'ManiphestDAO',
'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskOwner' => 'ManiphestConstants',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskProject' => 'ManiphestDAO',
'ManiphestTaskStatus' => 'ManiphestConstants',
'ManiphestTaskSubscriber' => 'ManiphestDAO',
'ManiphestTaskSummaryView' => 'ManiphestView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'ManiphestView',
'ManiphestTransactionListView' => 'ManiphestView',
'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController',
'ManiphestTransactionType' => 'ManiphestConstants',
'ManiphestView' => 'AphrontView',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController',
'PhabricatorCalendarController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
'PhabricatorController' => 'AphrontController',
'PhabricatorCountdownController' => 'PhabricatorController',
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonController' => 'PhabricatorController',
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEventsView' => 'AphrontView',
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
'PhabricatorDaemonLogListView' => 'AphrontView',
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector',
'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO',
'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorFeedController' => 'PhabricatorController',
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
'PhabricatorFeedStoryUnknown' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryView' => 'PhabricatorFeedView',
'PhabricatorFeedStreamController' => 'PhabricatorFeedController',
'PhabricatorFeedView' => 'AphrontView',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
'PhabricatorFileImageMacro' => 'PhabricatorFileDAO',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileMacroDeleteController' => 'PhabricatorFileController',
'PhabricatorFileMacroEditController' => 'PhabricatorFileController',
'PhabricatorFileMacroListController' => 'PhabricatorFileController',
'PhabricatorFileProxyController' => 'PhabricatorFileController',
'PhabricatorFileProxyImage' => 'PhabricatorFileDAO',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
'PhabricatorIRCBot' => 'PhabricatorDaemon',
'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler',
'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler',
'PhabricatorJavelinLinter' => 'ArcanistLinter',
'PhabricatorLintEngine' => 'PhutilLintEngine',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTADaemon' => 'PhabricatorDaemon',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGithub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorObjectGraph' => 'AbstractDirectedGraph',
'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants',
'PhabricatorOwnersController' => 'PhabricatorController',
'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPackage' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPaste' => 'PhabricatorPasteDAO',
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteCreateController' => 'PhabricatorPasteController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteListController' => 'PhabricatorPasteController',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorProfileView' => 'AphrontView',
'PhabricatorProject' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliation' => 'PhabricatorProjectDAO',
'PhabricatorProjectAffiliationEditController' => 'PhabricatorProjectController',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
'PhabricatorProjectSubproject' => 'PhabricatorProjectDAO',
'PhabricatorRedirectController' => 'PhabricatorController',
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleDifferentialHandle' => 'PhabricatorRemarkupRuleObjectHandle',
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRuleManiphestHandle' => 'PhabricatorRemarkupRuleObjectHandle',
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObjectHandle' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObjectName' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRulePaste' => 'PhabricatorRemarkupRuleObjectName',
'PhabricatorRemarkupRulePhriction' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleProxyImage' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
'PhabricatorRepository' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryCommitTaskDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDaemon' => 'PhabricatorDaemon',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'PhabricatorRepositoryCommitMessageDetailParser',
'PhabricatorRepositoryDeleteController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryGitFetchDaemon' => 'PhabricatorRepositoryDaemon',
'PhabricatorRepositoryGitHubNotification' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryGitHubPostReceiveController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryShortcut' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorSearchAttachController' => 'PhabricatorSearchController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchCommitIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDifferentialIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchEngineMySQL' => 'PhabricatorSearchEngine',
'PhabricatorSearchIndexController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchManiphestIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchPhrictionIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSelectController' => 'PhabricatorSearchController',
'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteController' => 'PhabricatorController',
'PhabricatorSlowvoteCreateController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteDAO' => 'PhabricatorLiskDAO',
'PhabricatorSlowvoteListController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePoll' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController',
'PhabricatorStandardPageView' => 'AphrontPageView',
'PhabricatorStatusController' => 'PhabricatorController',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
'PhabricatorTimer' => 'PhabricatorCountdownDAO',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTrivialTestCase' => 'PhabricatorTestCase',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUIExampleController' => 'PhabricatorController',
'PhabricatorUIExampleRenderController' => 'PhabricatorUIExampleController',
'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
'PhabricatorUser' => 'PhabricatorUserDAO',
'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserEmailSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserLog' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSSHKey' => 'PhabricatorUserDAO',
'PhabricatorUserSSHKeysSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSettingsController' => 'PhabricatorPeopleController',
'PhabricatorUserSettingsPanelController' => 'PhabricatorPeopleController',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
'PhabricatorXHPASTViewController' => 'PhabricatorController',
'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'AphrontView',
'PhabricatorXHProfProfileTopLevelView' => 'AphrontView',
'PhrictionActionConstants' => 'PhrictionConstants',
'PhrictionContent' => 'PhrictionDAO',
'PhrictionController' => 'PhabricatorController',
'PhrictionDAO' => 'PhabricatorLiskDAO',
'PhrictionDiffController' => 'PhrictionController',
'PhrictionDocument' => 'PhrictionDAO',
'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentPreviewController' => 'PhrictionController',
'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
'PhrictionEditController' => 'PhrictionController',
'PhrictionHistoryController' => 'PhrictionController',
'PhrictionListController' => 'PhrictionController',
),
'requires_interface' =>
array(
),
));
diff --git a/src/applications/conduit/method/maniphest/info/ConduitAPI_maniphest_info_Method.php b/src/applications/conduit/method/maniphest/info/ConduitAPI_maniphest_info_Method.php
index d6f15cc48d..a24b9a39b6 100644
--- a/src/applications/conduit/method/maniphest/info/ConduitAPI_maniphest_info_Method.php
+++ b/src/applications/conduit/method/maniphest/info/ConduitAPI_maniphest_info_Method.php
@@ -1,72 +1,77 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_maniphest_info_Method extends ConduitAPIMethod {
public function getMethodDescription() {
return "Retrieve information about a Maniphest task, given its id.";
}
public function defineParamTypes() {
return array(
'task_id' => 'required id',
);
}
public function defineReturnType() {
return 'nonempty dict';
}
public function defineErrorTypes() {
return array(
'ERR_BAD_TASK' => 'No such maniphest task exists',
);
}
protected function execute(ConduitAPIRequest $request) {
$task_id = $request->getValue('task_id');
$task = id(new ManiphestTask())->load($task_id);
if (!$task) {
throw new ConduitException('ERR_BAD_TASK');
}
+ $auxiliary = $task->loadAuxiliaryAttributes();
+ $auxiliary = mpull($auxiliary, 'getValue', 'getName');
+
$result = array(
'id' => $task->getID(),
'phid' => $task->getPHID(),
'authorPHID' => $task->getAuthorPHID(),
'ownerPHID' => $task->getAuthorPHID(),
'ccPHIDs' => $task->getCCPHIDs(),
'status' => $task->getStatus(),
'priority' => ManiphestTaskPriority::getTaskPriorityName(
$task->getPriority()),
'title' => $task->getTitle(),
'description' => $task->getDescription(),
'projectPHIDs' => $task->getProjectPHIDs(),
'uri' => PhabricatorEnv::getProductionURI('/T'.$task->getID()),
+ 'auxiliary' => $auxiliary,
+
// Not sure what this is yet.
// 'attached' => array($task->getAttached()),
);
return $result;
}
}
diff --git a/src/applications/maniphest/auxiliaryfield/default/ManiphestAuxiliaryFieldDefaultSpecification.php b/src/applications/maniphest/auxiliaryfield/default/ManiphestAuxiliaryFieldDefaultSpecification.php
index ecaa2e8d1b..d6bbfc7022 100644
--- a/src/applications/maniphest/auxiliaryfield/default/ManiphestAuxiliaryFieldDefaultSpecification.php
+++ b/src/applications/maniphest/auxiliaryfield/default/ManiphestAuxiliaryFieldDefaultSpecification.php
@@ -1,137 +1,139 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
class ManiphestAuxiliaryFieldDefaultSpecification
extends ManiphestAuxiliaryFieldSpecification {
private $required;
private $fieldType;
private $selectOptions;
private $error;
const TYPE_SELECT = 'select';
const TYPE_STRING = 'string';
const TYPE_INT = 'int';
public function getFieldType() {
return $this->fieldType;
}
public function setFieldType($val) {
$this->fieldType = $val;
+ return $this;
}
public function getError() {
return $this->error;
}
public function setError($val) {
$this->error = $val;
+ return $this;
}
public function getSelectOptions() {
return $this->selectOptions;
}
public function setSelectOptions($array) {
$this->selectOptions = $array;
+ return $this;
}
public function setRequired($bool) {
$this->required = $bool;
+ return $this;
}
public function isRequired() {
return $this->required;
}
public function renderControl() {
$control = null;
switch ($this->getFieldType()) {
case self::TYPE_INT:
$control = new AphrontFormTextControl();
break;
case self::TYPE_STRING:
$control = new AphrontFormTextControl();
break;
case self::TYPE_SELECT:
$control = new AphrontFormSelectControl();
$control->setOptions($this->getSelectOptions());
break;
default:
throw new ManiphestAuxiliaryFieldTypeException(
$this->getFieldType().' is not a valid type for '.$this->getLabel()
);
break;
}
$control->setValue($this->getValue());
$control->setLabel($this->getLabel());
+ $control->setCaption($this->getCaption());
$control->setName('auxiliary['.$this->getAuxiliaryKey().']');
$control->setError($this->getError());
return $control;
}
public function setValueFromRequest($request) {
$aux_post_values = $request->getArr('auxiliary');
-
- $this->setValue(
- $aux_post_values[$this->getAuxiliaryKey()]
- );
+ $this->setValue(idx($aux_post_values, $this->getAuxiliaryKey()));
}
public function getValueForStorage() {
return $this->getValue();
}
public function setValueFromStorage($value) {
$this->setValue($value);
}
public function validate() {
switch ($this->getFieldType()) {
case self::TYPE_INT:
if (!is_numeric($this->getValue())) {
throw new ManiphestAuxiliaryFieldValidationException(
$this->getLabel().' must be an integer value.'
);
}
break;
case self::TYPE_STRING:
return true;
break;
case self::TYPE_SELECT:
return true;
break;
}
}
}
diff --git a/src/applications/maniphest/auxiliaryfield/default/__init__.php b/src/applications/maniphest/auxiliaryfield/default/__init__.php
index c6a28123c7..950c3a4495 100644
--- a/src/applications/maniphest/auxiliaryfield/default/__init__.php
+++ b/src/applications/maniphest/auxiliaryfield/default/__init__.php
@@ -1,16 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/maniphest/auxiliaryfield/base');
phutil_require_module('phabricator', 'applications/maniphest/auxiliaryfield/typeexception');
phutil_require_module('phabricator', 'applications/maniphest/auxiliaryfield/validationexception');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/text');
+phutil_require_module('phutil', 'utils');
+
phutil_require_source('ManiphestAuxiliaryFieldDefaultSpecification.php');
diff --git a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
index ff869b418a..176f66afa3 100644
--- a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
+++ b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php
@@ -1,472 +1,472 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
class ManiphestTaskDetailController extends ManiphestController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$e_title = null;
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
$task = id(new ManiphestTask())->load($this->id);
if (!$task) {
return new Aphront404Response();
}
$workflow = $request->getStr('workflow');
$parent_task = null;
if ($workflow && is_numeric($workflow)) {
$parent_task = id(new ManiphestTask())->load($workflow);
}
- $aux_fields = id(new ManiphestDefaultTaskExtensions())
- ->getAuxiliaryFieldSpecifications();
+ $extensions = ManiphestTaskExtensions::newExtensions();
+ $aux_fields = $extensions->getAuxiliaryFieldSpecifications();
$transactions = id(new ManiphestTransaction())->loadAllWhere(
'taskID = %d ORDER BY id ASC',
$task->getID());
$phids = array();
foreach ($transactions as $transaction) {
foreach ($transaction->extractPHIDs() as $phid) {
$phids[$phid] = true;
}
}
foreach ($task->getCCPHIDs() as $phid) {
$phids[$phid] = true;
}
foreach ($task->getProjectPHIDs() as $phid) {
$phids[$phid] = true;
}
if ($task->getOwnerPHID()) {
$phids[$task->getOwnerPHID()] = true;
}
$phids[$task->getAuthorPHID()] = true;
$attached = $task->getAttached();
foreach ($attached as $type => $list) {
foreach ($list as $phid => $info) {
$phids[$phid] = true;
}
}
if ($parent_task) {
$phids[$parent_task->getPHID()] = true;
}
$phids = array_keys($phids);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$engine = PhabricatorMarkupEngine::newManiphestMarkupEngine();
$dict = array();
$dict['Status'] =
'<strong>'.
ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()).
'</strong>';
$dict['Assigned To'] = $task->getOwnerPHID()
? $handles[$task->getOwnerPHID()]->renderLink()
: '<em>None</em>';
$dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName(
$task->getPriority());
$cc = $task->getCCPHIDs();
if ($cc) {
$cc_links = array();
foreach ($cc as $phid) {
$cc_links[] = $handles[$phid]->renderLink();
}
$dict['CC'] = implode(', ', $cc_links);
} else {
$dict['CC'] = '<em>None</em>';
}
$dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
$projects = $task->getProjectPHIDs();
if ($projects) {
$project_links = array();
foreach ($projects as $phid) {
$project_links[] = $handles[$phid]->renderLink();
}
$dict['Projects'] = implode(', ', $project_links);
} else {
$dict['Projects'] = '<em>None</em>';
}
if ($aux_fields) {
foreach ($aux_fields as $aux_field) {
$attribute = $task->loadAuxiliaryAttribute(
$aux_field->getAuxiliaryKey()
);
if ($attribute) {
$aux_field->setValue($attribute->getValue());
}
$dict[$aux_field->getLabel()] = $aux_field->renderForDetailView();
}
}
$dtasks = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_TASK);
if ($dtasks) {
$dtask_links = array();
foreach ($dtasks as $dtask => $info) {
$dtask_links[] = $handles[$dtask]->renderLink();
}
$dtask_links = implode('<br />', $dtask_links);
$dict['Depends On'] = $dtask_links;
}
$revs = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV);
if ($revs) {
$rev_links = array();
foreach ($revs as $rev => $info) {
$rev_links[] = $handles[$rev]->renderLink();
}
$rev_links = implode('<br />', $rev_links);
$dict['Revisions'] = $rev_links;
}
$file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
if ($file_infos) {
$file_phids = array_keys($file_infos);
$files = id(new PhabricatorFile())->loadAllWhere(
'phid IN (%Ls)',
$file_phids);
$views = array();
foreach ($files as $file) {
$view = new AphrontFilePreviewView();
$view->setFile($file);
$views[] = $view->render();
}
$dict['Files'] = implode('', $views);
}
$dict['Description'] =
'<div class="maniphest-task-description">'.
'<div class="phabricator-remarkup">'.
$engine->markupText($task->getDescription()).
'</div>'.
'</div>';
require_celerity_resource('mainphest-task-detail-css');
$table = array();
foreach ($dict as $key => $value) {
$table[] =
'<tr>'.
'<th>'.phutil_escape_html($key).':</th>'.
'<td>'.$value.'</td>'.
'</tr>';
}
$table =
'<table class="maniphest-task-properties">'.
implode("\n", $table).
'</table>';
$context_bar = null;
if ($parent_task) {
$context_bar = new AphrontContextBarView();
$context_bar->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/task/create/?parent='.$parent_task->getID(),
'class' => 'green button',
),
'Create Another Subtask'));
$context_bar->appendChild(
'Created a subtask of <strong>'.
$handles[$parent_task->getPHID()]->renderLink().
'</strong>');
} else if ($workflow == 'create') {
$context_bar = new AphrontContextBarView();
$context_bar->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/task/create/?template='.$task->getID(),
'class' => 'green button',
),
'Create Another Task'));
$context_bar->appendChild('New task created.');
}
$actions = array();
$action = new AphrontHeadsupActionView();
$action->setName('Edit Task');
$action->setURI('/maniphest/task/edit/'.$task->getID().'/');
$action->setClass('action-edit');
$actions[] = $action;
require_celerity_resource('phabricator-object-selector-css');
require_celerity_resource('javelin-behavior-phabricator-object-selector');
$action = new AphrontHeadsupActionView();
$action->setName('Merge Duplicates');
$action->setURI('/search/attach/'.$task->getPHID().'/TASK/merge/');
$action->setWorkflow(true);
$action->setClass('action-merge');
$actions[] = $action;
$action = new AphrontHeadsupActionView();
$action->setName('Create Subtask');
$action->setURI('/maniphest/task/create/?parent='.$task->getID());
$action->setClass('action-branch');
$actions[] = $action;
$action = new AphrontHeadsupActionView();
$action->setName('Edit Dependencies');
$action->setURI('/search/attach/'.$task->getPHID().'/TASK/dependencies/');
$action->setWorkflow(true);
$action->setClass('action-dependencies');
$actions[] = $action;
$action = new AphrontHeadsupActionView();
$action->setName('Edit Differential Revisions');
$action->setURI('/search/attach/'.$task->getPHID().'/DREV/');
$action->setWorkflow(true);
$action->setClass('action-attach');
$actions[] = $action;
$action_list = new AphrontHeadsupActionListView();
$action_list->setActions($actions);
$panel =
'<div class="maniphest-panel">'.
$action_list->render().
'<div class="maniphest-task-detail-core">'.
'<h1>'.
'<span class="aphront-headsup-object-name">'.
phutil_escape_html('T'.$task->getID()).
'</span>'.
' '.
phutil_escape_html($task->getTitle()).
'</h1>'.
$table.
'</div>'.
'</div>';
$transaction_types = ManiphestTransactionType::getTransactionTypeMap();
$resolution_types = ManiphestTaskStatus::getTaskStatusMap();
if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
$resolution_types = array_select_keys(
$resolution_types,
array(
ManiphestTaskStatus::STATUS_CLOSED_RESOLVED,
ManiphestTaskStatus::STATUS_CLOSED_WONTFIX,
ManiphestTaskStatus::STATUS_CLOSED_INVALID,
ManiphestTaskStatus::STATUS_CLOSED_SPITE,
));
} else {
$resolution_types = array(
ManiphestTaskStatus::STATUS_OPEN => 'Reopened',
);
$transaction_types[ManiphestTransactionType::TYPE_STATUS] =
'Reopen Task';
unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
}
$default_claim = array(
$user->getPHID() => $user->getUsername().' ('.$user->getRealName().')',
);
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
$user->getPHID(),
$task->getPHID());
if ($draft) {
$draft_text = $draft->getDraft();
} else {
$draft_text = null;
}
$panel_id = celerity_generate_unique_node_id();
$comment_form = new AphrontFormView();
$comment_form
->setUser($user)
->setAction('/maniphest/transaction/save/')
->setEncType('multipart/form-data')
->addHiddenInput('taskID', $task->getID())
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Action')
->setName('action')
->setOptions($transaction_types)
->setID('transaction-action'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Resolution')
->setName('resolution')
->setControlID('resolution')
->setControlStyle('display: none')
->setOptions($resolution_types))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Assign To')
->setName('assign_to')
->setControlID('assign_to')
->setControlStyle('display: none')
->setID('assign-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('CCs')
->setName('ccs')
->setControlID('ccs')
->setControlStyle('display: none')
->setID('cc-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Priority')
->setName('priority')
->setOptions($priority_map)
->setControlID('priority')
->setControlStyle('display: none')
->setValue($task->getPriority()))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Projects')
->setName('projects')
->setControlID('projects')
->setControlStyle('display: none')
->setID('projects-tokenizer')
->setDisableBehavior(true))
->appendChild(
id(new AphrontFormFileControl())
->setLabel('File')
->setName('file')
->setControlID('file')
->setControlStyle('display: none'))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Comments')
->setName('comments')
->setValue($draft_text)
->setID('transaction-comments'))
->appendChild(
id(new AphrontFormDragAndDropUploadControl())
->setLabel('Attached Files')
->setName('files')
->setDragAndDropTarget($panel_id)
->setActivatedClass('aphront-panel-view-drag-and-drop'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Avast!'));
$control_map = array(
ManiphestTransactionType::TYPE_STATUS => 'resolution',
ManiphestTransactionType::TYPE_OWNER => 'assign_to',
ManiphestTransactionType::TYPE_CCS => 'ccs',
ManiphestTransactionType::TYPE_PRIORITY => 'priority',
ManiphestTransactionType::TYPE_PROJECTS => 'projects',
ManiphestTransactionType::TYPE_ATTACH => 'file',
);
Javelin::initBehavior('maniphest-transaction-controls', array(
'select' => 'transaction-action',
'controlMap' => $control_map,
'tokenizers' => array(
ManiphestTransactionType::TYPE_PROJECTS => array(
'id' => 'projects-tokenizer',
'src' => '/typeahead/common/projects/',
),
ManiphestTransactionType::TYPE_OWNER => array(
'id' => 'assign-tokenizer',
'src' => '/typeahead/common/users/',
'value' => $default_claim,
'limit' => 1,
),
ManiphestTransactionType::TYPE_CCS => array(
'id' => 'cc-tokenizer',
'src' => '/typeahead/common/mailable/',
),
),
));
Javelin::initBehavior('maniphest-transaction-preview', array(
'uri' => '/maniphest/transaction/preview/'.$task->getID().'/',
'preview' => 'transaction-preview',
'comments' => 'transaction-comments',
'action' => 'transaction-action',
'map' => $control_map,
));
$comment_panel = new AphrontPanelView();
$comment_panel->appendChild($comment_form);
$comment_panel->setID($panel_id);
$comment_panel->addClass('aphront-panel-accent');
$comment_panel->setHeader('Weigh In');
$preview_panel =
'<div class="aphront-panel-preview">
<div id="transaction-preview">
<div class="aphront-panel-preview-loading-text">
Loading preview...
</div>
</div>
</div>';
$transaction_view = new ManiphestTransactionListView();
$transaction_view->setTransactions($transactions);
$transaction_view->setHandles($handles);
$transaction_view->setUser($user);
$transaction_view->setMarkupEngine($engine);
return $this->buildStandardPageResponse(
array(
$context_bar,
$panel,
$transaction_view,
$comment_panel,
$preview_panel,
),
array(
'title' => 'T'.$task->getID().' '.$task->getTitle(),
));
}
}
diff --git a/src/applications/maniphest/controller/taskdetail/__init__.php b/src/applications/maniphest/controller/taskdetail/__init__.php
index 38252741af..a8641f5343 100644
--- a/src/applications/maniphest/controller/taskdetail/__init__.php
+++ b/src/applications/maniphest/controller/taskdetail/__init__.php
@@ -1,42 +1,42 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/draft/storage/draft');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/maniphest/constants/priority');
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
-phutil_require_module('phabricator', 'applications/maniphest/extensions/task');
+phutil_require_module('phabricator', 'applications/maniphest/extensions/base');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
phutil_require_module('phabricator', 'applications/maniphest/view/transactionlist');
phutil_require_module('phabricator', 'applications/markup/engine');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/draganddropupload');
phutil_require_module('phabricator', 'view/form/control/file');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/control/tokenizer');
phutil_require_module('phabricator', 'view/layout/contextbar');
phutil_require_module('phabricator', 'view/layout/filepreview');
phutil_require_module('phabricator', 'view/layout/headsup/action');
phutil_require_module('phabricator', 'view/layout/headsup/actionlist');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTaskDetailController.php');
diff --git a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
index 2059bf89a7..c33c4a3a3e 100644
--- a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
+++ b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php
@@ -1,475 +1,474 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
class ManiphestTaskEditController extends ManiphestController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$files = array();
$parent_task = null;
$template_id = null;
if ($this->id) {
$task = id(new ManiphestTask())->load($this->id);
if (!$task) {
return new Aphront404Response();
}
} else {
$task = new ManiphestTask();
$task->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
$task->setAuthorPHID($user->getPHID());
// These allow task creation with defaults.
if (!$request->isFormPost()) {
$task->setTitle($request->getStr('title'));
$default_projects = $request->getStr('projects');
if ($default_projects) {
$task->setProjectPHIDs(explode(';', $default_projects));
}
}
$file_phids = $request->getArr('files', array());
if (!$file_phids) {
// Allow a single 'file' key instead, mostly since Mac OS X urlencodes
// square brackets in URLs when passed to 'open', so you can't 'open'
// a URL like '?files[]=xyz' and have PHP interpret it correctly.
$phid = $request->getStr('file');
if ($phid) {
$file_phids = array($phid);
}
}
if ($file_phids) {
$files = id(new PhabricatorFile())->loadAllWhere(
'phid IN (%Ls)',
$file_phids);
}
$template_id = $request->getInt('template');
// You can only have a parent task if you're creating a new task.
$parent_id = $request->getInt('parent');
if ($parent_id) {
$parent_task = id(new ManiphestTask())->load($parent_id);
}
}
$errors = array();
$e_title = true;
- $aux_fields = id(new ManiphestDefaultTaskExtensions())
- ->getAuxiliaryFieldSpecifications();
+ $extensions = ManiphestTaskExtensions::newExtensions();
+ $aux_fields = $extensions->getAuxiliaryFieldSpecifications();
if ($request->isFormPost()) {
$changes = array();
$new_title = $request->getStr('title');
$new_desc = $request->getStr('description');
$new_status = $request->getStr('status');
$workflow = '';
if ($task->getID()) {
if ($new_title != $task->getTitle()) {
$changes[ManiphestTransactionType::TYPE_TITLE] = $new_title;
}
if ($new_desc != $task->getDescription()) {
$changes[ManiphestTransactionType::TYPE_DESCRIPTION] = $new_desc;
}
if ($new_status != $task->getStatus()) {
$changes[ManiphestTransactionType::TYPE_STATUS] = $new_status;
}
} else {
$task->setTitle($new_title);
$task->setDescription($new_desc);
$changes[ManiphestTransactionType::TYPE_STATUS] =
ManiphestTaskStatus::STATUS_OPEN;
$workflow = 'create';
}
$owner_tokenizer = $request->getArr('assigned_to');
$owner_phid = reset($owner_tokenizer);
if (!strlen($new_title)) {
$e_title = 'Required';
$errors[] = 'Title is required.';
}
foreach ($aux_fields as $aux_field) {
$aux_field->setValueFromRequest($request);
if ($aux_field->isRequired() && !strlen($aux_field->getValue())) {
$errors[] = $aux_field->getLabel() . ' is required.';
$aux_field->setError('Required');
}
if (strlen($aux_field->getValue())) {
try {
$aux_field->validate();
} catch (Exception $e) {
$errors[] = $e->getMessage();
$aux_field->setError('Invalid');
}
}
}
if ($errors) {
$task->setPriority($request->getInt('priority'));
$task->setOwnerPHID($owner_phid);
$task->setCCPHIDs($request->getArr('cc'));
$task->setProjectPHIDs($request->getArr('projects'));
} else {
if ($request->getInt('priority') != $task->getPriority()) {
$changes[ManiphestTransactionType::TYPE_PRIORITY] =
$request->getInt('priority');
}
if ($owner_phid != $task->getOwnerPHID()) {
$changes[ManiphestTransactionType::TYPE_OWNER] = $owner_phid;
}
if ($request->getArr('cc') != $task->getCCPHIDs()) {
$changes[ManiphestTransactionType::TYPE_CCS] = $request->getArr('cc');
}
$new_proj_arr = $request->getArr('projects');
$new_proj_arr = array_values($new_proj_arr);
sort($new_proj_arr);
$cur_proj_arr = $task->getProjectPHIDs();
$cur_proj_arr = array_values($cur_proj_arr);
sort($cur_proj_arr);
if ($new_proj_arr != $cur_proj_arr) {
$changes[ManiphestTransactionType::TYPE_PROJECTS] = $new_proj_arr;
}
if ($files) {
$file_map = mpull($files, 'getPHID');
$file_map = array_fill_keys($file_map, true);
$changes[ManiphestTransactionType::TYPE_ATTACH] = array(
PhabricatorPHIDConstants::PHID_TYPE_FILE => $file_map,
);
}
$template = new ManiphestTransaction();
$template->setAuthorPHID($user->getPHID());
$transactions = array();
foreach ($changes as $type => $value) {
$transaction = clone $template;
$transaction->setTransactionType($type);
$transaction->setNewValue($value);
$transactions[] = $transaction;
}
if ($transactions) {
$editor = new ManiphestTransactionEditor();
$editor->applyTransactions($task, $transactions);
}
// TODO: Capture auxiliary field changes in a transaction
foreach ($aux_fields as $aux_field) {
$task->setAuxiliaryAttribute(
$aux_field->getAuxiliaryKey(),
$aux_field->getValueForStorage()
);
}
if ($parent_task) {
$type_task = PhabricatorPHIDConstants::PHID_TYPE_TASK;
// NOTE: It's safe to simply apply this transaction without doing
// cycle detection because we know the new task has no children.
$new_value = $parent_task->getAttached();
$new_value[$type_task][$task->getPHID()] = true;
$parent_xaction = clone $template;
$attach_type = ManiphestTransactionType::TYPE_ATTACH;
$parent_xaction->setTransactionType($attach_type);
$parent_xaction->setNewValue($new_value);
$editor = new ManiphestTransactionEditor();
$editor->applyTransactions($parent_task, array($parent_xaction));
$workflow = $parent_task->getID();
}
$redirect_uri = '/T'.$task->getID();
if ($workflow) {
$redirect_uri .= '?workflow='.$workflow;
}
return id(new AphrontRedirectResponse())
->setURI($redirect_uri);
}
} else {
if (!$task->getID()) {
$task->setCCPHIDs(array(
$user->getPHID(),
));
if ($template_id) {
$template_task = id(new ManiphestTask())->load($template_id);
if ($template_task) {
$task->setCCPHIDs($template_task->getCCPHIDs());
$task->setProjectPHIDs($template_task->getProjectPHIDs());
$task->setOwnerPHID($template_task->getOwnerPHID());
}
}
}
}
$phids = array_merge(
array($task->getOwnerPHID()),
$task->getCCPHIDs(),
$task->getProjectPHIDs());
if ($parent_task) {
$phids[] = $parent_task->getPHID();
}
$phids = array_filter($phids);
$phids = array_unique($phids);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles($phids);
$tvalues = mpull($handles, 'getFullName', 'getPHID');
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
$error_view->setTitle('Form Errors');
}
$priority_map = ManiphestTaskPriority::getTaskPriorityMap();
if ($task->getOwnerPHID()) {
$assigned_value = array(
$task->getOwnerPHID() => $handles[$task->getOwnerPHID()]->getFullName(),
);
} else {
$assigned_value = array();
}
if ($task->getCCPHIDs()) {
$cc_value = array_select_keys($tvalues, $task->getCCPHIDs());
} else {
$cc_value = array();
}
if ($task->getProjectPHIDs()) {
$projects_value = array_select_keys($tvalues, $task->getProjectPHIDs());
} else {
$projects_value = array();
}
$cancel_id = nonempty($task->getID(), $template_id);
if ($cancel_id) {
$cancel_uri = '/T'.$cancel_id;
} else {
$cancel_uri = '/maniphest/';
}
if ($task->getID()) {
$button_name = 'Save Task';
$header_name = 'Edit Task';
} else if ($parent_task) {
$cancel_uri = '/T'.$parent_task->getID();
$button_name = 'Create Task';
$header_name = 'Create New Subtask';
} else {
$button_name = 'Create Task';
$header_name = 'Create New Task';
}
$project_tokenizer_id = celerity_generate_unique_node_id();
$form = new AphrontFormView();
$form
->setUser($user)
->setAction($request->getRequestURI()->getPath())
->addHiddenInput('template', $template_id);
if ($parent_task) {
$form
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Parent Task')
->setValue($handles[$parent_task->getPHID()]->getFullName()))
->addHiddenInput('parent', $parent_task->getID());
}
$form
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Title')
->setName('title')
->setError($e_title)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
->setValue($task->getTitle()));
if ($task->getID()) {
// Only show this in "edit" mode, not "create" mode, since creating a
// non-open task is kind of silly and it would just clutter up the
// "create" interface.
$form
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Status')
->setName('status')
->setValue($task->getStatus())
->setOptions(ManiphestTaskStatus::getTaskStatusMap()));
}
$form
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Assigned To')
->setName('assigned_to')
->setValue($assigned_value)
->setDatasource('/typeahead/common/users/')
->setLimit(1))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('CC')
->setName('cc')
->setValue($cc_value)
->setDatasource('/typeahead/common/mailable/'))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel('Priority')
->setName('priority')
->setOptions($priority_map)
->setValue($task->getPriority()))
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel('Projects')
->setName('projects')
->setValue($projects_value)
->setID($project_tokenizer_id)
->setCaption(
javelin_render_tag(
'a',
array(
'href' => '/project/create/',
'mustcapture' => true,
'sigil' => 'project-create',
),
'Create New Project'))
->setDatasource('/typeahead/common/projects/'));
$attributes = $task->loadAuxiliaryAttributes();
$attributes = mpull($attributes, 'getValue', 'getName');
- foreach ($aux_fields as $aux_field)
- {
+ foreach ($aux_fields as $aux_field) {
if (!$request->isFormPost()) {
$attribute = null;
if (isset($attributes[$aux_field->getAuxiliaryKey()])) {
$attribute = $attributes[$aux_field->getAuxiliaryKey()];
$aux_field->setValueFromStorage($attribute);
}
}
if ($aux_field->isRequired() && !$aux_field->getError()
&& !$aux_field->getValue()) {
$aux_field->setError(true);
}
$aux_control = $aux_field->renderControl();
$form->appendChild($aux_control);
}
require_celerity_resource('aphront-error-view-css');
Javelin::initBehavior('maniphest-project-create', array(
'tokenizerID' => $project_tokenizer_id,
));
if ($files) {
$file_display = array();
foreach ($files as $file) {
$file_display[] = phutil_escape_html($file->getName());
}
$file_display = implode('<br />', $file_display);
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Files')
->setValue($file_display));
foreach ($files as $ii => $file) {
$form->addHiddenInput('files['.$ii.']', $file->getPHID());
}
}
$email_create = PhabricatorEnv::getEnvConfig(
'metamta.maniphest.public-create-email');
$email_hint = null;
if (!$task->getID() && $email_create) {
$email_hint = 'You can also create tasks by sending an email to: '.
'<tt>'.phutil_escape_html($email_create).'</tt>';
}
$form
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Description')
->setName('description')
->setCaption($email_hint)
->setValue($task->getDescription()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($button_name));
$panel = new AphrontPanelView();
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$panel->setHeader($header_name);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Create Task',
));
}
}
diff --git a/src/applications/maniphest/controller/taskedit/__init__.php b/src/applications/maniphest/controller/taskedit/__init__.php
index ff0eea8157..86b9ff37dc 100644
--- a/src/applications/maniphest/controller/taskedit/__init__.php
+++ b/src/applications/maniphest/controller/taskedit/__init__.php
@@ -1,40 +1,40 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/maniphest/constants/priority');
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
phutil_require_module('phabricator', 'applications/maniphest/controller/base');
phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
-phutil_require_module('phabricator', 'applications/maniphest/extensions/task');
+phutil_require_module('phabricator', 'applications/maniphest/extensions/base');
phutil_require_module('phabricator', 'applications/maniphest/storage/task');
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/markup');
phutil_require_module('phabricator', 'view/form/control/select');
phutil_require_module('phabricator', 'view/form/control/static');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/control/tokenizer');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestTaskEditController.php');
diff --git a/src/applications/maniphest/extensions/base/ManiphestTaskExtensions.php b/src/applications/maniphest/extensions/base/ManiphestTaskExtensions.php
new file mode 100644
index 0000000000..7fd8fb690d
--- /dev/null
+++ b/src/applications/maniphest/extensions/base/ManiphestTaskExtensions.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * Copyright 2011 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @group maniphest
+ */
+abstract class ManiphestTaskExtensions {
+
+ final public function __construct() {
+ // <empty>
+ }
+
+ abstract public function getAuxiliaryFieldSpecifications();
+
+
+ final public static function newExtensions() {
+ $key = 'maniphest.custom-task-extensions-class';
+ $class = PhabricatorEnv::getEnvConfig($key);
+ return newv($class, array());
+ }
+
+}
diff --git a/src/applications/maniphest/extensions/task/__init__.php b/src/applications/maniphest/extensions/base/__init__.php
similarity index 58%
copy from src/applications/maniphest/extensions/task/__init__.php
copy to src/applications/maniphest/extensions/base/__init__.php
index d0780ecbf3..500e40e1ab 100644
--- a/src/applications/maniphest/extensions/task/__init__.php
+++ b/src/applications/maniphest/extensions/base/__init__.php
@@ -1,15 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
-phutil_require_module('phabricator', 'applications/maniphest/auxiliaryfield/default');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'utils');
-phutil_require_source('ManiphestDefaultTaskExtensions.php');
+phutil_require_source('ManiphestTaskExtensions.php');
diff --git a/src/applications/maniphest/extensions/task/ManiphestDefaultTaskExtensions.php b/src/applications/maniphest/extensions/task/ManiphestDefaultTaskExtensions.php
index ade609daba..2793f83520 100644
--- a/src/applications/maniphest/extensions/task/ManiphestDefaultTaskExtensions.php
+++ b/src/applications/maniphest/extensions/task/ManiphestDefaultTaskExtensions.php
@@ -1,46 +1,47 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
-final class ManiphestDefaultTaskExtensions {
+final class ManiphestDefaultTaskExtensions
+ extends ManiphestTaskExtensions {
public function getAuxiliaryFieldSpecifications() {
$fields = PhabricatorEnv::getEnvConfig('maniphest.custom-fields');
$specs = array();
foreach ($fields as $aux => $info) {
$spec = new ManiphestAuxiliaryFieldDefaultSpecification();
$spec->setAuxiliaryKey($aux);
$spec->setLabel(idx($info, 'label'));
$spec->setCaption(idx($info, 'caption'));
$spec->setFieldType(idx($info, 'type'));
$spec->setRequired(idx($info, 'required'));
if ($spec->getFieldType() ==
ManiphestAuxiliaryFieldDefaultSpecification::TYPE_SELECT) {
$spec->setSelectOptions(idx($info, 'options'));
}
$specs[] = $spec;
}
return $specs;
}
}
diff --git a/src/applications/maniphest/extensions/task/__init__.php b/src/applications/maniphest/extensions/task/__init__.php
index d0780ecbf3..642ebb9ac5 100644
--- a/src/applications/maniphest/extensions/task/__init__.php
+++ b/src/applications/maniphest/extensions/task/__init__.php
@@ -1,15 +1,16 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/maniphest/auxiliaryfield/default');
+phutil_require_module('phabricator', 'applications/maniphest/extensions/base');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'utils');
phutil_require_source('ManiphestDefaultTaskExtensions.php');
diff --git a/src/docs/userguide/maniphest_custom.diviner b/src/docs/userguide/maniphest_custom.diviner
new file mode 100644
index 0000000000..c7f74fe64e
--- /dev/null
+++ b/src/docs/userguide/maniphest_custom.diviner
@@ -0,0 +1,66 @@
+@title Maniphest User Guide: Adding Custom Fields
+@group userguide
+
+How to add custom fields to Maniphest.
+
+= Overview =
+
+Maniphest provides some support for adding new fields to tasks, like an
+"cost" field, a "milestone" field, etc.
+
+NOTE: Currently, these fields are somewhat limited. They primarily give you a
+structured way to record data on tasks, but there isn't much support for
+bringing them into other interfaces (e.g., querying by them, aggregating them,
+drawing graphs, etc.). If you have a use case, let us know what you want to do
+and maybe we can figure something out. This data is also exposed via the Conduit
+API, so you might be able to write your own interface if you want to do
+something very custom.
+
+= Simple Field Customization =
+
+If you don't need complicated display controls or sophisticated validation, you
+can add simple fields. These allow you to attach things like strings, numbers,
+and dropdown menus to the task template.
+
+Customize Maniphest fields by setting ##maniphest.custom-fields## in your
+configuration. For example, suppose you want to add "Estimated Hours" and
+"Actual Hours" fields. To do this, set your configuration like this:
+
+ 'maniphest.custom-fields' => array(
+ 'mycompany:estimated-hours' => array(
+ 'label' => 'Estimated Hours',
+ 'type' => 'int',
+ 'caption' => 'Estimated number of hours this will take.',
+ 'required' => false,
+ ),
+ 'mycompany:actual-hours' => array(
+ 'label' => 'Actual Hours',
+ 'type' => 'int',
+ 'required' => false,
+ ),
+ )
+
+Each array key must be unique, and is used to organize the internal storage of
+the field. These options are available:
+
+ - **label**: Display label for the field on the edit and detail interfaces.
+ - **type**: Field type, one of **int**, **string** or **select**.
+ - **caption**: A caption to display underneath the field (optional).
+ - **required**: True if the user should be required to provide a value.
+ - **options**: If type is set to **select**, provide options for the dropdown
+ as a dictionary.
+
+= Advanced Field Customization =
+
+If you want to add fields with more specialized validation, storage, or
+rendering logic, you can do so with a little work:
+
+ - Extend @{class:ManiphestAuxiliaryFieldSpecification} and implement
+ your specialized rendering, validation, storage, etc., logic.
+ - Extend @{class:ManiphestTaskExtensions} and return a list of fields which
+ includes your custom field objects.
+ - Set 'maniphest.custom-extensions' to the name of your new extensions
+ class.
+
+This is relatively advanced but should give you significant flexibility in
+defining custom fields.

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 2, 1:43 PM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164943
Default Alt Text
(163 KB)

Event Timeline