mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Basic edit/create workflow for Phriction
Summary: This is another chunk of D636, I just simplified it a bit and added slugs. When you go to a page like /w/pokemon/, it allows you to create or edit the page. Title vs slug stuff is a little funky but I think mostly-reasonable. Test Plan: Created and edited /w/, /w/pokemon/, etc. Reviewed By: hsb Reviewers: hsb, codeblock, jungejason, aran, tuomaspelkonen CC: aran, hsb Differential Revision: 643
This commit is contained in:
parent
a20e46b061
commit
5704b2bc70
12 changed files with 329 additions and 4 deletions
22
resources/sql/patches/061.phrictioncontent.sql
Normal file
22
resources/sql/patches/061.phrictioncontent.sql
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* Patch 060 neglected to make this an AUTO_INCREMENT PRIMARY KEY */
|
||||
ALTER TABLE phabricator_phriction.phriction_document
|
||||
CHANGE id id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
|
||||
|
||||
/* Needs to be initially nullable for insert when documents are created. */
|
||||
ALTER TABLE phabricator_phriction.phriction_document
|
||||
CHANGE contentID contentID INT UNSIGNED;
|
||||
|
||||
CREATE TABLE phabricator_phriction.phriction_content (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
version INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY (documentID, version),
|
||||
authorPHID VARCHAR(64) BINARY NOT NULL,
|
||||
KEY (authorPHID),
|
||||
title VARCHAR(512) NOT NULL,
|
||||
slug VARCHAR(512) NOT NULL,
|
||||
KEY (slug),
|
||||
content LONGBLOB NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB;
|
|
@ -1135,6 +1135,15 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/css/application/uiexample/example.css',
|
||||
),
|
||||
'phriction-document-css' =>
|
||||
array(
|
||||
'uri' => '/res/b682cd2e/rsrc/css/application/phriction/phriction-document-css.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
),
|
||||
'disk' => '/rsrc/css/application/phriction/phriction-document-css.css',
|
||||
),
|
||||
'syntax-highlighting-css' =>
|
||||
array(
|
||||
'uri' => '/res/e5cc3d88/rsrc/css/core/syntax.css',
|
||||
|
|
|
@ -579,10 +579,12 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/profile',
|
||||
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/symbol',
|
||||
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/toplevel',
|
||||
'PhrictionContent' => 'applications/phriction/storage/content',
|
||||
'PhrictionController' => 'applications/phriction/controller/base',
|
||||
'PhrictionDAO' => 'applications/phriction/storage/base',
|
||||
'PhrictionDocument' => 'applications/phriction/storage/document',
|
||||
'PhrictionDocumentController' => 'applications/phriction/controller/document',
|
||||
'PhrictionEditController' => 'applications/phriction/controller/edit',
|
||||
),
|
||||
'function' =>
|
||||
array(
|
||||
|
@ -1072,10 +1074,12 @@ phutil_register_library_map(array(
|
|||
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
|
||||
'PhabricatorXHProfProfileSymbolView' => 'AphrontView',
|
||||
'PhabricatorXHProfProfileTopLevelView' => 'AphrontView',
|
||||
'PhrictionContent' => 'PhrictionDAO',
|
||||
'PhrictionController' => 'PhabricatorController',
|
||||
'PhrictionDAO' => 'PhabricatorLiskDAO',
|
||||
'PhrictionDocument' => 'PhrictionDAO',
|
||||
'PhrictionDocumentController' => 'PhrictionController',
|
||||
'PhrictionEditController' => 'PhrictionController',
|
||||
),
|
||||
'requires_interface' =>
|
||||
array(
|
||||
|
|
|
@ -345,6 +345,10 @@ class AphrontDefaultApplicationConfiguration
|
|||
'/w(?P<slug>/)$' => 'PhrictionDocumentController',
|
||||
// Match "/w/x/y/z/" with slug "x/y/z/".
|
||||
'/w/(?P<slug>.+/)$' => 'PhrictionDocumentController',
|
||||
|
||||
'/phriction/' => array(
|
||||
'edit/(?:(?P<id>\d+)/)?$' => 'PhrictionEditController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ abstract class PhrictionController extends PhabricatorController {
|
|||
$page = $this->buildStandardPageView();
|
||||
|
||||
$page->setApplicationName('Phriction');
|
||||
$page->setBaseURI('/phriction/');
|
||||
$page->setBaseURI('/w/');
|
||||
$page->setTitle(idx($data, 'title'));
|
||||
$page->setGlyph("\xE2\x9A\xA1");
|
||||
|
||||
|
|
|
@ -34,12 +34,46 @@ class PhrictionDocumentController
|
|||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
|
||||
$slug_info = 'Phriction page for '.phutil_escape_html($this->slug);
|
||||
require_celerity_resource('phriction-document-css');
|
||||
|
||||
$document = id(new PhrictionDocument())->loadOneWhere(
|
||||
'slug = %s',
|
||||
$slug);
|
||||
|
||||
if (!$document) {
|
||||
$page_content = '<em>No content here!</em>';
|
||||
$page_title = 'Page Not Found';
|
||||
$button = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/phriction/edit/?slug='.$slug,
|
||||
'class' => 'green button',
|
||||
),
|
||||
'Create Page');
|
||||
} else {
|
||||
$content = id(new PhrictionContent())->load($document->getContentID());
|
||||
$page_content = phutil_escape_html($content->getContent());
|
||||
$page_title = $content->getTitle();
|
||||
$button = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/phriction/edit/'.$document->getID().'/',
|
||||
'class' => 'button',
|
||||
),
|
||||
'Edit Page');
|
||||
}
|
||||
|
||||
$page =
|
||||
'<div class="phriction-header">'.
|
||||
$button.
|
||||
'<h1>'.phutil_escape_html($page_title).'</h1>'.
|
||||
'</div>'.
|
||||
$page_content;
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$slug_info,
|
||||
$page,
|
||||
array(
|
||||
'title' => 'Phriction',
|
||||
'title' => 'Phriction - '.$page_title,
|
||||
));
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/phriction/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/phriction/storage/content');
|
||||
phutil_require_module('phabricator', 'applications/phriction/storage/document');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhrictionEditController
|
||||
extends PhrictionController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$slug = $request->getStr('slug');
|
||||
$slug = PhrictionDocument::normalizeSlug($slug);
|
||||
|
||||
if ($this->id) {
|
||||
$document = id(new PhrictionDocument())->load($this->id);
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$content = id(new PhrictionContent())->load($document->getContentID());
|
||||
} else if ($slug) {
|
||||
$document = null;
|
||||
if ($slug) {
|
||||
$document = id(new PhrictionDocument())->loadOneWhere(
|
||||
'slug = %s',
|
||||
$slug);
|
||||
}
|
||||
|
||||
if ($document) {
|
||||
$content = id(new PhrictionContent())->load($document->getContentID());
|
||||
} else {
|
||||
$document = new PhrictionDocument();
|
||||
$document->setSlug($slug);
|
||||
|
||||
$content = new PhrictionContent();
|
||||
$content->setSlug($slug);
|
||||
|
||||
$default_title = null;
|
||||
if ($slug) {
|
||||
$default_title = end(explode('/', trim($slug, '/')));
|
||||
$default_title = str_replace('_', ' ', $default_title);
|
||||
$default_title = ucwords($default_title);
|
||||
}
|
||||
$default_title = nonempty($default_title, 'New Document');
|
||||
$content->setTitle($default_title);
|
||||
}
|
||||
} else {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$e_title = true;
|
||||
$errors = array();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$title = $request->getStr('title');
|
||||
|
||||
if (!strlen($title)) {
|
||||
$e_title = 'Required';
|
||||
$errors[] = 'Document title is required.';
|
||||
} else {
|
||||
$e_title = null;
|
||||
}
|
||||
|
||||
if (!count($errors)) {
|
||||
|
||||
// TODO: This should all be transactional.
|
||||
|
||||
if (!$document->getID()) {
|
||||
$document->save();
|
||||
}
|
||||
|
||||
$new_content = new PhrictionContent();
|
||||
$new_content->setSlug($document->getSlug());
|
||||
$new_content->setTitle($title);
|
||||
$new_content->setContent($request->getStr('content'));
|
||||
|
||||
$new_content->setDocumentID($document->getID());
|
||||
$new_content->setVersion($content->getVersion() + 1);
|
||||
|
||||
$new_content->setAuthorPHID($user->getPHID());
|
||||
$new_content->save();
|
||||
|
||||
$document->setContentID($new_content->getID());
|
||||
$document->save();
|
||||
|
||||
$uri = PhrictionDocument::getSlugURI($document->getSlug());
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle('Form Errors')
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
if ($document->getID()) {
|
||||
$panel_header = 'Edit Phriction Document';
|
||||
$submit_button = 'Edit Document';
|
||||
} else {
|
||||
$panel_header = 'Create New Phriction Document';
|
||||
$submit_button = 'Create Document';
|
||||
}
|
||||
|
||||
$uri = $document->getSlug();
|
||||
$uri = PhrictionDocument::getSlugURI($uri);
|
||||
$uri = PhabricatorEnv::getProductionURI($uri);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->setAction($request->getRequestURI()->getPath())
|
||||
->addHiddenInput('slug', $slug)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Title')
|
||||
->setValue($content->getTitle())
|
||||
->setError($e_title)
|
||||
->setName('title'))
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('URI')
|
||||
->setValue($uri))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel('Content')
|
||||
->setValue($content->getContent())
|
||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||
->setName('content'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($submit_button));
|
||||
|
||||
$panel = id(new AphrontPanelView())
|
||||
->setWidth(AphrontPanelView::WIDTH_WIDE)
|
||||
->setHeader($panel_header)
|
||||
->appendChild($form);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array(
|
||||
$error_view,
|
||||
$panel,
|
||||
),
|
||||
array(
|
||||
'title' => 'Edit Document',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
26
src/applications/phriction/controller/edit/__init__.php
Normal file
26
src/applications/phriction/controller/edit/__init__.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/phriction/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/phriction/storage/content');
|
||||
phutil_require_module('phabricator', 'applications/phriction/storage/document');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/static');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/form/control/text');
|
||||
phutil_require_module('phabricator', 'view/form/control/textarea');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhrictionEditController.php');
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhrictionContent extends PhrictionDAO {
|
||||
|
||||
protected $id;
|
||||
protected $documentID;
|
||||
protected $version;
|
||||
protected $authorPHID;
|
||||
|
||||
protected $title;
|
||||
protected $slug;
|
||||
protected $content;
|
||||
|
||||
}
|
12
src/applications/phriction/storage/content/__init__.php
Normal file
12
src/applications/phriction/storage/content/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/phriction/storage/base');
|
||||
|
||||
|
||||
phutil_require_source('PhrictionContent.php');
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @provides phriction-document-css
|
||||
*/
|
||||
|
||||
.phriction-header {
|
||||
background: #dddddd;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.phriction-header a.button {
|
||||
float: right;
|
||||
}
|
Loading…
Reference in a new issue