Skip to content

Commit 00f1389

Browse files
author
epriestley
committedDec 28, 2015
Add phame.post.search Conduit API endpoint
Summary: Ref T9897. Mostly straightforward, but also modernize/fixup the Query a little so that posts never load with no blog. Test Plan: Queried posts via API. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14901
1 parent b74f93f commit 00f1389

File tree

5 files changed

+129
-67
lines changed

5 files changed

+129
-67
lines changed
 

‎src/__phutil_library_map__.php

+3
Original file line numberDiff line numberDiff line change
@@ -3440,6 +3440,7 @@
34403440
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
34413441
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
34423442
'PhamePostReplyHandler' => 'applications/phame/mail/PhamePostReplyHandler.php',
3443+
'PhamePostSearchConduitAPIMethod' => 'applications/phame/conduit/PhamePostSearchConduitAPIMethod.php',
34433444
'PhamePostSearchEngine' => 'applications/phame/query/PhamePostSearchEngine.php',
34443445
'PhamePostTransaction' => 'applications/phame/storage/PhamePostTransaction.php',
34453446
'PhamePostTransactionComment' => 'applications/phame/storage/PhamePostTransactionComment.php',
@@ -7886,6 +7887,7 @@
78867887
'PhabricatorSubscribableInterface',
78877888
'PhabricatorDestructibleInterface',
78887889
'PhabricatorTokenReceiverInterface',
7890+
'PhabricatorConduitResultInterface',
78897891
),
78907892
'PhamePostCommentController' => 'PhamePostController',
78917893
'PhamePostController' => 'PhameController',
@@ -7900,6 +7902,7 @@
79007902
'PhamePostPublishController' => 'PhamePostController',
79017903
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
79027904
'PhamePostReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
7905+
'PhamePostSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
79037906
'PhamePostSearchEngine' => 'PhabricatorApplicationSearchEngine',
79047907
'PhamePostTransaction' => 'PhabricatorApplicationTransaction',
79057908
'PhamePostTransactionComment' => 'PhabricatorApplicationTransactionComment',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
final class PhamePostSearchConduitAPIMethod
4+
extends PhabricatorSearchEngineAPIMethod {
5+
6+
public function getAPIMethodName() {
7+
return 'phame.post.search';
8+
}
9+
10+
public function newSearchEngine() {
11+
return new PhamePostSearchEngine();
12+
}
13+
14+
public function getMethodSummary() {
15+
return pht('Read information about blog posts.');
16+
}
17+
18+
}

‎src/applications/phame/query/PhamePostQuery.php

+35-37
Original file line numberDiff line numberDiff line change
@@ -39,38 +39,36 @@ public function withPublishedAfter($time) {
3939
return $this;
4040
}
4141

42+
public function newResultObject() {
43+
return new PhamePost();
44+
}
45+
4246
protected function loadPage() {
43-
$table = new PhamePost();
44-
$conn_r = $table->establishConnection('r');
45-
46-
$where_clause = $this->buildWhereClause($conn_r);
47-
$order_clause = $this->buildOrderClause($conn_r);
48-
$limit_clause = $this->buildLimitClause($conn_r);
49-
50-
$data = queryfx_all(
51-
$conn_r,
52-
'SELECT * FROM %T p %Q %Q %Q',
53-
$table->getTableName(),
54-
$where_clause,
55-
$order_clause,
56-
$limit_clause);
57-
58-
$posts = $table->loadAllFromArray($data);
59-
60-
if ($posts) {
61-
// We require these to do visibility checks, so load them unconditionally.
62-
$blog_phids = mpull($posts, 'getBlogPHID');
63-
$blogs = id(new PhameBlogQuery())
64-
->setViewer($this->getViewer())
65-
->needProfileImage(true)
66-
->withPHIDs($blog_phids)
67-
->execute();
68-
$blogs = mpull($blogs, null, 'getPHID');
69-
foreach ($posts as $post) {
70-
if (isset($blogs[$post->getBlogPHID()])) {
71-
$post->setBlog($blogs[$post->getBlogPHID()]);
72-
}
47+
return $this->loadStandardPage($this->newResultObject());
48+
}
49+
50+
protected function willFilterPage(array $posts) {
51+
// We require blogs to do visibility checks, so load them unconditionally.
52+
$blog_phids = mpull($posts, 'getBlogPHID');
53+
54+
$blogs = id(new PhameBlogQuery())
55+
->setViewer($this->getViewer())
56+
->needProfileImage(true)
57+
->withPHIDs($blog_phids)
58+
->execute();
59+
60+
$blogs = mpull($blogs, null, 'getPHID');
61+
foreach ($posts as $key => $post) {
62+
$blog_phid = $post->getBlogPHID();
63+
64+
$blog = idx($blogs, $blog_phid);
65+
if (!$blog) {
66+
$this->didRejectResult($post);
67+
unset($posts[$key]);
68+
continue;
7369
}
70+
71+
$post->attachBlog($blog);
7472
}
7573

7674
return $posts;
@@ -82,42 +80,42 @@ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
8280
if ($this->ids) {
8381
$where[] = qsprintf(
8482
$conn,
85-
'p.id IN (%Ld)',
83+
'id IN (%Ld)',
8684
$this->ids);
8785
}
8886

8987
if ($this->phids) {
9088
$where[] = qsprintf(
9189
$conn,
92-
'p.phid IN (%Ls)',
90+
'phid IN (%Ls)',
9391
$this->phids);
9492
}
9593

9694
if ($this->bloggerPHIDs) {
9795
$where[] = qsprintf(
9896
$conn,
99-
'p.bloggerPHID IN (%Ls)',
97+
'bloggerPHID IN (%Ls)',
10098
$this->bloggerPHIDs);
10199
}
102100

103101
if ($this->visibility !== null) {
104102
$where[] = qsprintf(
105103
$conn,
106-
'p.visibility = %d',
104+
'visibility = %d',
107105
$this->visibility);
108106
}
109107

110108
if ($this->publishedAfter !== null) {
111109
$where[] = qsprintf(
112110
$conn,
113-
'p.datePublished > %d',
111+
'datePublished > %d',
114112
$this->publishedAfter);
115113
}
116114

117-
if ($this->blogPHIDs) {
115+
if ($this->blogPHIDs !== null) {
118116
$where[] = qsprintf(
119117
$conn,
120-
'p.blogPHID in (%Ls)',
118+
'blogPHID in (%Ls)',
121119
$this->blogPHIDs);
122120
}
123121

‎src/applications/phame/query/PhamePostSearchEngine.php

+11-10
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ protected function buildCustomSearchFields() {
3030
id(new PhabricatorSearchSelectField())
3131
->setKey('visibility')
3232
->setLabel(pht('Visibility'))
33-
->setOptions(array(
34-
'' => pht('All'),
35-
PhameConstants::VISIBILITY_PUBLISHED => pht('Published'),
36-
PhameConstants::VISIBILITY_DRAFT => pht('Draft'),
33+
->setOptions(
34+
array(
35+
'' => pht('All'),
36+
PhameConstants::VISIBILITY_PUBLISHED => pht('Published'),
37+
PhameConstants::VISIBILITY_DRAFT => pht('Draft'),
3738
)),
3839
);
3940
}
@@ -68,6 +69,8 @@ public function buildSavedQueryFromBuiltin($query_key) {
6869

6970
return parent::buildSavedQueryFromBuiltin($query_key);
7071
}
72+
73+
7174
protected function renderResultList(
7275
array $posts,
7376
PhabricatorSavedQuery $query,
@@ -82,12 +85,10 @@ protected function renderResultList(
8285
foreach ($posts as $post) {
8386
$id = $post->getID();
8487
$blog = $post->getBlog();
85-
if ($blog) {
86-
$blog_name = $viewer->renderHandle($post->getBlogPHID())->render();
87-
$blog_name = pht('Blog: %s', $blog_name);
88-
} else {
89-
$blog_name = pht('[No Blog]');
90-
}
88+
89+
$blog_name = $viewer->renderHandle($post->getBlogPHID())->render();
90+
$blog_name = pht('Blog: %s', $blog_name);
91+
9192
$item = id(new PHUIObjectItemView())
9293
->setUser($viewer)
9394
->setObject($post)

‎src/applications/phame/storage/PhamePost.php

+62-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ final class PhamePost extends PhameDAO
99
PhabricatorApplicationTransactionInterface,
1010
PhabricatorSubscribableInterface,
1111
PhabricatorDestructibleInterface,
12-
PhabricatorTokenReceiverInterface {
12+
PhabricatorTokenReceiverInterface,
13+
PhabricatorConduitResultInterface {
1314

1415
const MARKUP_FIELD_BODY = 'markup:body';
1516
const MARKUP_FIELD_SUMMARY = 'markup:summary';
@@ -24,7 +25,7 @@ final class PhamePost extends PhameDAO
2425
protected $blogPHID;
2526
protected $mailKey;
2627

27-
private $blog;
28+
private $blog = self::ATTACHABLE;
2829

2930
public static function initializePost(
3031
PhabricatorUser $blogger,
@@ -33,19 +34,20 @@ public static function initializePost(
3334
$post = id(new PhamePost())
3435
->setBloggerPHID($blogger->getPHID())
3536
->setBlogPHID($blog->getPHID())
36-
->setBlog($blog)
37+
->attachBlog($blog)
3738
->setDatePublished(PhabricatorTime::getNow())
3839
->setVisibility(PhameConstants::VISIBILITY_PUBLISHED);
40+
3941
return $post;
4042
}
4143

42-
public function setBlog(PhameBlog $blog) {
44+
public function attachBlog(PhameBlog $blog) {
4345
$this->blog = $blog;
4446
return $this;
4547
}
4648

4749
public function getBlog() {
48-
return $this->blog;
50+
return $this->assertAttached($this->blog);
4951
}
5052

5153
public function getLiveURI() {
@@ -146,21 +148,6 @@ public function getSlug() {
146148
return PhabricatorSlug::normalizeProjectSlug($this->getTitle(), true);
147149
}
148150

149-
public function toDictionary() {
150-
return array(
151-
'id' => $this->getID(),
152-
'phid' => $this->getPHID(),
153-
'blogPHID' => $this->getBlogPHID(),
154-
'bloggerPHID' => $this->getBloggerPHID(),
155-
'viewURI' => $this->getViewURI(),
156-
'title' => $this->getTitle(),
157-
'body' => $this->getBody(),
158-
'summary' => PhabricatorMarkupEngine::summarize($this->getBody()),
159-
'datePublished' => $this->getDatePublished(),
160-
'published' => !$this->isDraft(),
161-
);
162-
}
163-
164151

165152
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
166153

@@ -303,4 +290,59 @@ public function shouldAllowSubscription($phid) {
303290
return true;
304291
}
305292

293+
294+
/* -( PhabricatorConduitResultInterface )---------------------------------- */
295+
296+
297+
public function getFieldSpecificationsForConduit() {
298+
return array(
299+
id(new PhabricatorConduitSearchFieldSpecification())
300+
->setKey('title')
301+
->setType('string')
302+
->setDescription(pht('Title of the post.')),
303+
id(new PhabricatorConduitSearchFieldSpecification())
304+
->setKey('slug')
305+
->setType('string')
306+
->setDescription(pht('Slug for the post.')),
307+
id(new PhabricatorConduitSearchFieldSpecification())
308+
->setKey('blogPHID')
309+
->setType('phid')
310+
->setDescription(pht('PHID of the blog that the post belongs to.')),
311+
id(new PhabricatorConduitSearchFieldSpecification())
312+
->setKey('authorPHID')
313+
->setType('phid')
314+
->setDescription(pht('PHID of the author of the post.')),
315+
id(new PhabricatorConduitSearchFieldSpecification())
316+
->setKey('body')
317+
->setType('string')
318+
->setDescription(pht('Body of the post.')),
319+
id(new PhabricatorConduitSearchFieldSpecification())
320+
->setKey('datePublished')
321+
->setType('epoch?')
322+
->setDescription(pht('Publish date, if the post has been published.')),
323+
324+
);
325+
}
326+
327+
public function getFieldValuesForConduit() {
328+
if ($this->isDraft()) {
329+
$date_published = null;
330+
} else {
331+
$date_published = (int)$this->getDatePublished();
332+
}
333+
334+
return array(
335+
'title' => $this->getTitle(),
336+
'slug' => $this->getSlug(),
337+
'blogPHID' => $this->getBlogPHID(),
338+
'authorPHID' => $this->getBloggerPHID(),
339+
'body' => $this->getBody(),
340+
'datePublished' => $date_published,
341+
);
342+
}
343+
344+
public function getConduitSearchAttachments() {
345+
return array();
346+
}
347+
306348
}

0 commit comments

Comments
 (0)
Failed to load comments.