1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Add DoorkeeperExternalObjectQuery, expose more ref/import APIs

Summary:
Ref T2852.

  - Broadly, we support "I have a Ref, I need a PHID" well but not "I have a PHID, I need a Ref".
  - Add DoorkeeperExternalObjectQuery, and use it to query ExternalObjects.
  - Allow external objects to be imported by their internal PHIDs. Basically, if we have an edge pointing at an ExternalObject, we can say "load all the data about this" from just the PHID and have it hit all the same code.
  - Allow construction of Refs from ExternalObjects. This makes the "I have a PHID, I need a Ref" easier.

Test Plan:
  - Verified Asana links still enrich properly at display time.
  - Used in future revision.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2852

Differential Revision: https://secure.phabricator.com/D6294
This commit is contained in:
epriestley 2013-06-25 16:30:44 -07:00
parent c77bfd6603
commit 4ca38612f2
6 changed files with 105 additions and 17 deletions

View file

@ -537,6 +537,7 @@ phutil_register_library_map(array(
'DoorkeeperBridgeAsana' => 'applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php',
'DoorkeeperDAO' => 'applications/doorkeeper/storage/DoorkeeperDAO.php',
'DoorkeeperExternalObject' => 'applications/doorkeeper/storage/DoorkeeperExternalObject.php',
'DoorkeeperExternalObjectQuery' => 'applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php',
'DoorkeeperImportEngine' => 'applications/doorkeeper/engine/DoorkeeperImportEngine.php',
'DoorkeeperObjectRef' => 'applications/doorkeeper/engine/DoorkeeperObjectRef.php',
'DoorkeeperRemarkupRuleAsana' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRuleAsana.php',
@ -2426,6 +2427,7 @@ phutil_register_library_map(array(
0 => 'DoorkeeperDAO',
1 => 'PhabricatorPolicyInterface',
),
'DoorkeeperExternalObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DoorkeeperImportEngine' => 'Phobject',
'DoorkeeperObjectRef' => 'Phobject',
'DoorkeeperRemarkupRuleAsana' => 'PhutilRemarkupRule',

View file

@ -20,4 +20,7 @@ abstract class DoorkeeperBridge extends Phobject {
abstract public function canPullRef(DoorkeeperObjectRef $ref);
abstract public function pullRefs(array $refs);
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
}
}

View file

@ -77,9 +77,7 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
continue;
}
$id = $result['id'];
$uri = "https://app.asana.com/0/{$id}/{$id}";
$obj->setObjectURI($uri);
$this->fillObjectFromData($obj, $result);
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$obj->save();
@ -87,4 +85,10 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
}
}
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
$id = $result['id'];
$uri = "https://app.asana.com/0/{$id}/{$id}";
$obj->setObjectURI($uri);
}
}

View file

@ -3,7 +3,8 @@
final class DoorkeeperImportEngine extends Phobject {
private $viewer;
private $refs;
private $refs = array();
private $phids = array();
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
@ -24,26 +25,45 @@ final class DoorkeeperImportEngine extends Phobject {
return $this->refs;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function execute() {
$refs = $this->getRefs();
$viewer = $this->getViewer();
$keys = mpull($refs, 'getObjectKey');
if ($keys) {
$xobjs = id(new DoorkeeperExternalObject())->loadAllWhere(
'objectKey IN (%Ls)',
$keys);
$xobjs = id(new DoorkeeperExternalObjectQuery())
->setViewer($viewer)
->withObjectKeys($keys)
->execute();
$xobjs = mpull($xobjs, null, 'getObjectKey');
foreach ($refs as $ref) {
$xobj = idx($xobjs, $ref->getObjectKey());
if (!$xobj) {
$xobj = $ref->newExternalObject()
$xobj = $ref
->newExternalObject()
->setImporterPHID($viewer->getPHID());
}
$ref->attachExternalObject($xobj);
}
}
if ($this->phids) {
$xobjs = id(new DoorkeeperExternalObjectQuery())
->setViewer($viewer)
->withPHIDs($this->phids)
->execute();
foreach ($xobjs as $xobj) {
$ref = $xobj->getRef();
$ref->attachExternalObject($xobj);
$refs[$ref->getObjectKey()] = $ref;
}
}
$bridges = id(new PhutilSymbolLoader())
->setAncestorClass('DoorkeeperBridge')
->loadObjects();
@ -55,12 +75,13 @@ final class DoorkeeperImportEngine extends Phobject {
$bridge->setViewer($viewer);
}
$working_set = $refs;
foreach ($bridges as $bridge) {
$bridge_refs = array();
foreach ($refs as $key => $ref) {
foreach ($working_set as $key => $ref) {
if ($bridge->canPullRef($ref)) {
$bridge_refs[$key] = $ref;
unset($refs[$key]);
unset($working_set[$key]);
}
}
if ($bridge_refs) {
@ -68,7 +89,7 @@ final class DoorkeeperImportEngine extends Phobject {
}
}
return $this->getRefs();
return $refs;
}
}

View file

@ -0,0 +1,55 @@
<?php
final class DoorkeeperExternalObjectQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
protected $phids;
protected $objectKeys;
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withObjectKeys(array $keys) {
$this->objectKeys = $keys;
return $this;
}
public function loadPage() {
$table = new DoorkeeperExternalObject();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->objectKeys) {
$where[] = qsprintf(
$conn_r,
'objectKey IN (%Ls)',
$this->objectKeys);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
}

View file

@ -39,16 +39,19 @@ final class DoorkeeperExternalObject extends DoorkeeperDAO
public function getObjectKey() {
$key = parent::getObjectKey();
if ($key === null) {
$key = id(new DoorkeeperObjectRef())
->setApplicationType($this->getApplicationType())
->setApplicationDomain($this->getApplicationDomain())
->setObjectType($this->getObjectType())
->setObjectID($this->getObjectID())
->getObjectKey();
$key = $this->getRef()->getObjectKey();
}
return $key;
}
public function getRef() {
return id(new DoorkeeperObjectRef())
->setApplicationType($this->getApplicationType())
->setApplicationDomain($this->getApplicationDomain())
->setObjectType($this->getObjectType())
->setObjectID($this->getObjectID());
}
public function save() {
if (!$this->objectKey) {
$this->objectKey = $this->getObjectKey();