diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 26272151e3..1352206d1b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -141,6 +141,8 @@ phutil_register_library_map(array( 'ConduitAPI_phriction_edit_Method' => 'applications/conduit/method/phriction/edit', 'ConduitAPI_phriction_history_Method' => 'applications/conduit/method/phriction/history', 'ConduitAPI_phriction_info_Method' => 'applications/conduit/method/phriction/info', + 'ConduitAPI_project_Method' => 'applications/conduit/method/project/base', + 'ConduitAPI_project_query_Method' => 'applications/conduit/method/project/query', 'ConduitAPI_slowvote_info_Method' => 'applications/conduit/method/slowvote/info', 'ConduitAPI_user_Method' => 'applications/conduit/method/user/base', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', @@ -903,6 +905,8 @@ phutil_register_library_map(array( 'ConduitAPI_phriction_edit_Method' => 'ConduitAPI_phriction_Method', 'ConduitAPI_phriction_history_Method' => 'ConduitAPI_phriction_Method', 'ConduitAPI_phriction_info_Method' => 'ConduitAPI_phriction_Method', + 'ConduitAPI_project_Method' => 'ConduitAPIMethod', + 'ConduitAPI_project_query_Method' => 'ConduitAPI_project_Method', 'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method', diff --git a/src/applications/conduit/method/project/base/ConduitAPI_project_Method.php b/src/applications/conduit/method/project/base/ConduitAPI_project_Method.php new file mode 100644 index 0000000000..ca3d642828 --- /dev/null +++ b/src/applications/conduit/method/project/base/ConduitAPI_project_Method.php @@ -0,0 +1,53 @@ +buildProjectInfoDictionaries(array($project)); + return idx($results, $project->getPHID()); + } + + protected function buildProjectInfoDictionaries(array $projects) { + if (!$projects) { + return array(); + } + + $result = array(); + foreach ($projects as $project) { + + $member_phids = mpull($project->getAffiliations(), 'getUserPHID'); + $member_phids = array_values($member_phids); + + $result[$project->getPHID()] = array( + 'id' => $project->getID(), + 'phid' => $project->getPHID(), + 'name' => $project->getName(), + 'members' => $member_phids, + 'dateCreated' => $project->getDateCreated(), + 'dateModified' => $project->getDateModified(), + ); + } + + return $result; + } + +} diff --git a/src/applications/conduit/method/project/base/__init__.php b/src/applications/conduit/method/project/base/__init__.php new file mode 100644 index 0000000000..8cd2a1566f --- /dev/null +++ b/src/applications/conduit/method/project/base/__init__.php @@ -0,0 +1,14 @@ + 'optional list', + 'phids' => 'optional list', + + 'members' => 'optional list', + + 'limit' => 'optional int', + 'offset' => 'optional int', + ); + } + + public function defineReturnType() { + return 'list'; + } + + public function defineErrorTypes() { + return array( + ); + } + + protected function execute(ConduitAPIRequest $request) { + $query = new PhabricatorProjectQuery(); + $query->needMembers(true); + + $ids = $request->getValue('ids'); + if ($ids) { + $query->withIDs($ids); + } + + $phids = $request->getValue('phids'); + if ($phids) { + $query->withPHIDs($phids); + } + + $members = $request->getValue('members'); + if ($members) { + $query->setMembers($members); + } + + $limit = $request->getValue('limit'); + if ($limit) { + $query->setLimit($limit); + } + + $offset = $request->getValue('offset'); + if ($offset) { + $query->setOffset($offset); + } + + $results = $query->execute(); + return $this->buildProjectInfoDictionaries($results); + } + +} diff --git a/src/applications/conduit/method/project/query/__init__.php b/src/applications/conduit/method/project/query/__init__.php new file mode 100644 index 0000000000..4eb019a7b4 --- /dev/null +++ b/src/applications/conduit/method/project/query/__init__.php @@ -0,0 +1,13 @@ +ids = $ids; + return $this; + } + + public function withPHIDs(array $phids) { + $this->phids = $phids; + return $this; + } + public function setLimit($limit) { $this->limit = $limit; return $this; @@ -44,13 +58,19 @@ final class PhabricatorProjectQuery { return $this; } + public function needMembers($need_members) { + $this->needMembers = $need_members; + return $this; + } + public function execute() { $table = id(new PhabricatorProject()); $conn_r = $table->establishConnection('r'); + $where = $this->buildWhereClause($conn_r); $joins = $this->buildJoinsClause($conn_r); - $limit = null; + $limit = ''; if ($this->limit) { $limit = qsprintf( $conn_r, @@ -69,13 +89,51 @@ final class PhabricatorProjectQuery { $data = queryfx_all( $conn_r, - 'SELECT p.* FROM %T p %Q %Q %Q', + 'SELECT p.* FROM %T p %Q %Q %Q %Q', $table->getTableName(), $joins, + $where, $order, $limit); - return $table->loadAllFromArray($data); + $projects = $table->loadAllFromArray($data); + + if ($projects && $this->needMembers) { + $members = PhabricatorProjectAffiliation::loadAllForProjectPHIDs( + mpull($projects, 'getPHID')); + foreach ($projects as $project) { + $project->attachAffiliations( + array_values(idx($members, $project->getPHID(), array()))); + } + } + + return $projects; + } + + private function buildWhereClause($conn_r) { + $where = array(); + + if ($this->ids) { + $where[] = qsprintf( + $conn_r, + 'id IN (%Ld)', + $this->ids); + } + + if ($this->phids) { + $where[] = qsprintf( + $conn_r, + 'phid IN (%Ls)', + $this->phids); + } + + if ($where) { + $where = 'WHERE ('.implode(') AND (', $where).')'; + } else { + $where = ''; + } + + return $where; } private function buildJoinsClause($conn_r) { diff --git a/src/applications/project/storage/project/PhabricatorProject.php b/src/applications/project/storage/project/PhabricatorProject.php index b73f88e17c..b3a1e56522 100644 --- a/src/applications/project/storage/project/PhabricatorProject.php +++ b/src/applications/project/storage/project/PhabricatorProject.php @@ -1,7 +1,7 @@ affiliations === null) { + throw new Exception('Attach affiliations first!'); + } + return $this->affiliations; + } + + public function attachAffiliations(array $affiliations) { + $this->affiliations = $affiliations; + return $this; + } + public function loadAffiliations() { $affils = PhabricatorProjectAffiliation::loadAllForProjectPHIDs( array($this->getPHID()));