Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
Show First 20 Lines • Show All 400 Lines • ▼ Show 20 Lines | /* -( Query Workspace )---------------------------------------------------- */ | ||||
* | * | ||||
* **Never put objects into the workspace which the viewer may not be able | * **Never put objects into the workspace which the viewer may not be able | ||||
* to see**. You need to apply all policy filtering //before// putting | * to see**. You need to apply all policy filtering //before// putting | ||||
* objects in the workspace. Otherwise, subqueries may read the objects and | * objects in the workspace. Otherwise, subqueries may read the objects and | ||||
* use them to permit access to content the user shouldn't be able to view. | * use them to permit access to content the user shouldn't be able to view. | ||||
* | * | ||||
* **Fully enrich objects pulled from the workspace.** After pulling objects | * **Fully enrich objects pulled from the workspace.** After pulling objects | ||||
* from the workspace, you still need to load and attach any additional | * from the workspace, you still need to load and attach any additional | ||||
* content the query requests. Otherwise, a query might return objects without | * content the query requests. Otherwise, a query might return objects | ||||
* requested content. | * without requested content. | ||||
* | * | ||||
* Generally, you do not need to update the workspace yourself: it is | * Generally, you do not need to update the workspace yourself: it is | ||||
* automatically populated as a side effect of objects surviving policy | * automatically populated as a side effect of objects surviving policy | ||||
* filtering. | * filtering. | ||||
* | * | ||||
* @param map<phid, PhabricatorPolicyInterface> Objects to add to the query | * @param map<phid, PhabricatorPolicyInterface> Objects to add to the query | ||||
* workspace. | * workspace. | ||||
* @return this | * @return this | ||||
* @task workspace | * @task workspace | ||||
*/ | */ | ||||
public function putObjectsInWorkspace(array $objects) { | public function putObjectsInWorkspace(array $objects) { | ||||
$parent = $this->getParentQuery(); | |||||
if ($parent) { | |||||
$parent->putObjectsInWorkspace($objects); | |||||
return $this; | |||||
} | |||||
assert_instances_of($objects, 'PhabricatorPolicyInterface'); | assert_instances_of($objects, 'PhabricatorPolicyInterface'); | ||||
$viewer_phid = $this->getViewer()->getPHID(); | $viewer_fragment = $this->getViewer()->getCacheFragment(); | ||||
// The workspace is scoped per viewer to prevent accidental contamination. | // The workspace is scoped per viewer to prevent accidental contamination. | ||||
if (empty($this->workspace[$viewer_phid])) { | if (empty($this->workspace[$viewer_fragment])) { | ||||
$this->workspace[$viewer_phid] = array(); | $this->workspace[$viewer_fragment] = array(); | ||||
} | } | ||||
$this->workspace[$viewer_phid] += $objects; | $this->workspace[$viewer_fragment] += $objects; | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Retrieve objects from the query workspace. For more discussion about the | * Retrieve objects from the query workspace. For more discussion about the | ||||
* workspace mechanism, see @{method:putObjectsInWorkspace}. This method | * workspace mechanism, see @{method:putObjectsInWorkspace}. This method | ||||
* searches both the current query's workspace and the workspaces of parent | * searches both the current query's workspace and the workspaces of parent | ||||
* queries. | * queries. | ||||
* | * | ||||
* @param list<phid> List of PHIDs to retrieve. | * @param list<phid> List of PHIDs to retrieve. | ||||
* @return this | * @return this | ||||
* @task workspace | * @task workspace | ||||
*/ | */ | ||||
public function getObjectsFromWorkspace(array $phids) { | public function getObjectsFromWorkspace(array $phids) { | ||||
$viewer_phid = $this->getViewer()->getPHID(); | $parent = $this->getParentQuery(); | ||||
if ($parent) { | |||||
return $parent->getObjectsFromWorkspace($phids); | |||||
} | |||||
$viewer_fragment = $this->getViewer()->getCacheFragment(); | |||||
$results = array(); | $results = array(); | ||||
foreach ($phids as $key => $phid) { | foreach ($phids as $key => $phid) { | ||||
if (isset($this->workspace[$viewer_phid][$phid])) { | if (isset($this->workspace[$viewer_fragment][$phid])) { | ||||
$results[$phid] = $this->workspace[$viewer_phid][$phid]; | $results[$phid] = $this->workspace[$viewer_fragment][$phid]; | ||||
unset($phids[$key]); | unset($phids[$key]); | ||||
} | } | ||||
} | } | ||||
if ($phids && $this->getParentQuery()) { | |||||
$results += $this->getParentQuery()->getObjectsFromWorkspace($phids); | |||||
} | |||||
return $results; | return $results; | ||||
} | } | ||||
/** | /** | ||||
* Convert a result page to a `<phid, PhabricatorPolicyInterface>` map. | * Convert a result page to a `<phid, PhabricatorPolicyInterface>` map. | ||||
* | * | ||||
* @param list<PhabricatorPolicyInterface> Objects. | * @param list<PhabricatorPolicyInterface> Objects. | ||||
▲ Show 20 Lines • Show All 221 Lines • Show Last 20 Lines |