+
+You can also use create named links, where you choose the displayed text. These
+work within Phorge or on the internet at large:
+
+ [[/herald/transcript/ | Herald Transcripts]]
+ [[http://www.boring-legal-documents.com/ | exciting legal documents]]
+
+Markdown-style links are also supported:
+
+ [Toil](http://www.trouble.com)
+
+= Linking to Objects =
+
+You can link to Phorge objects, such as Differential revisions, Diffusion
+commits and Maniphest tasks, by mentioning the name of an object:
+
+ D123 # Link to Differential revision D123
+ rX123 # Link to SVN commit 123 from the "X" repository
+ rXaf3192cd5 # Link to Git commit "af3192cd5..." from the "X" repository.
+ # You must specify at least 7 characters of the hash.
+ T123 # Link to Maniphest task T123
+
+You can also link directly to a comment in Maniphest and Differential (these
+can be found on the date stamp of any transaction/comment):
+
+ T123#412 # Link to comment id #412 of task T123
+
+See the Phorge configuration setting `remarkup.ignored-object-names` to
+modify this behavior.
+
+= Embedding Objects
+
+You can also generate full-name references to some objects by using braces:
+
+ {D123} # Link to Differential revision D123 with the full name
+ {T123} # Link to Maniphest task T123 with the full name
+
+These references will also show when an object changes state (for instance, a
+task or revision is closed). Some types of objects support rich embedding.
+
+== Linking to Project Tags
+
+Projects can be linked to with the use of a hashtag `#`. This works by default
+using the name of the Project (lowercase, underscored). Additionally you
+can set multiple additional hashtags by editing the Project details.
+
+ #qa, #quality_assurance
+
+== Embedding Mocks (Pholio)
+
+You can embed a Pholio mock by using braces to refer to it:
+
+ {M123}
+
+By default the first four images from the mock set are displayed. This behavior
+can be overridden with the **image** option. With the **image** option you can
+provide one or more image IDs to display.
+
+You can set the image (or images) to display like this:
+
+ {M123, image=12345}
+ {M123, image=12345 & 6789}
+
+== Embedding Pastes
+
+You can embed a Paste using braces:
+
+ {P123}
+
+You can adjust the embed height with the `lines` option:
+
+ {P123, lines=15}
+
+You can highlight specific lines with the `highlight` option:
+
+ {P123, highlight=15}
+ {P123, highlight="23-25, 31"}
+
+== Embedding Images
+
+You can embed an image or other file by using braces to refer to it:
+
+ {F123}
+
+In most interfaces, you can drag-and-drop an image from your computer into the
+text area to upload and reference it.
+
+Some browsers (e.g. Chrome) support uploading an image data just by pasting them
+from clipboard into the text area.
+
+You can set file display options like this:
+
+ {F123, layout=left, float, size=full, alt="a duckling"}
+
+Valid options for all files are:
+
+ - **layout** left (default), center, right, inline, link (render a link
+ instead of a thumbnail for images)
+ - **name** with `layout=link` or for non-images, use this name for the link
+ text
+ - **alt** Provide alternate text for assistive technologies.
+
+Image files support these options:
+
+ - **float** If layout is set to left or right, the image will be floated so
+ text wraps around it.
+ - **size** thumb (default), full
+ - **width** Scale image to a specific width.
+ - **height** Scale image to a specific height.
+
+Audio and video files support these options:
+
+ - **media**: Specify the media type as `audio` or `video`. This allows you
+ to disambiguate how file format which may contain either audio or video
+ should be rendered.
+ - **loop**: Loop this media.
+ - **autoplay**: Automatically begin playing this media.
+
+== Embedding Countdowns
+
+You can embed a countdown by using braces:
+
+ {C123}
+
+= Quoting Text =
+
+To quote text, preface it with an `>`:
+
+ > This is quoted text.
+
+This appears like this:
+
+> This is quoted text.
+
+= Embedding Media =
+
+If you set a configuration flag, you can embed media directly in text:
+
+ - **remarkup.enable-embedded-youtube**: allows you to paste in YouTube videos
+ and have them render inline.
+
+This option is disabled by default because it has security and/or
+silliness implications. Carefully read the description before enabling it.
+
+= Image Macros =
+
+You can upload image macros (More Stuff -> Macro) which will replace text
+strings with the image you specify. For instance, you could upload an image of a
+dancing banana to create a macro named "peanutbutterjellytime", and then any
+time you type that string on a separate line it will be replaced with the image
+of a dancing banana.
+
+= Memes =
+
+You can also use image macros in the context of memes. For example, if you
+have an image macro named `grumpy`, you can create a meme by doing the
+following:
+
+ {meme, src = grumpy, above = toptextgoeshere, below = bottomtextgoeshere}
+
+By default, the font used to create the text for the meme is `tuffy.ttf`. For
+the more authentic feel of `impact.ttf`, you simply have to place the Impact
+TrueType font in the Phorge subfolder `/resources/font/`. If Remarkup
+detects the presence of `impact.ttf`, it will automatically use it.
+
+= Mentioning Users =
+
+In Differential and Maniphest, you can mention another user by writing:
+
+ @username
+
+When you submit your comment, this will add them as a CC on the revision or task
+if they aren't already CC'd.
+
+Icons
+=====
+
+You can add icons to comments using the `{icon ...}` syntax. For example:
+
+ {icon camera}
+
+This renders: {icon camera}
+
+You can select a color for icons:
+
+ {icon camera color=blue}
+
+This renders: {icon camera color=blue}
+
+For a list of available icons and colors, check the UIExamples application.
+(The icons are sourced from
+[[ https://fontawesome.com/v4.7.0/icons/ | FontAwesome ]], so you can also
+browse the collection there.)
+
+You can add `spin` to make the icon spin:
+
+ {icon cog spin}
+
+This renders: {icon cog spin}
+
+
+= Phriction Documents =
+
+You can link to Phriction documents with a name or path:
+
+ Make sure you sign and date your [[legal/Letter of Marque and Reprisal]]!
+
+By default, the link will render with the document title as the link name.
+With a pipe (`|`), you can retitle the link. Use this to mislead your
+opponents:
+
+ Check out these [[legal/boring_documents/ | exciting legal documents]]!
+
+Links to pages which do not exist are shown in red. Links to pages which exist
+but which the viewer does not have permission to see are shown with a lock
+icon, and the link will not disclose the page title.
+
+If you begin a link path with `./` or `../`, the remainder of the path will be
+evaluated relative to the current wiki page. For example, if you are writing
+content for the document `fruit/` a link to `[[./guava]]` is the same as a link
+to `[[fruit/guava]]` from elsewhere.
+
+Relative links may use `../` to transverse up the document tree. From the
+`produce/vegetables/` page, you can use `[[../fruit/guava]]` to link to the
+`produce/fruit/guava` page.
+
+Relative links do not work when used outside of wiki pages. For example,
+you can't use a relative link in a comment on a task, because there is no
+reasonable place for the link to start resolving from.
+
+When documents are moved, relative links are not automatically updated: they
+are preserved as currently written. After moving a document, you may need to
+review and adjust any relative links it contains.
+
+
+= Literal Blocks =
+
+To place text in a literal block use `%%%`:
+
+ %%%Text that won't be processed by remarkup
+ [[http://www.example.com | example]]
+ %%%
+
+Remarkup will not process the text inside of literal blocks (other than to
+escape HTML and preserve line breaks).
+
+= Tables =
+
+Remarkup supports simple table syntax. For example, this:
+
+```
+| Fruit | Color | Price | Peel?
+| ----- | ----- | ----- | -----
+| Apple | red | `\$0.93` | no
+| Banana | yellow | `\$0.19` | **YES**
+```
+
+...produces this:
+
+| Fruit | Color | Price | Peel?
+| ----- | ----- | ----- | -----
+| Apple | red | `\$0.93` | no
+| Banana | yellow | `\$0.19` | **YES**
+
+Remarkup also supports a simplified HTML table syntax. For example, this:
+
+```
+
+
+ Fruit |
+ Color |
+ Price |
+ Peel? |
+
+
+ Apple |
+ red |
+ `\$0.93` |
+ no |
+
+
+ Banana |
+ yellow |
+ `\$0.19` |
+ **YES** |
+
+
+```
+
+...produces this:
+
+
+
+ Fruit |
+ Color |
+ Price |
+ Peel? |
+
+
+ Apple |
+ red |
+ `\$0.93` |
+ no |
+
+
+ Banana |
+ yellow |
+ `\$0.19` |
+ **YES** |
+
+
+
+Some general notes about this syntax:
+
+ - your tags must all be properly balanced;
+ - your tags must NOT include attributes (`` is OK, ` | ` is
+ not);
+ - you can use other Remarkup rules (like **bold**, //italics//, etc.) inside
+ table cells.
+
+Navigation Sequences
+====================
+
+You can use `{nav ...}` to render a stylized navigation sequence when helping
+someone to locate something. This can be useful when writing documentation.
+For example, you could give someone directions to purchase lemons:
+
+{nav icon=home, name=Home >
+Grocery Store >
+Produce Section >
+icon=lemon-o, name=Lemons}
+
+To render this example, use this markup:
+
+```
+{nav icon=home, name=Home >
+Grocery Store >
+Produce Section >
+icon=lemon-o, name=Lemons}
+```
+
+In general:
+
+ - Separate sections with `>`.
+ - Each section can just have a name to add an element to the navigation
+ sequence, or a list of key-value pairs.
+ - Supported keys are `icon`, `name`, `type` and `href`.
+ - The `type` option can be set to `instructions` to indicate that an element
+ is asking the user to make a choice or follow specific instructions.
+
+Keystrokes
+==========
+
+You can use `{key ...}` to render a stylized keystroke. For example, this:
+
+```
+Press {key M} to view the starmap.
+```
+
+...renders this:
+
+> Press {key M} to view the starmap.
+
+You can also render sequences with modifier keys. This:
+
+```
+Use {key command option shift 3} to take a screenshot.
+Press {key down down-right right LP} to activate the hadoken technique.
+```
+
+...renders this:
+
+> Use {key command option shift 3} to take a screenshot.
+> Press {key down down-right right LP} to activate the hadoken technique.
+
+
+Anchors
+========
+
+You can use `{anchor #xyz}` to create a document anchor and later link to
+it directly with `#xyz` in the URI.
+
+Headers also automatically create named anchors.
+
+If you navigate to `#xyz` in your browser location bar, the page will scroll
+to the first anchor with "xyz" as a prefix of the anchor name.
+
+
+= Fullscreen Mode =
+
+Remarkup editors provide a fullscreen composition mode. This can make it easier
+to edit large blocks of text, or improve focus by removing distractions. You can
+exit **Fullscreen** mode by clicking the button again or by pressing escape.
+EOTEXT;
+
+ $remarkup_syntax_documentation_providers = id(new PhutilClassMapQuery())
+ ->setAncestorClass('RemarkupSyntaxDocumentationProvider')
+ ->execute();
+
+ // add custom Remarkup help
+ $content .= "\r\n\r\n";
+ foreach ($remarkup_syntax_documentation_providers as $doc_provider) {
+ $content .= $doc_provider->getDocumentation()."\r\n\r\n";
+ }
+
+ return $content;
+ }
+}
diff --git a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
index 48eabf1545..8294f6832e 100644
--- a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
+++ b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
@@ -341,8 +341,8 @@ final class PhabricatorRepositoryPullLocalDaemon
* With the `$consume` flag, an internal cursor will also be incremented so
* that these messages are not returned by subsequent calls.
*
- * @param bool Pass `true` to consume these messages, so the process will
- * not see them again.
+ * @param bool? $consume Pass `true` to consume these messages, so the
+ * process will not see them again.
* @return list Pending update messages.
*
* @task pull
diff --git a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
index 8f5b346ecd..7d66868f50 100644
--- a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
@@ -538,7 +538,7 @@ final class PhabricatorRepositoryDiscoveryEngine
*
* @task internal
*
- * @param list List of refs.
+ * @param list $refs List of refs.
* @return list Sorted list of refs.
*/
private function sortRefs(array $refs) {
diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
index 5bcf4554fd..af4cd95d0a 100644
--- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
@@ -602,22 +602,6 @@ final class PhabricatorRepositoryPullEngine
return $map;
}
- private function loadGitLocalRefs(PhabricatorRepository $repository) {
- $refs = id(new DiffusionLowLevelGitRefQuery())
- ->setRepository($repository)
- ->execute();
-
- $map = array();
- foreach ($refs as $ref) {
- $fields = $ref->getRawFields();
- $map[idx($fields, 'refname')] = $ref->getCommitIdentifier();
- }
-
- ksort($map);
-
- return $map;
- }
-
private function logRefDifferences(array $remote, array $local) {
$all = $local + $remote;
@@ -756,7 +740,7 @@ final class PhabricatorRepositoryPullEngine
* error message. To prevent this, censor response bodies out of error
* messages.
*
- * @param string Uncensored Mercurial command output.
+ * @param string $message Uncensored Mercurial command output.
* @return string Censored Mercurial command output.
*/
private function censorMercurialErrorMessage($message) {
diff --git a/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php b/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
index 60a96578a3..6cb9f27384 100644
--- a/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
@@ -233,7 +233,7 @@ final class PhabricatorRepositoryRefEngine
* point at commits which no longer exist. This can make commands issued later
* fail. See T5839 for discussion.
*
- * @param list List of commit identifiers.
+ * @param list $identifiers List of commit identifiers.
* @return list List with nonexistent identifiers removed.
*/
private function removeMissingCommits(array $identifiers) {
diff --git a/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php b/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php
index c4adc61ab0..2d9c36fae7 100644
--- a/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php
+++ b/src/applications/repository/graphcache/PhabricatorRepositoryGraphCache.php
@@ -64,10 +64,10 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
/**
* Search the graph cache for the most modification to a path.
*
- * @param int The commit ID to search ancestors of.
- * @param int The path ID to search for changes to.
- * @param float Maximum number of seconds to spend trying to satisfy this
- * query using the graph cache. By default, `0.5` (500ms).
+ * @param int $commit_id The commit ID to search ancestors of.
+ * @param int $path_id The path ID to search for changes to.
+ * @param float $time Maximum number of seconds to spend trying to satisfy
+ * this query using the graph cache. By default `0.5` (500ms).
* @return mixed Commit ID, or `null` if no ancestors exist, or `false` if
* the graph cache was unable to determine the answer.
* @task query
@@ -189,7 +189,7 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
/**
* Get the bucket key for a given commit ID.
*
- * @param int Commit ID.
+ * @param int $commit_id Commit ID.
* @return int Bucket key.
* @task cache
*/
@@ -201,7 +201,7 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
/**
* Get the cache key for a given bucket key (from @{method:getBucketKey}).
*
- * @param int Bucket key.
+ * @param int $bucket_key Bucket key.
* @return string Cache key.
* @task cache
*/
@@ -235,9 +235,10 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
* Normally, this operates as a readthrough cache call. It can also be used
* to force a cache update by passing the existing data to `$rebuild_data`.
*
- * @param int Bucket key, from @{method:getBucketKey}.
- * @param mixed Current data, to force a cache rebuild of this bucket.
- * @return array Data from the cache.
+ * @param int $bucket_key Bucket key, from @{method:getBucketKey}.
+ * @param mixed? $rebuild_data Current data, to force a cache rebuild of
+ * this bucket.
+ * @return array Data from the cache.
* @task cache
*/
private function getBucketData($bucket_key, $rebuild_data = null) {
@@ -287,9 +288,9 @@ final class PhabricatorRepositoryGraphCache extends Phobject {
/**
* Rebuild a cache bucket, amending existing data if available.
*
- * @param int Bucket key, from @{method:getBucketKey}.
- * @param array Existing bucket data.
- * @return array Rebuilt bucket data.
+ * @param int $bucket_key Bucket key, from @{method:getBucketKey}.
+ * @param array $current_data Existing bucket data.
+ * @return array Rebuilt bucket data.
* @task cache
*/
private function rebuildBucket($bucket_key, array $current_data) {
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
index b2855c0c06..b9aab043ad 100644
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1288,7 +1288,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
/**
* Determine if a protocol is SSH or SSH-like.
*
- * @param string A protocol string, like "http" or "ssh".
+ * @param string $protocol A protocol string, like "http" or "ssh".
* @return bool True if the protocol is SSH-like.
* @task uri
*/
@@ -1701,7 +1701,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
* 2037). We adjust the pull frequency based on when the most recent commit
* occurred.
*
- * @param int The minimum update interval to use, in seconds.
+ * @param int? $minimum The minimum update interval to use, in seconds.
* @return int Repository update interval, in seconds.
*/
public function loadUpdateInterval($minimum = 15) {
@@ -1836,8 +1836,8 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
* with repository services. This method provides lower-level resolution of
* services, returning raw URIs.
*
- * @param PhabricatorUser Viewing user.
- * @param map Constraints on selectable services.
+ * @param PhabricatorUser $viewer Viewing user.
+ * @param map $options Constraints on selectable services.
* @return string|null URI, or `null` for local repositories.
*/
public function getAlmanacServiceURI(
@@ -2168,8 +2168,8 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
*
* For lower-level service resolution, see @{method:getAlmanacServiceURI}.
*
- * @param PhabricatorUser Viewing user.
- * @param bool `true` to throw if a client would be returned.
+ * @param PhabricatorUser $viewer Viewing user.
+ * @param bool? $never_proxy `true` to throw if a client would be returned.
* @return ConduitClient|null Client, or `null` for local repositories.
*/
public function newConduitClient(
diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php
index d8f53538e4..5178a1a1d9 100644
--- a/src/applications/search/controller/PhabricatorApplicationSearchController.php
+++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php
@@ -346,6 +346,15 @@ final class PhabricatorApplicationSearchController
$body[] = $pager_box;
}
}
+ } catch (PhabricatorTypeaheadLoginRequiredException $ex) {
+
+ // A specific token requires login. Show login page.
+ $auth_class = PhabricatorAuthApplication::class;
+ $auth_application = PhabricatorApplication::getByClass($auth_class);
+ $login_controller = new PhabricatorAuthStartController();
+ $this->setCurrentApplication($auth_application);
+ return $this->delegateToController($login_controller);
+
} catch (PhabricatorTypeaheadInvalidTokenException $ex) {
$exec_errors[] = pht(
'This query specifies an invalid parameter. Review the '.
diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
index cad397b0ac..1979ec092a 100644
--- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
@@ -13,6 +13,7 @@
* @task read Reading Utilities
* @task exec Paging and Executing Queries
* @task render Rendering Results
+ * @task custom Custom Fields
*/
abstract class PhabricatorApplicationSearchEngine extends Phobject {
@@ -125,7 +126,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
/**
* Create a saved query object from the request.
*
- * @param AphrontRequest The search request.
+ * @param AphrontRequest $request The search request.
* @return PhabricatorSavedQuery
*/
public function buildSavedQueryFromRequest(AphrontRequest $request) {
@@ -146,7 +147,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
/**
* Executes the saved query.
*
- * @param PhabricatorSavedQuery The saved query to operate on.
+ * @param PhabricatorSavedQuery $original The saved query to operate on.
* @return PhabricatorQuery The result of the query.
*/
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $original) {
@@ -200,7 +201,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* hook to keep old queries working the way users expect, by reading,
* adjusting, and overwriting parameters.
*
- * @param PhabricatorSavedQuery Saved query which will be executed.
+ * @param PhabricatorSavedQuery $saved Saved query which will be executed.
* @return void
*/
protected function willUseSavedQuery(PhabricatorSavedQuery $saved) {
@@ -214,8 +215,8 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
/**
* Builds the search form using the request.
*
- * @param AphrontFormView Form to populate.
- * @param PhabricatorSavedQuery The query from which to build the form.
+ * @param AphrontFormView $form Form to populate.
+ * @param PhabricatorSavedQuery $saved Query from which to build the form.
* @return void
*/
public function buildSearchForm(
@@ -399,7 +400,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* Return an application URI corresponding to the results page of a query.
* Normally, this is something like `/application/query/QUERYKEY/`.
*
- * @param string The query key to build a URI for.
+ * @param string $query_key The query key to build a URI for.
* @return string URI where the query can be executed.
* @task uri
*/
@@ -729,9 +730,9 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* links to pages (like "alincoln's open revisions") without needing to make
* API calls.
*
- * @param AphrontRequest Request to read user PHIDs from.
- * @param string Key to read in the request.
- * @param list Other permitted PHID types.
+ * @param AphrontRequest $request Request to read user PHIDs from.
+ * @param string $key Key to read in the request.
+ * @param list? $allow_types Other permitted PHID types.
* @return list List of user PHIDs and selector functions.
* @task read
*/
@@ -781,8 +782,8 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
/**
* Read a list of subscribers from a request in a flexible way.
*
- * @param AphrontRequest Request to read PHIDs from.
- * @param string Key to read in the request.
+ * @param AphrontRequest $request Request to read PHIDs from.
+ * @param string $key Key to read in the request.
* @return list List of object PHIDs.
* @task read
*/
@@ -804,9 +805,10 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* comma-delimited forms. Objects can be specified either by PHID or by
* object name.
*
- * @param AphrontRequest Request to read PHIDs from.
- * @param string Key to read in the request.
- * @param list Optional, list of permitted PHID types.
+ * @param AphrontRequest $request Request to read PHIDs from.
+ * @param string $key Key to read in the request.
+ * @param list? $allow_types Optional, list of permitted PHID
+ * types.
* @return list List of object PHIDs.
*
* @task read
@@ -852,8 +854,8 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* This provides flexibility when constructing URIs, especially from external
* sources.
*
- * @param AphrontRequest Request to read strings from.
- * @param string Key to read in the request.
+ * @param AphrontRequest $request Request to read strings from.
+ * @param string $key Key to read in the request.
* @return list List of values.
*/
protected function readListFromRequest(
@@ -1071,7 +1073,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
if ($phids) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->requireViewer())
- ->witHPHIDs($phids)
+ ->withPHIDs($phids)
->execute();
} else {
$handles = array();
@@ -1453,6 +1455,12 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $attachments;
}
+ /**
+ * Render a content body (if available) to onboard new users.
+ * This body is usually visible when you have no elements in a list,
+ * or when you force the rendering on a list with the `?nux=1` URL.
+ * @return wild|PhutilSafeHTML|null
+ */
final public function renderNewUserView() {
$body = $this->getNewUserBody();
@@ -1463,6 +1471,12 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $body;
}
+ /**
+ * Get a content body to onboard new users.
+ * Traditionally this content is shown from an empty list, to explain
+ * what a certain entity does, and how to create a new one.
+ * @return wild|PhutilSafeHTML|null
+ */
protected function getNewUserHeader() {
return null;
}
@@ -1626,4 +1640,33 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $supported;
}
+ /**
+ * Load from object and from storage, and updates Custom Fields instances
+ * that are attached to each object.
+ *
+ * @return mapPhabricatorCustomFieldList> of loaded fields.
+ * @task custom
+ */
+ protected function loadCustomFields(array $objects, $role) {
+ assert_instances_of($objects, 'PhabricatorCustomFieldInterface');
+
+ $query = new PhabricatorCustomFieldStorageQuery();
+ $lists = array();
+
+ foreach ($objects as $object) {
+ $field_list = PhabricatorCustomField::getObjectFields($object, $role);
+ $field_list->readFieldsFromObject($object);
+ foreach ($field_list->getFields() as $field) {
+ // TODO move $viewer into PhabricatorCustomFieldStorageQuery
+ $field->setViewer($this->viewer);
+ }
+ $lists[$object->getPHID()] = $field_list;
+ $query->addFields($field_list->getFields());
+ }
+ // This updates the field_list objects.
+ $query->execute();
+
+ return $lists;
+ }
+
}
diff --git a/src/applications/search/engine/PhabricatorProfileMenuEngine.php b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
index 8799ae8f0b..7fbfe1c2da 100644
--- a/src/applications/search/engine/PhabricatorProfileMenuEngine.php
+++ b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
@@ -54,6 +54,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
$custom_phid = $this->getCustomPHID();
break;
case self::MODE_GLOBAL:
+ default:
$custom_phid = null;
break;
}
@@ -87,6 +88,9 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
abstract public function getItemURI($path);
abstract protected function isMenuEngineConfigurable();
+ /**
+ * @return array of PhabricatorProfileMenuItemConfiguration objects
+ */
abstract protected function getBuiltinProfileItems($object);
protected function getBuiltinCustomProfileItems(
@@ -465,15 +469,6 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
return $map;
}
- private function validateNavigationMenuItem($item) {
- if (!($item instanceof PHUIListItemView)) {
- throw new Exception(
- pht(
- 'Expected buildNavigationMenuItems() to return a list of '.
- 'PHUIListItemView objects, but got a surprise.'));
- }
- }
-
public function getConfigureURI() {
$mode = $this->getEditMode();
diff --git a/src/applications/search/field/PhabricatorSearchField.php b/src/applications/search/field/PhabricatorSearchField.php
index 36db0523b7..7b420ac8e6 100644
--- a/src/applications/search/field/PhabricatorSearchField.php
+++ b/src/applications/search/field/PhabricatorSearchField.php
@@ -33,7 +33,7 @@ abstract class PhabricatorSearchField extends Phobject {
* The key should be a short, unique (within a search engine) string which
* does not contain any special characters.
*
- * @param string Unique key which identifies the field.
+ * @param string $key Unique key which identifies the field.
* @return this
* @task config
*/
@@ -59,7 +59,7 @@ abstract class PhabricatorSearchField extends Phobject {
*
* This should be a short text string, like "Reviewers" or "Colors".
*
- * @param string Short, human-readable field label.
+ * @param string $label Short, human-readable field label.
* @return this
* task config
*/
@@ -86,7 +86,7 @@ abstract class PhabricatorSearchField extends Phobject {
* Engines do not need to do this explicitly; it will be done on their
* behalf by the caller.
*
- * @param PhabricatorUser Viewer.
+ * @param PhabricatorUser $viewer Viewer.
* @return this
* @task config
*/
@@ -115,7 +115,7 @@ abstract class PhabricatorSearchField extends Phobject {
* an alias like `authors` to let users write `&authors=alincoln` instead of
* `&authorPHIDs=alincoln`. This is a little easier to use.
*
- * @param list List of aliases for this field.
+ * @param list $aliases List of aliases for this field.
* @return this
* @task config
*/
@@ -142,7 +142,7 @@ abstract class PhabricatorSearchField extends Phobject {
* This can allow you to choose a more usable key for API endpoints.
* If no key is provided, the main key is used.
*
- * @param string Alternate key for Conduit.
+ * @param string $conduit_key Alternate key for Conduit.
* @return this
* @task config
*/
@@ -170,7 +170,7 @@ abstract class PhabricatorSearchField extends Phobject {
/**
* Set a human-readable description for this field.
*
- * @param string Human-readable description.
+ * @param string $description Human-readable description.
* @return this
* @task config
*/
@@ -194,7 +194,7 @@ abstract class PhabricatorSearchField extends Phobject {
/**
* Hide this field from the web UI.
*
- * @param bool True to hide the field from the web UI.
+ * @param bool $is_hidden True to hide the field from the web UI.
* @return this
* @task config
*/
@@ -400,8 +400,8 @@ abstract class PhabricatorSearchField extends Phobject {
* This provides flexibility when constructing URIs, especially from external
* sources.
*
- * @param AphrontRequest Request to read strings from.
- * @param string Key to read in the request.
+ * @param AphrontRequest $request Request to read strings from.
+ * @param string $key Key to read in the request.
* @return list List of values.
* @task utility
*/
diff --git a/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php b/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php
index ba019ea593..3745bbf35e 100644
--- a/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php
+++ b/src/applications/search/fulltextstorage/PhabricatorFulltextStorageEngine.php
@@ -47,7 +47,7 @@ abstract class PhabricatorFulltextStorageEngine extends Phobject {
/**
* Update the index for an abstract document.
*
- * @param PhabricatorSearchAbstractDocument Document to update.
+ * @param PhabricatorSearchAbstractDocument $document Document to update.
* @return void
*/
abstract public function reindexAbstractDocument(
@@ -56,7 +56,7 @@ abstract class PhabricatorFulltextStorageEngine extends Phobject {
/**
* Execute a search query.
*
- * @param PhabricatorSavedQuery A query to execute.
+ * @param PhabricatorSavedQuery $query A query to execute.
* @return list A list of matching PHIDs.
*/
abstract public function executeSearch(PhabricatorSavedQuery $query);
diff --git a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php
index 50d64072f5..6e84e28622 100644
--- a/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorEmailPreferencesSettingsPanel.php
@@ -97,14 +97,15 @@ final class PhabricatorEmailPreferencesSettingsPanel
'count' => 0,
'name' => $name,
);
+ } else {
+ $all_tags[$tag]['count']++;
}
- $all_tags[$tag]['count'];
}
}
$common_tags = array();
foreach ($all_tags as $tag => $info) {
- if ($info['count'] > 1) {
+ if ($info['count'] > 0) {
$common_tags[$tag] = $info['name'];
}
}
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanel.php b/src/applications/settings/panel/PhabricatorSettingsPanel.php
index e2efd92093..ac92a134c6 100644
--- a/src/applications/settings/panel/PhabricatorSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanel.php
@@ -222,7 +222,7 @@ abstract class PhabricatorSettingsPanel extends Phobject {
* Generally, render your settings panel by returning a form, then return
* a redirect when the user saves settings.
*
- * @param AphrontRequest Incoming request.
+ * @param AphrontRequest $request Incoming request.
* @return wild Response to request, either as an
* @{class:AphrontResponse} or something which can
* be composed into a @{class:AphrontView}.
@@ -234,7 +234,7 @@ abstract class PhabricatorSettingsPanel extends Phobject {
/**
* Get the URI for this panel.
*
- * @param string? Optional path to append.
+ * @param string? $path Optional path to append.
* @return string Relative URI for the panel.
* @task panel
*/
diff --git a/src/applications/settings/query/PhabricatorUserPreferencesQuery.php b/src/applications/settings/query/PhabricatorUserPreferencesQuery.php
index 5fa9b89bdd..5795b78f27 100644
--- a/src/applications/settings/query/PhabricatorUserPreferencesQuery.php
+++ b/src/applications/settings/query/PhabricatorUserPreferencesQuery.php
@@ -49,7 +49,8 @@ final class PhabricatorUserPreferencesQuery
* If no settings exist for a user, a new empty settings object with
* appropriate defaults is returned.
*
- * @param bool True to generate synthetic preferences for missing users.
+ * @param bool $synthetic True to generate synthetic preferences for missing
+ * users.
*/
public function needSyntheticPreferences($synthetic) {
$this->synthetic = $synthetic;
diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php
index 6cceff57de..f004361a29 100644
--- a/src/applications/settings/storage/PhabricatorUserPreferences.php
+++ b/src/applications/settings/storage/PhabricatorUserPreferences.php
@@ -119,7 +119,7 @@ final class PhabricatorUserPreferences
/**
* Load or create a preferences object for the given user.
*
- * @param PhabricatorUser User to load or create preferences for.
+ * @param PhabricatorUser $user User to load or create preferences for.
*/
public static function loadUserPreferences(PhabricatorUser $user) {
return id(new PhabricatorUserPreferencesQuery())
@@ -134,7 +134,7 @@ final class PhabricatorUserPreferences
*
* If no global preferences exist, an empty preferences object is returned.
*
- * @param PhabricatorUser Viewing user.
+ * @param PhabricatorUser $viewer Viewing user.
*/
public static function loadGlobalPreferences(PhabricatorUser $viewer) {
$global = id(new PhabricatorUserPreferencesQuery())
diff --git a/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php b/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
index 7ed83fb13f..1844a5f03c 100644
--- a/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
+++ b/src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
@@ -154,7 +154,7 @@ final class PhabricatorSlowvotePollController
return id(new PhabricatorApplicationTransactionCommentView())
->setUser($viewer)
- ->setObjectPHID($poll->getPHID())
+ ->setObject($poll)
->setDraft($draft)
->setHeaderText($add_comment_header)
->setAction($this->getApplicationURI('/comment/'.$poll->getID().'/'))
diff --git a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php
index 6703ed664e..6de31ff5c1 100644
--- a/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php
+++ b/src/applications/spaces/query/PhabricatorSpacesNamespaceQuery.php
@@ -212,7 +212,7 @@ final class PhabricatorSpacesNamespaceQuery
* This is intended to simplify performing a bunch of redundant checks; you
* can intentionally pass any value in (including `null`).
*
- * @param wild
+ * @param wild $object
* @return phid|null
*/
public static function getObjectSpacePHID($object) {
diff --git a/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php b/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php
index 3ee4b5f6e8..a36fed1c5d 100644
--- a/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php
+++ b/src/applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php
@@ -18,7 +18,7 @@ final class PhabricatorSubscriptionsEditor extends PhabricatorEditor {
* (or been subscribed) to the object, and will be added even if they
* had previously unsubscribed.
*
- * @param list List of PHIDs to explicitly subscribe.
+ * @param list $phids List of PHIDs to explicitly subscribe.
* @return this
*/
public function subscribeExplicit(array $phids) {
@@ -32,7 +32,7 @@ final class PhabricatorSubscriptionsEditor extends PhabricatorEditor {
* implicitly subscribes them (e.g., adding a comment) but it will be
* suppressed if they've previously unsubscribed from the object.
*
- * @param list List of PHIDs to implicitly subscribe.
+ * @param list $phids List of PHIDs to implicitly subscribe.
* @return this
*/
public function subscribeImplicit(array $phids) {
@@ -45,7 +45,7 @@ final class PhabricatorSubscriptionsEditor extends PhabricatorEditor {
* Unsubscribe PHIDs and mark them as unsubscribed, so implicit subscriptions
* will not resubscribe them.
*
- * @param list List of PHIDs to unsubscribe.
+ * @param list $phids List of PHIDs to unsubscribe.
* @return this
*/
public function unsubscribe(array $phids) {
diff --git a/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php b/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
index 2077160b7c..3d43d972f6 100644
--- a/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
+++ b/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
@@ -94,26 +94,33 @@ final class PhabricatorSubscriptionsUIEventListener
}
}
- $mute_action = id(new PhabricatorActionView())
- ->setWorkflow(true)
- ->setHref('/subscriptions/mute/'.$object->getPHID().'/')
- ->setDisabled(!$user_phid);
-
- if (!$is_muted) {
- $mute_action
- ->setName(pht('Mute Notifications'))
- ->setIcon('fa-volume-up');
- } else {
- $mute_action
- ->setName(pht('Unmute Notifications'))
- ->setIcon('fa-volume-off')
- ->setColor(PhabricatorActionView::RED);
- }
-
-
$actions = $event->getValue('actions');
$actions[] = $sub_action;
- $actions[] = $mute_action;
+
+ // Hide "Mute Notifications" in sidebar if not supported by Editor - T15378
+ $supported_editor_transaction_types =
+ array_fill_keys($object->getApplicationTransactionEditor()
+ ->getTransactionTypesForObject($object), true);
+ if (array_key_exists(PhabricatorTransactions::TYPE_EDGE,
+ $supported_editor_transaction_types)) {
+ $mute_action = id(new PhabricatorActionView())
+ ->setWorkflow(true)
+ ->setHref('/subscriptions/mute/'.$object->getPHID().'/')
+ ->setDisabled(!$user_phid);
+
+ if (!$is_muted) {
+ $mute_action
+ ->setName(pht('Mute Notifications'))
+ ->setIcon('fa-volume-up');
+ } else {
+ $mute_action
+ ->setName(pht('Unmute Notifications'))
+ ->setIcon('fa-volume-off')
+ ->setColor(PhabricatorActionView::RED);
+ }
+ $actions[] = $mute_action;
+ }
+
$event->setValue('actions', $actions);
}
diff --git a/src/applications/subscriptions/interface/PhabricatorSubscribableInterface.php b/src/applications/subscriptions/interface/PhabricatorSubscribableInterface.php
index 1af9e7107f..6528774ee8 100644
--- a/src/applications/subscriptions/interface/PhabricatorSubscribableInterface.php
+++ b/src/applications/subscriptions/interface/PhabricatorSubscribableInterface.php
@@ -8,7 +8,8 @@ interface PhabricatorSubscribableInterface {
* irrevocably a subscriber). This will, e.g., cause the UI to render
* "Automatically Subscribed" instead of "Subscribe".
*
- * @param PHID PHID (presumably a user) to test for automatic subscription.
+ * @param PHID $phid PHID (presumably a user) to test for automatic
+ * subscription.
* @return bool True if the object/user is automatically subscribed.
*/
public function isAutomaticallySubscribed($phid);
diff --git a/src/applications/system/engine/PhabricatorSystemActionEngine.php b/src/applications/system/engine/PhabricatorSystemActionEngine.php
index 6d6f9eacfd..106ef05e48 100644
--- a/src/applications/system/engine/PhabricatorSystemActionEngine.php
+++ b/src/applications/system/engine/PhabricatorSystemActionEngine.php
@@ -33,9 +33,9 @@ final class PhabricatorSystemActionEngine extends Phobject {
* If any actor is exceeding their rate limit, this method throws a
* @{class:PhabricatorSystemActionRateLimitException}.
*
- * @param list List of actors.
- * @param PhabricatorSystemAction Action being taken.
- * @param float Score or credit, see above.
+ * @param list $actors List of actors.
+ * @param PhabricatorSystemAction $action Action being taken.
+ * @param float $score Score or credit, see above.
* @return void
*/
public static function willTakeAction(
@@ -174,7 +174,7 @@ final class PhabricatorSystemActionEngine extends Phobject {
* Reset all action counts for actions taken by some set of actors in the
* previous action window.
*
- * @param list Actors to reset counts for.
+ * @param list $actors Actors to reset counts for.
* @return int Number of actions cleared.
*/
public static function resetActions(array $actors) {
diff --git a/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php b/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
index d80534ce73..87de9ee37b 100644
--- a/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
+++ b/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
@@ -8,7 +8,7 @@ final class PhabricatorBulkManagementExportWorkflow
->setName('export')
->setExamples('**export** [options]')
->setSynopsis(
- pht('Export data to a flat file (JSON, CSV, Excel, etc).'))
+ pht('Export data to a flat file (JSON, CSV, Excel, etc.).'))
->setArguments(
array(
array(
diff --git a/src/applications/transactions/constants/PhabricatorTransactions.php b/src/applications/transactions/constants/PhabricatorTransactions.php
index 3e31bdb1db..1f896d662d 100644
--- a/src/applications/transactions/constants/PhabricatorTransactions.php
+++ b/src/applications/transactions/constants/PhabricatorTransactions.php
@@ -41,4 +41,19 @@ final class PhabricatorTransactions extends Phobject {
);
}
+ /**
+ * Find the first transaction that matches a type.
+ * @param array $xactions
+ * @param string $type
+ * @return PhabricatorTransactions|null
+ */
+ public static function findOneByType($xactions, $type) {
+ foreach ($xactions as $xaction) {
+ if ($xaction->getTransactionType() === $type) {
+ return $xaction;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php
index f70e172a99..6b3aae2790 100644
--- a/src/applications/transactions/editengine/PhabricatorEditEngine.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php
@@ -339,7 +339,17 @@ abstract class PhabricatorEditEngine
return null;
}
-
+ /**
+ * Set default placeholder plain text in the comment textarea of the engine.
+ * To be overwritten by conditions defined in the child EditEngine class.
+ *
+ * @param object $object Object in which the comment textarea is displayed.
+ * @return string Placeholder text to display in the comment textarea.
+ * @task text
+ */
+ public function getCommentFieldPlaceholderText($object) {
+ return '';
+ }
/**
* Return a human-readable header describing what this engine is used to do,
@@ -668,7 +678,7 @@ abstract class PhabricatorEditEngine
* Initialize a new object for object creation via Conduit.
*
* @return object Newly initialized object.
- * @param list Raw transactions.
+ * @param list $raw_xactions Raw transactions.
* @task load
*/
protected function newEditableObjectFromConduit(array $raw_xactions) {
@@ -688,7 +698,7 @@ abstract class PhabricatorEditEngine
/**
* Flag this workflow as a create or edit.
*
- * @param bool True if this is a create workflow.
+ * @param bool $is_create True if this is a create workflow.
* @return this
* @task load
*/
@@ -702,9 +712,9 @@ abstract class PhabricatorEditEngine
* Try to load an object by ID, PHID, or monogram. This is done primarily
* to make Conduit a little easier to use.
*
- * @param wild ID, PHID, or monogram.
- * @param list List of required capability constants, or omit for
- * defaults.
+ * @param wild $identifier ID, PHID, or monogram.
+ * @param list? $capabilities List of required capability constants,
+ * or omit for defaults.
* @return object Corresponding editable object.
* @task load
*/
@@ -782,9 +792,9 @@ abstract class PhabricatorEditEngine
/**
* Load an object by ID.
*
- * @param int Object ID.
- * @param list List of required capability constants, or omit for
- * defaults.
+ * @param int $id Object ID.
+ * @param list? $capabilities List of required capability constants,
+ * or omit for defaults.
* @return object|null Object, or null if no such object exists.
* @task load
*/
@@ -799,9 +809,9 @@ abstract class PhabricatorEditEngine
/**
* Load an object by PHID.
*
- * @param phid Object PHID.
- * @param list List of required capability constants, or omit for
- * defaults.
+ * @param phid $phid Object PHID.
+ * @param list? $capabilities List of required capability constants,
+ * or omit for defaults.
* @return object|null Object, or null if no such object exists.
* @task load
*/
@@ -816,9 +826,9 @@ abstract class PhabricatorEditEngine
/**
* Load an object given a configured query.
*
- * @param PhabricatorPolicyAwareQuery Configured query.
- * @param list List of required capability constants, or omit for
- * defaults.
+ * @param PhabricatorPolicyAwareQuery $query Configured query.
+ * @param list? $capabilities List of required capability constants,
+ * or omit for defaults.
* @return object|null Object, or null if no such object exists.
* @task load
*/
@@ -850,7 +860,7 @@ abstract class PhabricatorEditEngine
/**
* Verify that an object is appropriate for editing.
*
- * @param wild Loaded value.
+ * @param wild $object Loaded value.
* @return void
* @task load
*/
@@ -1664,10 +1674,12 @@ abstract class PhabricatorEditEngine
$view = id(new PhabricatorApplicationTransactionCommentView())
->setUser($viewer)
- ->setObjectPHID($object_phid)
->setHeaderText($header_text)
->setAction($comment_uri)
+ ->setRequestURI(new PhutilURI($this->getObjectViewURI($object)))
->setRequiresMFA($requires_mfa)
+ ->setObject($object)
+ ->setEditEngine($this)
->setSubmitButtonName($button_text);
$draft = PhabricatorVersionedDraft::loadDraft(
@@ -1755,7 +1767,7 @@ abstract class PhabricatorEditEngine
/**
* Respond to a request for documentation on HTTP parameters.
*
- * @param object Editable object.
+ * @param object $object Editable object.
* @return AphrontResponse Response object.
* @task http
*/
@@ -1909,7 +1921,7 @@ abstract class PhabricatorEditEngine
$comment_text = $request->getStr('comment');
$comment_metadata = $request->getStr('comment_metadata');
- if (strlen($comment_metadata)) {
+ if (phutil_nonempty_string($comment_metadata)) {
$comment_metadata = phutil_json_decode($comment_metadata);
}
@@ -2009,7 +2021,7 @@ abstract class PhabricatorEditEngine
$xactions[] = $xaction;
}
- if (strlen($comment_text) || !$xactions) {
+ if (phutil_nonempty_string($comment_text) || !$xactions) {
$xactions[] = id(clone $template)
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->setMetadataValue('remarkup.control', $comment_metadata)
@@ -2232,10 +2244,10 @@ abstract class PhabricatorEditEngine
* Generate transactions which can be applied from edit actions in a Conduit
* request.
*
- * @param ConduitAPIRequest The request.
- * @param list Raw conduit transactions.
- * @param list Supported edit types.
- * @param PhabricatorApplicationTransaction Template transaction.
+ * @param ConduitAPIRequest $request The request.
+ * @param list $xactions Raw conduit transactions.
+ * @param list $types Supported edit types.
+ * @param PhabricatorApplicationTransaction $template Template transaction.
* @return list Generated transactions.
* @task conduit
*/
diff --git a/src/applications/transactions/editfield/PhabricatorEditField.php b/src/applications/transactions/editfield/PhabricatorEditField.php
index 4c72d63214..4e17bf006c 100644
--- a/src/applications/transactions/editfield/PhabricatorEditField.php
+++ b/src/applications/transactions/editfield/PhabricatorEditField.php
@@ -573,8 +573,8 @@ abstract class PhabricatorEditField extends Phobject {
* Most fields do not need to store these values or deal with initial value
* handling.
*
- * @param AphrontRequest Request to read from.
- * @param string Key to read.
+ * @param AphrontRequest $request Request to read from.
+ * @param string $key Key to read.
* @return wild Value read from request.
*/
protected function getInitialValueFromSubmit(AphrontRequest $request, $key) {
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
index 1d9d3282b7..b759e58c1d 100644
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -140,7 +140,8 @@ abstract class PhabricatorApplicationTransactionEditor
* nothing (e.g., empty comment with a status change that has already been
* performed by another user).
*
- * @param bool True to drop transactions without effect and continue.
+ * @param bool $continue True to drop transactions without effect and
+ * continue.
* @return this
*/
public function setContinueOnNoEffect($continue) {
@@ -168,8 +169,8 @@ abstract class PhabricatorApplicationTransactionEditor
* (like the priority, batch, and merge editors in Maniphest), these
* operations can continue to function even if an object is outdated.
*
- * @param bool True to continue when transactions don't completely satisfy
- * all required fields.
+ * @param bool $continue_on_missing_fields True to continue when transactions
+ * don't completely satisfy all required fields.
* @return this
*/
public function setContinueOnMissingFields($continue_on_missing_fields) {
@@ -2853,11 +2854,11 @@ abstract class PhabricatorApplicationTransactionEditor
* missing, by detecting that the object has no field value and there is no
* transaction which sets one.
*
- * @param PhabricatorLiskDAO Object being edited.
- * @param string Transaction type to validate.
- * @param list Transactions of given type,
- * which may be empty if the edit does not apply any transactions of the
- * given type.
+ * @param PhabricatorLiskDAO $object Object being edited.
+ * @param string $type Transaction type to validate.
+ * @param list $xactions Transactions of
+ * given type, which may be empty if the edit does not apply any
+ * transactions of the given type.
* @return list List of
* validation errors.
*/
@@ -3277,9 +3278,9 @@ abstract class PhabricatorApplicationTransactionEditor
* This will return `true` if the net effect of the object and transactions
* is an empty field.
*
- * @param wild Current field value.
- * @param list Transactions editing the
- * field.
+ * @param wild $field_value Current field value.
+ * @param list $xactions Transactions
+ * editing the field.
* @return bool True if the field will be an empty text field after edits.
*/
protected function validateIsEmptyTextField($field_value, array $xactions) {
@@ -3299,7 +3300,10 @@ abstract class PhabricatorApplicationTransactionEditor
/**
- * When a user interacts with an object, we might want to add them to CC.
+ * Adds the actor as a subscriber to the object with which they interact
+ * @param PhabricatorLiskDAO $object on which the action is performed
+ * @param array $xactions Transactions to apply
+ * @return array Transactions to apply
*/
final public function applyImplicitCC(
PhabricatorLiskDAO $object,
@@ -3381,11 +3385,18 @@ abstract class PhabricatorApplicationTransactionEditor
return $xactions;
}
+ /**
+ * Whether the action implies the actor should be subscribed on the object
+ * @param PhabricatorLiskDAO $object on which the action is performed
+ * @param PhabricatorApplicationTransaction $xaction Transaction to apply
+ * @return bool True if the actor should be subscribed on the object
+ */
protected function shouldImplyCC(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
- return $xaction->isCommentTransaction();
+ return ($xaction->isCommentTransaction() &&
+ !($xaction->getComment()->getIsRemoved()));
}
@@ -4590,7 +4601,8 @@ abstract class PhabricatorApplicationTransactionEditor
*
* This method is used to load state when running worker operations.
*
- * @param dict Editor state, from @{method:getWorkerState}.
+ * @param dict $state Editor state, from
+ @{method:getWorkerState}.
* @return this
* @task workers
*/
@@ -4616,7 +4628,7 @@ abstract class PhabricatorApplicationTransactionEditor
* Hook; set custom properties on the editor from data emitted by
* @{method:getCustomWorkerState}.
*
- * @param dict Custom state,
+ * @param dict $state Custom state,
* from @{method:getCustomWorkerState}.
* @return this
* @task workers
@@ -4664,8 +4676,8 @@ abstract class PhabricatorApplicationTransactionEditor
*
* See @{method:getCustomWorkerStateEncoding}.
*
- * @param map Map of values to encode.
- * @param map Map of encodings to apply.
+ * @param map $state Map of values to encode.
+ * @param map $encodings Map of encodings to apply.
* @return map Map of encoded values.
* @task workers
*/
@@ -4710,8 +4722,8 @@ abstract class PhabricatorApplicationTransactionEditor
*
* See @{method:getCustomWorkerStateEncoding}.
*
- * @param map Map of encoded values.
- * @param map |