2011-07-11 12:34:53 -07:00
|
|
|
<?php
|
|
|
|
|
|
2011-09-14 08:02:31 -07:00
|
|
|
/**
|
|
|
|
|
* @group phriction
|
|
|
|
|
*/
|
2012-03-09 15:46:25 -08:00
|
|
|
final class PhrictionEditController
|
2011-07-11 12:34:53 -07:00
|
|
|
extends PhrictionController {
|
|
|
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
|
$this->id = idx($data, 'id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
|
|
|
|
|
|
$request = $this->getRequest();
|
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
|
|
if ($this->id) {
|
|
|
|
|
$document = id(new PhrictionDocument())->load($this->id);
|
|
|
|
|
if (!$document) {
|
|
|
|
|
return new Aphront404Response();
|
|
|
|
|
}
|
2011-07-17 11:06:02 -07:00
|
|
|
|
|
|
|
|
$revert = $request->getInt('revert');
|
|
|
|
|
if ($revert) {
|
|
|
|
|
$content = id(new PhrictionContent())->loadOneWhere(
|
|
|
|
|
'documentID = %d AND version = %d',
|
|
|
|
|
$document->getID(),
|
|
|
|
|
$revert);
|
|
|
|
|
if (!$content) {
|
|
|
|
|
return new Aphront404Response();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$content = id(new PhrictionContent())->load($document->getContentID());
|
|
|
|
|
}
|
2011-08-31 12:00:34 -07:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
$slug = $request->getStr('slug');
|
2012-04-10 14:18:20 -07:00
|
|
|
$slug = PhabricatorSlug::normalize($slug);
|
2011-08-31 12:00:34 -07:00
|
|
|
if (!$slug) {
|
|
|
|
|
return new Aphront404Response();
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-12 08:08:03 -07:00
|
|
|
$document = id(new PhrictionDocument())->loadOneWhere(
|
|
|
|
|
'slug = %s',
|
|
|
|
|
$slug);
|
2011-07-11 12:34:53 -07:00
|
|
|
|
|
|
|
|
if ($document) {
|
|
|
|
|
$content = id(new PhrictionContent())->load($document->getContentID());
|
|
|
|
|
} else {
|
2012-05-20 08:54:25 -07:00
|
|
|
if (PhrictionDocument::isProjectSlug($slug)) {
|
|
|
|
|
$project = id(new PhabricatorProject())->loadOneWhere(
|
|
|
|
|
'phrictionSlug = %s',
|
|
|
|
|
PhrictionDocument::getProjectSlugIdentifier($slug));
|
|
|
|
|
if (!$project) {
|
|
|
|
|
return new Aphront404Response();
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-07-11 12:34:53 -07:00
|
|
|
$document = new PhrictionDocument();
|
|
|
|
|
$document->setSlug($slug);
|
|
|
|
|
|
|
|
|
|
$content = new PhrictionContent();
|
|
|
|
|
$content->setSlug($slug);
|
|
|
|
|
|
2012-04-10 14:18:20 -07:00
|
|
|
$default_title = PhabricatorSlug::getDefaultTitle($slug);
|
2011-07-11 12:34:53 -07:00
|
|
|
$content->setTitle($default_title);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-12 11:57:22 -08:00
|
|
|
if ($request->getBool('nodraft')) {
|
|
|
|
|
$draft = null;
|
|
|
|
|
$draft_key = null;
|
|
|
|
|
} else {
|
|
|
|
|
if ($document->getPHID()) {
|
|
|
|
|
$draft_key = $document->getPHID().':'.$content->getVersion();
|
|
|
|
|
} else {
|
|
|
|
|
$draft_key = 'phriction:'.$content->getSlug();
|
|
|
|
|
}
|
|
|
|
|
$draft = id(new PhabricatorDraft())->loadOneWhere(
|
|
|
|
|
'authorPHID = %s AND draftKey = %s',
|
|
|
|
|
$user->getPHID(),
|
|
|
|
|
$draft_key);
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-16 18:25:45 -07:00
|
|
|
require_celerity_resource('phriction-document-css');
|
|
|
|
|
|
2011-07-11 12:34:53 -07:00
|
|
|
$e_title = true;
|
2012-07-16 09:40:10 -07:00
|
|
|
$notes = null;
|
2011-07-11 12:34:53 -07:00
|
|
|
$errors = array();
|
|
|
|
|
|
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
|
$title = $request->getStr('title');
|
2012-07-16 09:40:10 -07:00
|
|
|
$notes = $request->getStr('description');
|
2011-07-11 12:34:53 -07:00
|
|
|
|
|
|
|
|
if (!strlen($title)) {
|
2013-02-08 09:54:27 -08:00
|
|
|
$e_title = pht('Required');
|
|
|
|
|
$errors[] = pht('Document title is required.');
|
2011-07-11 12:34:53 -07:00
|
|
|
} else {
|
|
|
|
|
$e_title = null;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-16 09:40:10 -07:00
|
|
|
if ($document->getID()) {
|
|
|
|
|
if ($content->getTitle() == $title &&
|
|
|
|
|
$content->getContent() == $request->getStr('content')) {
|
|
|
|
|
|
|
|
|
|
$dialog = new AphrontDialogView();
|
|
|
|
|
$dialog->setUser($user);
|
2013-02-08 09:54:27 -08:00
|
|
|
$dialog->setTitle(pht('No Edits'));
|
2013-02-13 14:50:15 -08:00
|
|
|
$dialog->appendChild(phutil_tag('p', array(), pht(
|
|
|
|
|
'You did not make any changes to the document.')));
|
2012-07-16 09:40:10 -07:00
|
|
|
$dialog->addCancelButton($request->getRequestURI());
|
|
|
|
|
|
|
|
|
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
|
|
|
|
}
|
2012-10-17 15:13:03 -07:00
|
|
|
} else if (!strlen($request->getStr('content'))) {
|
|
|
|
|
|
|
|
|
|
// We trigger this only for new pages. For existing pages, deleting
|
|
|
|
|
// all the content counts as deleting the page.
|
|
|
|
|
|
|
|
|
|
$dialog = new AphrontDialogView();
|
|
|
|
|
$dialog->setUser($user);
|
2013-02-08 09:54:27 -08:00
|
|
|
$dialog->setTitle(pht('Empty Page'));
|
2013-02-13 14:50:15 -08:00
|
|
|
$dialog->appendChild(phutil_tag('p', array(), pht(
|
|
|
|
|
'You can not create an empty document.')));
|
2012-10-17 15:13:03 -07:00
|
|
|
$dialog->addCancelButton($request->getRequestURI());
|
|
|
|
|
|
|
|
|
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
2012-07-16 09:40:10 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-11 12:34:53 -07:00
|
|
|
if (!count($errors)) {
|
2011-08-31 12:00:34 -07:00
|
|
|
$editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))
|
2012-10-10 10:18:23 -07:00
|
|
|
->setActor($user)
|
2011-08-26 12:50:28 -07:00
|
|
|
->setTitle($title)
|
|
|
|
|
->setContent($request->getStr('content'))
|
2012-07-16 09:40:10 -07:00
|
|
|
->setDescription($notes);
|
2011-07-11 12:34:53 -07:00
|
|
|
|
2011-08-26 12:50:28 -07:00
|
|
|
$editor->save();
|
2011-07-11 12:34:53 -07:00
|
|
|
|
2012-01-12 11:57:22 -08:00
|
|
|
if ($draft) {
|
|
|
|
|
$draft->delete();
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-31 12:00:34 -07:00
|
|
|
$uri = PhrictionDocument::getSlugURI($document->getSlug());
|
2011-07-11 12:34:53 -07:00
|
|
|
return id(new AphrontRedirectResponse())->setURI($uri);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$error_view = null;
|
|
|
|
|
if ($errors) {
|
|
|
|
|
$error_view = id(new AphrontErrorView())
|
2013-02-08 09:54:27 -08:00
|
|
|
->setTitle(pht('Form Errors'))
|
2011-07-11 12:34:53 -07:00
|
|
|
->setErrors($errors);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($document->getID()) {
|
2013-02-08 09:54:27 -08:00
|
|
|
$panel_header = pht('Edit Phriction Document');
|
|
|
|
|
$submit_button = pht('Save Changes');
|
2011-07-11 12:34:53 -07:00
|
|
|
} else {
|
2013-02-08 09:54:27 -08:00
|
|
|
$panel_header = pht('Create New Phriction Document');
|
|
|
|
|
$submit_button = pht('Create Document');
|
2011-07-11 12:34:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$uri = $document->getSlug();
|
|
|
|
|
$uri = PhrictionDocument::getSlugURI($uri);
|
|
|
|
|
$uri = PhabricatorEnv::getProductionURI($uri);
|
|
|
|
|
|
2011-07-15 14:24:50 -07:00
|
|
|
$cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
|
|
|
|
|
|
2012-01-12 11:57:22 -08:00
|
|
|
if ($draft &&
|
|
|
|
|
strlen($draft->getDraft()) &&
|
|
|
|
|
($draft->getDraft() != $content->getContent())) {
|
|
|
|
|
$content_text = $draft->getDraft();
|
|
|
|
|
|
2013-01-17 18:57:09 -08:00
|
|
|
$discard = phutil_tag(
|
2012-01-12 11:57:22 -08:00
|
|
|
'a',
|
|
|
|
|
array(
|
|
|
|
|
'href' => $request->getRequestURI()->alter('nodraft', true),
|
|
|
|
|
),
|
2013-02-08 09:54:27 -08:00
|
|
|
pht('discard this draft'));
|
2012-01-12 11:57:22 -08:00
|
|
|
|
|
|
|
|
$draft_note = new AphrontErrorView();
|
|
|
|
|
$draft_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
|
|
|
|
$draft_note->setTitle('Recovered Draft');
|
2013-02-06 16:53:49 -08:00
|
|
|
$draft_note->appendChild(hsprintf(
|
|
|
|
|
'<p>Showing a saved draft of your edits, you can %s.</p>',
|
|
|
|
|
$discard));
|
2012-01-12 11:57:22 -08:00
|
|
|
} else {
|
|
|
|
|
$content_text = $content->getContent();
|
|
|
|
|
$draft_note = null;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-11 12:34:53 -07:00
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
|
->setUser($user)
|
2012-07-16 09:40:10 -07:00
|
|
|
->setWorkflow(true)
|
2011-07-11 12:34:53 -07:00
|
|
|
->setAction($request->getRequestURI()->getPath())
|
2011-08-31 12:00:34 -07:00
|
|
|
->addHiddenInput('slug', $document->getSlug())
|
2012-01-12 11:57:22 -08:00
|
|
|
->addHiddenInput('nodraft', $request->getBool('nodraft'))
|
2011-07-11 12:34:53 -07:00
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-08 09:54:27 -08:00
|
|
|
->setLabel(pht('Title'))
|
2011-07-11 12:34:53 -07:00
|
|
|
->setValue($content->getTitle())
|
|
|
|
|
->setError($e_title)
|
|
|
|
|
->setName('title'))
|
|
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormStaticControl())
|
2013-02-08 09:54:27 -08:00
|
|
|
->setLabel(pht('URI'))
|
2011-07-11 12:34:53 -07:00
|
|
|
->setValue($uri))
|
|
|
|
|
->appendChild(
|
2012-09-19 12:27:28 -07:00
|
|
|
id(new PhabricatorRemarkupControl())
|
2013-02-08 09:54:27 -08:00
|
|
|
->setLabel(pht('Content'))
|
2012-01-12 11:57:22 -08:00
|
|
|
->setValue($content_text)
|
2011-07-11 12:34:53 -07:00
|
|
|
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
2011-07-12 08:28:07 -07:00
|
|
|
->setName('content')
|
2012-11-27 14:06:31 -08:00
|
|
|
->setID('document-textarea')
|
|
|
|
|
->setUser($user))
|
2011-12-17 09:19:08 -08:00
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-08 09:54:27 -08:00
|
|
|
->setLabel(pht('Edit Notes'))
|
2012-07-16 09:40:10 -07:00
|
|
|
->setValue($notes)
|
2011-12-17 09:19:08 -08:00
|
|
|
->setError(null)
|
|
|
|
|
->setName('description'))
|
2011-07-11 12:34:53 -07:00
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormSubmitControl())
|
2011-07-15 14:24:50 -07:00
|
|
|
->addCancelButton($cancel_uri)
|
2011-07-11 12:34:53 -07:00
|
|
|
->setValue($submit_button));
|
|
|
|
|
|
Update form styles, implement in many places
Summary:
This creates a common form look and feel across the site. I spent a bit of time working out a number of kinks in our various renderings. Some things:
- Font Styles are correctly applied for form elements now.
- Everything lines up!
- Selects are larger, easier to read, interact.
- Inputs have been squared.
- Consistant CSS applied glow (try it!)
- Improved Mobile Responsiveness
- CSS applied to all form elements, not just Aphront
- Many other minor tweaks.
I tried to hit as many high profile forms as possible in an effort to increase consistency. Stopped for now and will follow up after this lands. I know Evan is not a super fan of the glow, but after working with it for a week, it's way cleaner and responsive than the OS controls. Give it a try.
Test Plan: Tested many applications, forms, mobile and tablet.
Reviewers: epriestley, btrahan
Reviewed By: epriestley
CC: aran, Korvin
Differential Revision: https://secure.phabricator.com/D5860
2013-05-07 14:07:06 -07:00
|
|
|
$header = id(new PhabricatorHeaderView())
|
|
|
|
|
->setHeader($panel_header);
|
2011-07-11 12:34:53 -07:00
|
|
|
|
2013-08-05 10:47:26 -07:00
|
|
|
$preview = id(new PHUIRemarkupPreviewPanel())
|
|
|
|
|
->setHeader(pht('Document Preview'))
|
|
|
|
|
->setPreviewURI('/phriction/preview/')
|
|
|
|
|
->setControlID('document-textarea')
|
|
|
|
|
->setSkin('document');
|
2011-07-16 18:25:45 -07:00
|
|
|
|
2013-07-27 18:26:42 -07:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
|
if ($document->getID()) {
|
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
|
->setName($content->getTitle())
|
|
|
|
|
->setHref(PhrictionDocument::getSlugURI($document->getSlug())));
|
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
|
->setName(pht('Edit')));
|
|
|
|
|
} else {
|
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
|
->setName(pht('Create')));
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-09 08:36:28 -08:00
|
|
|
return $this->buildApplicationPage(
|
2011-07-11 12:34:53 -07:00
|
|
|
array(
|
2013-07-27 18:26:42 -07:00
|
|
|
$crumbs,
|
2012-01-12 11:57:22 -08:00
|
|
|
$draft_note,
|
2011-07-11 12:34:53 -07:00
|
|
|
$error_view,
|
Update form styles, implement in many places
Summary:
This creates a common form look and feel across the site. I spent a bit of time working out a number of kinks in our various renderings. Some things:
- Font Styles are correctly applied for form elements now.
- Everything lines up!
- Selects are larger, easier to read, interact.
- Inputs have been squared.
- Consistant CSS applied glow (try it!)
- Improved Mobile Responsiveness
- CSS applied to all form elements, not just Aphront
- Many other minor tweaks.
I tried to hit as many high profile forms as possible in an effort to increase consistency. Stopped for now and will follow up after this lands. I know Evan is not a super fan of the glow, but after working with it for a week, it's way cleaner and responsive than the OS controls. Give it a try.
Test Plan: Tested many applications, forms, mobile and tablet.
Reviewers: epriestley, btrahan
Reviewed By: epriestley
CC: aran, Korvin
Differential Revision: https://secure.phabricator.com/D5860
2013-05-07 14:07:06 -07:00
|
|
|
$form,
|
2013-08-05 10:47:26 -07:00
|
|
|
$preview,
|
2011-07-11 12:34:53 -07:00
|
|
|
),
|
|
|
|
|
array(
|
2013-04-11 15:05:50 -07:00
|
|
|
'title' => pht('Edit Document'),
|
|
|
|
|
'device' => true,
|
2011-07-11 12:34:53 -07:00
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|