1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-08 21:08:29 +01:00
phorge-phorge/src/applications/phame/storage/PhamePost.php

341 lines
8.8 KiB
PHP
Raw Normal View History

<?php
final class PhamePost extends PhameDAO
implements
PhabricatorPolicyInterface,
PhabricatorMarkupInterface,
PhabricatorFlaggableInterface,
PhabricatorProjectInterface,
PhabricatorApplicationTransactionInterface,
PhabricatorSubscribableInterface,
PhabricatorDestructibleInterface,
PhabricatorTokenReceiverInterface,
PhabricatorConduitResultInterface {
const MARKUP_FIELD_BODY = 'markup:body';
const MARKUP_FIELD_SUMMARY = 'markup:summary';
protected $bloggerPHID;
protected $title;
protected $phameTitle;
protected $body;
protected $visibility;
protected $configData;
protected $datePublished;
protected $blogPHID;
protected $mailKey;
private $blog = self::ATTACHABLE;
public static function initializePost(
PhabricatorUser $blogger,
PhameBlog $blog) {
$post = id(new PhamePost())
->setBloggerPHID($blogger->getPHID())
->setBlogPHID($blog->getPHID())
->attachBlog($blog)
->setDatePublished(PhabricatorTime::getNow())
->setVisibility(PhameConstants::VISIBILITY_PUBLISHED);
return $post;
}
public function attachBlog(PhameBlog $blog) {
$this->blog = $blog;
return $this;
}
public function getBlog() {
return $this->assertAttached($this->blog);
}
public function getLiveURI() {
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
$blog = $this->getBlog();
$is_draft = $this->isDraft();
if (strlen($blog->getDomain()) && !$is_draft) {
return $this->getExternalLiveURI();
} else {
return $this->getInternalLiveURI();
}
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
}
public function getExternalLiveURI() {
$id = $this->getID();
$slug = $this->getSlug();
$path = "/post/{$id}/{$slug}/";
$domain = $this->getBlog()->getDomain();
return (string)id(new PhutilURI('http://'.$domain))
->setPath($path);
}
public function getInternalLiveURI() {
$id = $this->getID();
$slug = $this->getSlug();
$blog_id = $this->getBlog()->getID();
return "/phame/live/{$blog_id}/post/{$id}/{$slug}/";
}
public function getViewURI() {
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
$id = $this->getID();
$slug = $this->getSlug();
return "/phame/post/view/{$id}/{$slug}/";
}
public function getEditURI() {
return '/phame/post/edit/'.$this->getID().'/';
}
public function isDraft() {
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
return ($this->getVisibility() == PhameConstants::VISIBILITY_DRAFT);
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'configData' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255',
'phameTitle' => 'sort64?',
'visibility' => 'uint32',
'mailKey' => 'bytes20',
// T6203/NULLABILITY
// These seem like they should always be non-null?
'blogPHID' => 'phid?',
'body' => 'text?',
'configData' => 'text?',
// T6203/NULLABILITY
// This one probably should be nullable?
'datePublished' => 'epoch',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'phid' => array(
'columns' => array('phid'),
'unique' => true,
),
'bloggerPosts' => array(
'columns' => array(
'bloggerPHID',
'visibility',
'datePublished',
'id',
),
),
),
) + parent::getConfiguration();
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
return parent::save();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPhamePostPHIDType::TYPECONST);
}
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
public function getSlug() {
return PhabricatorSlug::normalizeProjectSlug($this->getTitle(), true);
Remove skins from Phame Summary: Ref T9897. Purge a bunch of stuff: - Remove skins. - Remove all custom sites for skin resources. - Remove "framed", "notlive", "preview", separate "live" controllers (see below). - Merge "publish" and "unpublish" controllers into one. New behavior: - Blogs and posts have three views: - "View": Internal view URI, which is a normal detail page. - "Internal Live": Internal view URI which is a little prettier. - "External Live": External view URI for an external domain. Right now, the differences are pretty minor (basically, different crumbs/chrome). This mostly gives us room to put some milder flavor of skins back later (photography or more "presentation" elements, for example). This removes 9 million lines of code so I probably missed a couple of things, but I think it's like 95% of the way there. Test Plan: Here are some examples of what the "view", "internal" and "external" views look like for blogs (posts are similar): "View": Unchanged {F1021634} "Internal": No chrome or footer. Still write actions (edit, post commments). Has crumbs to get back into Phame. {F1021635} "External": No chrome or footer. No write actions. No Phabricator crumbs. No policy/status information. {F1021638} I figure we'll probably tweak these a bit to figure out what makes sense (like: maybe no actions on "internal, live"? and "external, live" probably needs a way to set a root "Company >" crumb?) but that they're reasonable-ish as a first cut? Reviewers: chad Reviewed By: chad Maniphest Tasks: T9897 Differential Revision: https://secure.phabricator.com/D14740
2015-12-11 07:07:45 -08:00
}
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
// Draft posts are visible only to the author. Published posts are visible
// to whoever the blog is visible to.
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
if (!$this->isDraft() && $this->getBlog()) {
return $this->getBlog()->getViewPolicy();
} else if ($this->getBlog()) {
return $this->getBlog()->getEditPolicy();
} else {
return PhabricatorPolicies::POLICY_NOONE;
}
break;
case PhabricatorPolicyCapability::CAN_EDIT:
if ($this->getBlog()) {
return $this->getBlog()->getEditPolicy();
} else {
return PhabricatorPolicies::POLICY_NOONE;
}
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
// A blog post's author can always view it.
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
case PhabricatorPolicyCapability::CAN_EDIT:
return ($user->getPHID() == $this->getBloggerPHID());
}
}
public function describeAutomaticCapability($capability) {
return pht('The author of a blog post can always view and edit it.');
}
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
public function getMarkupFieldKey($field) {
$hash = PhabricatorHash::digest($this->getMarkupText($field));
return $this->getPHID().':'.$field.':'.$hash;
}
public function newMarkupEngine($field) {
return PhabricatorMarkupEngine::newPhameMarkupEngine();
}
public function getMarkupText($field) {
switch ($field) {
case self::MARKUP_FIELD_BODY:
return $this->getBody();
case self::MARKUP_FIELD_SUMMARY:
return PhabricatorMarkupEngine::summarize($this->getBody());
}
}
public function didMarkupText(
$field,
$output,
PhutilMarkupEngine $engine) {
return $output;
}
public function shouldUseMarkupCache($field) {
return (bool)$this->getPHID();
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new PhamePostEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new PhamePostTransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
public function getUsersToNotifyOfTokenGiven() {
return array(
$this->getBloggerPHID(),
);
}
/* -( PhabricatorSubscribableInterface Implementation )-------------------- */
public function isAutomaticallySubscribed($phid) {
return ($this->bloggerPHID == $phid);
}
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('title')
->setType('string')
->setDescription(pht('Title of the post.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('slug')
->setType('string')
->setDescription(pht('Slug for the post.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('blogPHID')
->setType('phid')
->setDescription(pht('PHID of the blog that the post belongs to.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('authorPHID')
->setType('phid')
->setDescription(pht('PHID of the author of the post.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('body')
->setType('string')
->setDescription(pht('Body of the post.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('datePublished')
->setType('epoch?')
->setDescription(pht('Publish date, if the post has been published.')),
);
}
public function getFieldValuesForConduit() {
if ($this->isDraft()) {
$date_published = null;
} else {
$date_published = (int)$this->getDatePublished();
}
return array(
'title' => $this->getTitle(),
'slug' => $this->getSlug(),
'blogPHID' => $this->getBlogPHID(),
'authorPHID' => $this->getBloggerPHID(),
'body' => $this->getBody(),
'datePublished' => $date_published,
);
}
public function getConduitSearchAttachments() {
return array();
}
}