Creating (or updating) a Phriction Document creates empty parent documents

Summary:
Fixes T2208

Parent documents get created as stubs - while the action is "parent" - don't ask

Test Plan: Created some documents with somewhat ancestry - verified their parents had pages and stub messages display ({F34456}).

Reviewers: epriestley, btrahan

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2208

Differential Revision: https://secure.phabricator.com/D5201
This commit is contained in:
Anh Nhan Nguyen 2013-03-04 07:31:59 -08:00 committed by epriestley
parent 98615c3540
commit fd016b5864
4 changed files with 69 additions and 15 deletions

View file

@ -9,6 +9,7 @@ final class PhrictionChangeType extends PhrictionConstants {
const CHANGE_DELETE = 1; const CHANGE_DELETE = 1;
const CHANGE_MOVE_HERE = 2; const CHANGE_MOVE_HERE = 2;
const CHANGE_MOVE_AWAY = 3; const CHANGE_MOVE_AWAY = 3;
const CHANGE_PARENT = 4;
public static function getChangeTypeLabel($const) { public static function getChangeTypeLabel($const) {
static $map = array( static $map = array(
@ -16,6 +17,7 @@ final class PhrictionChangeType extends PhrictionConstants {
self::CHANGE_DELETE => 'Delete', self::CHANGE_DELETE => 'Delete',
self::CHANGE_MOVE_HERE => 'Move Here', self::CHANGE_MOVE_HERE => 'Move Here',
self::CHANGE_MOVE_AWAY => 'Move Away', self::CHANGE_MOVE_AWAY => 'Move Away',
self::CHANGE_PARENT => 'Created through child',
); );
return idx($map, $const, '???'); return idx($map, $const, '???');

View file

@ -7,11 +7,13 @@ final class PhrictionDocumentStatus extends PhrictionConstants {
const STATUS_EXISTS = 0; const STATUS_EXISTS = 0;
const STATUS_DELETED = 1; const STATUS_DELETED = 1;
const STATUS_STUB = 3;
public static function getConduitConstant($const) { public static function getConduitConstant($const) {
static $map = array( static $map = array(
self::STATUS_EXISTS => 'exists', self::STATUS_EXISTS => 'exists',
self::STATUS_DELETED => 'deleted', self::STATUS_DELETED => 'deleted',
self::STATUS_STUB => 'stubbed',
); );
return idx($map, $const, 'unknown'); return idx($map, $const, 'unknown');

View file

@ -140,6 +140,14 @@ final class PhrictionDocumentController
pht('This document has been deleted. You can edit it to put new '. pht('This document has been deleted. You can edit it to put new '.
'content here, or use history to revert to an earlier version.')); 'content here, or use history to revert to an earlier version.'));
$core_content = $notice->render(); $core_content = $notice->render();
} else if ($doc_status == PhrictionDocumentStatus::STATUS_STUB) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle('Empty Document');
$notice->appendChild(
pht('This document is empty. You can edit it to put some proper '.
'content here.'));
$core_content = $notice->render();
} else { } else {
throw new Exception("Unknown document status '{$doc_status}'!"); throw new Exception("Unknown document status '{$doc_status}'!");
} }
@ -244,14 +252,17 @@ final class PhrictionDocumentController
'SELECT d.slug, d.depth, c.title FROM %T d JOIN %T c 'SELECT d.slug, d.depth, c.title FROM %T d JOIN %T c
ON d.contentID = c.id ON d.contentID = c.id
WHERE d.slug LIKE %> AND d.depth IN (%d, %d) WHERE d.slug LIKE %> AND d.depth IN (%d, %d)
AND d.status = %d AND d.status IN (%Ld)
ORDER BY d.depth, c.title LIMIT %d', ORDER BY d.depth, c.title LIMIT %d',
$document_dao->getTableName(), $document_dao->getTableName(),
$content_dao->getTableName(), $content_dao->getTableName(),
($slug == '/' ? '' : $slug), ($slug == '/' ? '' : $slug),
$d_child, $d_child,
$d_grandchild, $d_grandchild,
array(
PhrictionDocumentStatus::STATUS_EXISTS, PhrictionDocumentStatus::STATUS_EXISTS,
PhrictionDocumentStatus::STATUS_STUB,
),
$limit); $limit);
if (!$children) { if (!$children) {

View file

@ -83,6 +83,18 @@ final class PhrictionDocumentEditor extends PhabricatorEditor {
return $this->updateDocument($document, $content, $new_content); return $this->updateDocument($document, $content, $new_content);
} }
public function stub() {
$actor = $this->requireActor();
$document = $this->document;
$content = $this->content;
$new_content = $this->buildContentTemplate($document, $content);
$new_content->setChangeType(PhrictionChangeType::CHANGE_PARENT);
$new_content->setContent('');
return $this->updateDocument($document, $content, $new_content);
}
public function save() { public function save() {
$actor = $this->requireActor(); $actor = $this->requireActor();
@ -152,6 +164,10 @@ final class PhrictionDocumentEditor extends PhabricatorEditor {
"You can not delete a document which doesn't exist yet!"); "You can not delete a document which doesn't exist yet!");
} }
break; break;
case PhrictionChangeType::CHANGE_PARENT:
$doc_status = PhrictionDocumentStatus::STATUS_STUB;
$feed_action = null;
break;
default: default:
throw new Exception( throw new Exception(
"Unsupported content change type '{$change_type}'!"); "Unsupported content change type '{$change_type}'!");
@ -176,6 +192,27 @@ final class PhrictionDocumentEditor extends PhabricatorEditor {
id(new PhabricatorSearchIndexer()) id(new PhabricatorSearchIndexer())
->indexDocumentByPHID($document->getPHID()); ->indexDocumentByPHID($document->getPHID());
// Stub out empty parent documents if they don't exist
$ancestral_slugs = PhabricatorSlug::getAncestry($document->getSlug());
if ($ancestral_slugs) {
$ancestors = id(new PhrictionDocument())->loadAllWhere(
'slug IN (%Ls)',
$ancestral_slugs);
foreach ($ancestral_slugs as $slug) {
// We check for change type to prevent near-infinite recursion
if (!isset($ancestors[$slug]) &&
$new_content->getChangeType() != PhrictionChangeType::CHANGE_PARENT) {
id(PhrictionDocumentEditor::newForSlug($slug))
->setActor($this->getActor())
->setTitle(PhabricatorSlug::getDefaultTitle($slug))
->setContent('')
->setDescription(pht('Empty Parent Document'))
->stub();
}
}
}
$project_phid = null; $project_phid = null;
$slug = $document->getSlug(); $slug = $document->getSlug();
if (PhrictionDocument::isProjectSlug($slug)) { if (PhrictionDocument::isProjectSlug($slug)) {
@ -196,6 +233,7 @@ final class PhrictionDocumentEditor extends PhabricatorEditor {
$related_phids[] = $project_phid; $related_phids[] = $project_phid;
} }
if ($feed_action) {
id(new PhabricatorFeedStoryPublisher()) id(new PhabricatorFeedStoryPublisher())
->setRelatedPHIDs($related_phids) ->setRelatedPHIDs($related_phids)
->setStoryAuthorPHID($this->getActor()->getPHID()) ->setStoryAuthorPHID($this->getActor()->getPHID())
@ -209,6 +247,7 @@ final class PhrictionDocumentEditor extends PhabricatorEditor {
'project' => $project_phid, 'project' => $project_phid,
)) ))
->publish(); ->publish();
}
return $this; return $this;
} }