Modernize Macro application

Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.

Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}

Reviewers: vrana, btrahan, chad

Reviewed By: vrana

CC: aran

Maniphest Tasks: T2157, T175, T2104

Differential Revision: https://secure.phabricator.com/D4141
This commit is contained in:
epriestley
2012-12-11 14:01:03 -08:00
parent 4081579e79
commit ba7723d905
33 changed files with 1233 additions and 117 deletions

View File

@@ -26,8 +26,11 @@ final class PhabricatorApplicationMacro extends PhabricatorApplication {
return array(
'/macro/' => array(
'' => 'PhabricatorMacroListController',
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'PhabricatorMacroEditController',
'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroDeleteController',
'create/' => 'PhabricatorMacroEditController',
'view/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroViewController',
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroCommentController',
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroEditController',
'disable/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroDisableController',
),
);
}

View File

@@ -0,0 +1,9 @@
<?php
final class PhabricatorMacroTransactionType {
const TYPE_NAME = 'macro:name';
const TYPE_DISABLED = 'macro:disabled';
const TYPE_FILE = 'macro:file';
}

View File

@@ -0,0 +1,49 @@
<?php
final class PhabricatorMacroCommentController
extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if (!$request->isFormPost()) {
return new Aphront400Response();
}
$macro = id(new PhabricatorFileImageMacro())->load($this->id);
if (!$macro) {
return new Aphront404Response();
}
$view_uri = $this->getApplicationURI('/view/'.$macro->getID().'/');
$xactions = array();
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->attachComment(
id(new PhabricatorMacroTransactionComment())
->setContent($request->getStr('comment')));
$editor = id(new PhabricatorMacroEditor())
->setActor($user)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_WEB,
array(
'ip' => $request->getRemoteAddr(),
)))
->applyTransactions($macro, $xactions);
return id(new AphrontRedirectResponse())
->setURI($view_uri);
}
}

View File

@@ -3,19 +3,39 @@
abstract class PhabricatorMacroController
extends PhabricatorController {
protected function buildSideNavView(PhabricatorFileImageMacro $macro = null) {
protected function buildSideNavView($for_app = false, $has_search = false) {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
$nav->addLabel('Create');
$nav->addFilter('edit', 'Create Macro');
$nav->addSpacer();
if ($for_app) {
$nav->addLabel('Create');
$nav->addFilter('', 'Create Macro', $this->getApplicationURI('/create/'));
}
$nav->addLabel('Macros');
$nav->addFilter('', 'All Macros');
$nav->addFilter('/', 'All Macros');
if ($has_search) {
$nav->addFilter('search', 'Search', $this->getRequest()->getRequestURI());
}
return $nav;
}
public function buildApplicationMenu() {
return $this->buildSideNavView($for_app = true)->getMenu();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PhabricatorMenuItemView())
->setName(pht('Create Macro'))
->setHref($this->getApplicationURI('/create/'))
->setIcon('create'));
return $crumbs;
}
}

View File

@@ -1,42 +0,0 @@
<?php
final class PhabricatorMacroDeleteController
extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$macro = id(new PhabricatorFileImageMacro())->load($this->id);
if (!$macro) {
return new Aphront404Response();
}
$request = $this->getRequest();
if ($request->isDialogFormPost()) {
$macro->delete();
return id(new AphrontRedirectResponse())->setURI(
$this->getApplicationURI());
}
$dialog = new AphrontDialogView();
$dialog
->setUser($request->getUser())
->setTitle('Really delete macro?')
->appendChild(
'<p>Really delete the much-beloved image macro "'.
phutil_escape_html($macro->getName()).'"? It will be sorely missed.'.
'</p>')
->setSubmitURI($this->getApplicationURI('/delete/'.$this->id.'/'))
->addSubmitButton('Delete')
->addCancelButton($this->getApplicationURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}

View File

@@ -0,0 +1,55 @@
<?php
final class PhabricatorMacroDisableController
extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$macro = id(new PhabricatorFileImageMacro())->load($this->id);
if (!$macro) {
return new Aphront404Response();
}
$view_uri = $this->getApplicationURI('/view/'.$this->id.'/');
if ($request->isDialogFormPost() || $macro->getIsDisabled()) {
$xaction = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_DISABLED)
->setNewValue($macro->getIsDisabled() ? 0 : 1);
$editor = id(new PhabricatorMacroEditor())
->setActor($user)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_WEB,
array(
'ip' => $request->getRemoteAddr(),
)))
->applyTransactions($macro, array($xaction));
return id(new AphrontRedirectResponse())->setURI($view_uri);
}
$dialog = new AphrontDialogView();
$dialog
->setUser($request->getUser())
->setTitle('Really disable macro?')
->appendChild(
'<p>Really disable the much-beloved image macro "'.
phutil_escape_html($macro->getName()).'"? It will be sorely missed.'.
'</p>')
->setSubmitURI($this->getApplicationURI('/disable/'.$this->id.'/'))
->addSubmitButton('Disable')
->addCancelButton($view_uri);
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}

View File

@@ -22,56 +22,96 @@ final class PhabricatorMacroEditController
$errors = array();
$e_name = true;
$e_file = true;
$file = null;
$request = $this->getRequest();
$user = $request->getUser();
if ($request->isFormPost()) {
$original = clone $macro;
$macro->setName($request->getStr('name'));
$new_name = null;
if ($request->getBool('name_form') || !$macro->getID()) {
$new_name = $request->getStr('name');
if (!strlen($macro->getName())) {
$errors[] = 'Macro name is required.';
$e_name = 'Required';
} else if (!preg_match('/^[a-z0-9_-]{3,}$/', $macro->getName())) {
$errors[] = 'Macro must be at least three characters long and contain '.
'only lowercase letters, digits, hyphen and underscore.';
$e_name = 'Invalid';
} else {
$e_name = null;
$macro->setName($new_name);
if (!strlen($macro->getName())) {
$errors[] = 'Macro name is required.';
$e_name = 'Required';
} else if (!preg_match('/^[a-z0-9_-]{3,}$/', $macro->getName())) {
$errors[] = 'Macro must be at least three characters long and '.
'contain only lowercase letters, digits, hyphen and '.
'underscore.';
$e_name = 'Invalid';
} else {
$e_name = null;
}
}
if (!$errors) {
$file = null;
if ($request->getFileExists('file')) {
$file = PhabricatorFile::newFromPHPUpload(
idx($_FILES, 'file'),
$_FILES['file'],
array(
'name' => $request->getStr('name'),
'authorPHID' => $user->getPHID(),
));
$macro->setFilePHID($file->getPHID());
} else if ($request->getStr('phid')) {
$file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$request->getStr('phid'));
}
if ($file) {
if (!$file->isViewableInBrowser()) {
$errors[] = pht('You must upload an image.');
$e_file = pht('Invalid');
} else {
$macro->setFilePHID($file->getPHID());
$e_file = null;
}
}
if (!$macro->getID() && !$file) {
$errors[] = 'You must upload an image to create a macro.';
$e_file = pht('Required');
}
if (!$errors) {
try {
$macro->save();
return id(new AphrontRedirectResponse())->setURI(
$this->getApplicationURI());
$xactions = array();
if ($new_name !== null) {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_NAME)
->setNewValue($new_name);
}
if ($file) {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_FILE)
->setNewValue($file->getPHID());
}
$editor = id(new PhabricatorMacroEditor())
->setActor($user)
->setContentSource(
PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_WEB,
array(
'ip' => $request->getRemoteAddr(),
)))
->applyTransactions($original, $xactions);
$view_uri = $this->getApplicationURI('/view/'.$original->getID().'/');
return id(new AphrontRedirectResponse())->setURI($view_uri);
} catch (AphrontQueryDuplicateKeyException $ex) {
throw $ex;
$errors[] = 'Macro name is not unique!';
$e_name = 'Duplicate';
}
}
} else if ($this->id) {
$file = id(new PhabricatorFile())
->loadOneWhere('phid = %s', $macro->getFilePHID());
}
$caption = null;
if ($file) {
$caption = phutil_render_tag(
'img',
array(
'src' => $file->getViewURI(),
));
}
if ($errors) {
@@ -82,7 +122,17 @@ final class PhabricatorMacroEditController
$error_view = null;
}
$current_file = null;
if ($macro->getFilePHID()) {
$current_file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$macro->getFilePHID());
}
$form = new AphrontFormView();
$form->setFlexible(true);
$form->addHiddenInput('name_form', 1);
$form->setUser($request->getUser());
$form
@@ -93,35 +143,101 @@ final class PhabricatorMacroEditController
->setName('name')
->setValue($macro->getName())
->setCaption('This word or phrase will be replaced with the image.')
->setError($e_name))
->appendChild(
->setError($e_name));
if (!$macro->getID()) {
if ($current_file) {
$current_file_view = id(new PhabricatorFileLinkView())
->setFilePHID($current_file->getPHID())
->setFileName($current_file->getName())
->setFileViewable(true)
->setFileViewURI($current_file->getBestURI())
->render();
$form->addHiddenInput('phid', $current_file->getPHID());
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel('Selected File')
->setValue($current_file_view));
$other_label = pht('Change File');
} else {
$other_label = pht('File');
}
$form->appendChild(
id(new AphrontFormFileControl())
->setLabel('File')
->setLabel($other_label)
->setName('file')
->setCaption($caption)
->setError(true))
->setError($e_file));
}
$view_uri = $this->getApplicationURI('/view/'.$macro->getID().'/');
if ($macro->getID()) {
$cancel_uri = $view_uri;
} else {
$cancel_uri = $this->getApplicationURI();
}
$form
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Save Image Macro')
->addCancelButton($this->getApplicationURI()));
->setValue(pht('Save Image Macro'))
->addCancelButton($cancel_uri));
$crumbs = $this->buildApplicationCrumbs();
$panel = new AphrontPanelView();
if ($macro->getID()) {
$title = 'Edit Image Macro';
} else {
$title = 'Create Image Macro';
}
$panel->setHeader($title);
$panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$title = pht('Edit Image Macro');
$crumb = pht('Edit');
$nav = $this->buildSideNavView($macro);
$nav->selectFilter('#', 'edit');
$nav->appendChild($error_view);
$nav->appendChild($panel);
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setHref($view_uri)
->setName(pht('Macro "%s"', $macro->getName())));
} else {
$title = pht('Create Image Macro');
$crumb = pht('Create');
}
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setHref($request->getRequestURI())
->setName($crumb));
$header = id(new PhabricatorHeaderView())
->setHeader($title);
$upload = null;
if ($macro->getID()) {
$upload_header = id(new PhabricatorHeaderView())
->setHeader(pht('Upload New File'));
$upload_form = id(new AphrontFormView())
->setFlexible(true)
->setEncType('multipart/form-data')
->setUser($request->getUser())
->appendChild(
id(new AphrontFormFileControl())
->setLabel('File')
->setName('file'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Upload File'));
$upload = array($upload_header, $upload_form);
}
return $this->buildApplicationPage(
$nav,
array(
$crumbs,
$header,
$error_view,
$form,
$upload,
),
array(
'title' => $title,
));

View File

@@ -70,8 +70,11 @@ final class PhabricatorMacroListController
$filter_view = new AphrontListFilterView();
$filter_view->appendChild($filter_form);
$nav = $this->buildSideNavView();
$nav->selectFilter('/');
$has_search = strlen($filter);
$nav = $this->buildSideNavView(
$for_app = false,
$has_search);
$nav->selectFilter($has_search ? 'search' : '/');
$nav->appendChild($filter_view);
@@ -97,7 +100,7 @@ final class PhabricatorMacroListController
array(),
'Created on '.$datetime));
}
$item->setURI($this->getApplicationURI('/edit/'.$macro->getID().'/'));
$item->setURI($this->getApplicationURI('/view/'.$macro->getID().'/'));
$item->setHeader($macro->getName());
$pinboard->addItem($item);
@@ -109,11 +112,20 @@ final class PhabricatorMacroListController
$nav->appendChild($list);
}
if ($filter === null) {
if (!strlen($filter)) {
$nav->appendChild($pager);
$name = pht('All Macros');
} else {
$name = pht('Search');
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($name)
->setHref($request->getRequestURI()));
$nav->setCrumbs($crumbs);
return $this->buildApplicationPage(
$nav,
array(

View File

@@ -0,0 +1,193 @@
<?php
final class PhabricatorMacroViewController
extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$macro = id(new PhabricatorFileImageMacro())->load($this->id);
if (!$macro) {
return new Aphront404Response();
}
$file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$macro->getFilePHID());
$title_short = pht('Macro "%s"', $macro->getName());
$title_long = pht('Image Macro "%s"', $macro->getName());
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
$macro->getPHID());
$this->loadHandles($subscribers);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setHref($this->getApplicationURI('/view/'.$macro->getID().'/'))
->setName($title_short));
$actions = $this->buildActionView($macro);
$properties = $this->buildPropertyView($macro, $file, $subscribers);
$xactions = id(new PhabricatorMacroTransactionQuery())
->setViewer($request->getUser())
->withObjectPHIDs(array($macro->getPHID()))
->execute();
$engine = id(new PhabricatorMarkupEngine())
->setViewer($user);
foreach ($xactions as $xaction) {
if ($xaction->getComment()) {
$engine->addObject(
$xaction->getComment(),
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
}
}
$engine->process();
$timeline = id(new PhabricatorApplicationTransactionView())
->setViewer($user)
->setTransactions($xactions)
->setMarkupEngine($engine);
$header = id(new PhabricatorHeaderView())
->setHeader($title_long);
if ($macro->getIsDisabled()) {
$header->addTag(
id(new PhabricatorTagView())
->setType(PhabricatorTagView::TYPE_STATE)
->setName(pht('Macro Disabled'))
->setBackgroundColor(PhabricatorTagView::COLOR_RED));
}
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$add_comment_header = id(new PhabricatorHeaderView())
->setHeader(
$is_serious
? pht('Add Comment')
: pht('Grovel in Awe'));
$add_comment_form = id(new AphrontFormView())
->setWorkflow(true)
->setFlexible(true)
->setAction($this->getApplicationURI('/comment/'.$macro->getID().'/'))
->setUser($user)
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($user)
->setLabel('Comment')
->setName('comment'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(
$is_serious
? pht('Add Comment')
: pht('Lavish Praise')));
return $this->buildApplicationPage(
array(
$crumbs,
$header,
$actions,
$properties,
$timeline,
$add_comment_header,
$add_comment_form,
),
array(
'title' => $title_short,
));
}
private function buildActionView(PhabricatorFileImageMacro $macro) {
$view = new PhabricatorActionListView();
$view->setUser($this->getRequest()->getUser());
$view->setObject($macro);
$view->addAction(
id(new PhabricatorActionView())
->setName('Edit Macro')
->setHref($this->getApplicationURI('/edit/'.$macro->getID().'/'))
->setIcon('edit'));
if ($macro->getIsDisabled()) {
$view->addAction(
id(new PhabricatorActionView())
->setName('Restore Macro')
->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/'))
->setWorkflow(true)
->setIcon('undo'));
} else {
$view->addAction(
id(new PhabricatorActionView())
->setName('Disable Macro')
->setHref($this->getApplicationURI('/disable/'.$macro->getID().'/'))
->setWorkflow(true)
->setIcon('delete'));
}
return $view;
}
private function buildPropertyView(
PhabricatorFileImageMacro $macro,
PhabricatorFile $file = null,
array $subscribers) {
$view = new PhabricatorPropertyListView();
$view->addProperty(
pht('Name'),
phutil_escape_html($macro->getName()));
$view->addProperty(
pht('Status'),
$macro->getIsDisabled()
? pht('Disabled')
: pht('Enabled'));
$view->addProperty(
pht('Created'),
phabricator_date(
$macro->getDateCreated(),
$this->getRequest()->getUser()));
if ($subscribers) {
$sub_view = array();
foreach ($subscribers as $subscriber) {
$sub_view[] = $this->getHandle($subscriber)->renderLink();
}
$sub_view = implode(', ', $sub_view);
} else {
$sub_view = '<em>'.pht('None').'</em>';
}
$view->addProperty(
pht('Subscribers'),
$sub_view);
if ($file) {
$view->addTextContent(
phutil_render_tag(
'img',
array(
'src' => $file->getViewURI(),
'class' => 'phabricator-image-macro-hero',
)));
}
return $view;
}
}

View File

@@ -0,0 +1,123 @@
<?php
final class PhabricatorMacroEditor
extends PhabricatorApplicationTransactionEditor {
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorMacroTransactionType::TYPE_NAME;
$types[] = PhabricatorMacroTransactionType::TYPE_DISABLED;
$types[] = PhabricatorMacroTransactionType::TYPE_FILE;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return $object->getName();
case PhabricatorMacroTransactionType::TYPE_DISABLED:
return $object->getIsDisabled();
case PhabricatorMacroTransactionType::TYPE_FILE:
return $object->getFilePHID();
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
case PhabricatorMacroTransactionType::TYPE_DISABLED:
case PhabricatorMacroTransactionType::TYPE_FILE:
return $xaction->getNewValue();
}
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
$object->setName($xaction->getNewValue());
break;
case PhabricatorMacroTransactionType::TYPE_DISABLED:
$object->setIsDisabled($xaction->getNewValue());
break;
case PhabricatorMacroTransactionType::TYPE_FILE:
$object->setFilePHID($xaction->getNewValue());
break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
return;
}
protected function mergeTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$type = $u->getTransactionType();
switch ($type) {
case PhabricatorMacroTransactionType::TYPE_NAME:
case PhabricatorMacroTransactionType::TYPE_DISABLED:
case PhabricatorMacroTransactionType::TYPE_FILE:
return $v;
}
return parent::mergeTransactions($u, $v);
}
protected function supportsMail() {
return true;
}
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
return id(new PhabricatorMacroReplyHandler())
->setMailReceiver($object);
}
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
$name = $object->getName();
$name = 'Image Macro "'.$name.'"';
return id(new PhabricatorMetaMTAMail())
->setSubject($name)
->addHeader('Thread-Topic', $name);
}
protected function getMailTo(PhabricatorLiskDAO $object) {
return array(
$this->requireActor()->getPHID(),
);
}
protected function buildMailBody(
PhabricatorLiskDAO $object,
array $xactions) {
$body = parent::buildMailBody($object, $xactions);
$body->addTextSection(
pht('MACRO DETAIL'),
PhabricatorEnv::getProductionURI('/macro/view/'.$object->getID().'/'));
return $body;
}
protected function getMailSubjectPrefix() {
return PhabricatorEnv::getEnvConfig('metamta.macro.subject-prefix');
}
protected function supportsFeed() {
return true;
}
}

View File

@@ -0,0 +1,40 @@
<?php
final class PhabricatorMacroReplyHandler extends PhabricatorMailReplyHandler {
public function validateMailReceiver($mail_receiver) {
if (!($mail_receiver instanceof PhabricatorFileImageMacro)) {
throw new Exception("Mail receiver is not a PhabricatorFileImageMacro!");
}
}
public function getPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle) {
return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'MCRO');
}
public function getPublicReplyHandlerEmailAddress() {
return $this->getDefaultPublicReplyHandlerEmailAddress('MCRO');
}
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig(
'metamta.macro.reply-handler-domain');
}
public function getReplyHandlerInstructions() {
if ($this->supportsReplies()) {
// TODO: Implement.
return null;
return "Reply to comment.";
} else {
return null;
}
}
protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) {
// TODO: Implement this.
return null;
}
}

View File

@@ -0,0 +1,10 @@
<?php
final class PhabricatorMacroTransactionQuery
extends PhabricatorApplicationTransactionQuery {
protected function getTemplateApplicationTransaction() {
return new PhabricatorMacroTransaction();
}
}

View File

@@ -1,16 +1,24 @@
<?php
final class PhabricatorFileImageMacro extends PhabricatorFileDAO {
final class PhabricatorFileImageMacro extends PhabricatorFileDAO
implements PhabricatorSubscribableInterface {
protected $filePHID;
protected $phid;
protected $name;
protected $isDisabled = 0;
public function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_MCRO);
}
static public function newFromImageURI($uri, $file_name, $image_macro_name) {
$file = PhabricatorFile::newFromFileDownload($uri, $file_name);
@@ -25,5 +33,10 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO {
return $image_macro;
}
public function isAutomaticallySubscribed($phid) {
return false;
}
}

View File

@@ -0,0 +1,231 @@
<?php
final class PhabricatorMacroTransaction
extends PhabricatorApplicationTransaction {
public function getApplicationName() {
return 'file';
}
public function getTableName() {
return 'macro_transaction';
}
public function getApplicationTransactionType() {
return PhabricatorPHIDConstants::PHID_TYPE_MCRO;
}
public function getApplicationTransactionCommentObject() {
return new PhabricatorMacroTransactionComment();
}
public function getApplicationObjectTypeName() {
return pht('macro');
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old !== null) {
$phids[] = $old;
}
$phids[] = $new;
break;
}
return $phids;
}
public function shouldHide() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return ($old === null);
}
return parent::shouldHide();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return pht(
'%s renamed this macro from "%s" to "%s".',
$this->renderHandleLink($author_phid),
phutil_escape_html($old),
phutil_escape_html($new));
break;
case PhabricatorMacroTransactionType::TYPE_DISABLED:
if ($new) {
return pht(
'%s disabled this macro.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s restored this macro.',
$this->renderHandleLink($author_phid));
}
break;
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) {
return pht(
'%s created this macro.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed the image for this macro from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
break;
}
return parent::getTitle();
}
public function getTitleForFeed() {
$author_phid = $this->getAuthorPHID();
$object_phid = $this->getObjectPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return pht(
'%s renamed %s from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
phutil_escape_html($old),
phutil_escape_html($new));
case PhabricatorMacroTransactionType::TYPE_DISABLED:
if ($new) {
return pht(
'%s disabled %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s restored %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) {
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s updated the image for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
}
return parent::getTitleForFeed();
}
public function getActionName() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
if ($old === null) {
return pht('Created');
} else {
return pht('Renamed');
}
case PhabricatorMacroTransactionType::TYPE_DISABLED:
if ($new) {
return pht('Disabled');
} else {
return pht('Restored');
}
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) {
return pht('Created');
} else {
return pht('Edited Image');
}
}
return parent::getActionName();
}
public function getActionStrength() {
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_DISABLED:
return 2.0;
case PhabricatorMacroTransactionType::TYPE_FILE:
return 1.5;
}
return parent::getActionStrength();
}
public function getIcon() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return 'edit';
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) {
return 'create';
} else {
return 'edit';
}
case PhabricatorMacroTransactionType::TYPE_DISABLED:
if ($new) {
return 'delete';
} else {
return 'undo';
}
}
return parent::getIcon();
}
public function getColor() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_NAME:
return PhabricatorTransactions::COLOR_BLUE;
case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) {
return PhabricatorTransactions::COLOR_GREEN;
} else {
return PhabricatorTransactions::COLOR_BLUE;
}
case PhabricatorMacroTransactionType::TYPE_DISABLED:
if ($new) {
return PhabricatorTransactions::COLOR_BLACK;
} else {
return PhabricatorTransactions::COLOR_SKY;
}
}
return parent::getColor();
}
}

View File

@@ -0,0 +1,11 @@
<?php
final class PhabricatorMacroTransactionComment
extends PhabricatorApplicationTransactionComment {
public function getApplicationTransactionObject() {
return new PhabricatorMacroTransaction();
}
}