1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52: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:
epriestley 2011-07-11 12:34:53 -07:00
parent a20e46b061
commit 5704b2bc70
12 changed files with 329 additions and 4 deletions

View 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;

View file

@ -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',

View file

@ -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(

View file

@ -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',
),
);
}

View file

@ -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");

View file

@ -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,
));
}

View file

@ -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');

View file

@ -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',
));
}
}

View 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');

View file

@ -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;
}

View 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');

View file

@ -0,0 +1,12 @@
/**
* @provides phriction-document-css
*/
.phriction-header {
background: #dddddd;
padding: 1em;
}
.phriction-header a.button {
float: right;
}