Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2891290
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/resources/sql/patches/063.pasteforks.sql b/resources/sql/patches/063.pasteforks.sql
new file mode 100644
index 0000000000..d2fb7430bc
--- /dev/null
+++ b/resources/sql/patches/063.pasteforks.sql
@@ -0,0 +1,3 @@
+ALTER TABLE phabricator_pastebin.pastebin_paste
+ ADD COLUMN parentPHID VARCHAR(64) BINARY,
+ ADD KEY (parentPHID);
\ No newline at end of file
diff --git a/src/applications/paste/controller/create/PhabricatorPasteCreateController.php b/src/applications/paste/controller/create/PhabricatorPasteCreateController.php
index 5fb13d950c..27aa6ef28a 100644
--- a/src/applications/paste/controller/create/PhabricatorPasteCreateController.php
+++ b/src/applications/paste/controller/create/PhabricatorPasteCreateController.php
@@ -1,147 +1,156 @@
<?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 PhabricatorPasteCreateController extends PhabricatorPasteController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$paste = new PhabricatorPaste();
$error_view = null;
$e_text = true;
+ $fork = $request->getInt('fork');
+
$paste_text = null;
+ $paste_parent = null;
+
if ($request->isFormPost()) {
$errors = array();
$title = $request->getStr('title');
- $language = $request->getStr('language');
- if ($language == 'infer') {
- // If it's infer, store an empty string. Otherwise, store the
- // language name. We do this so we can refer to 'infer' elsewhere
- // in the code (such as default value) while retaining backwards
- // compatibility with old posts with no language stored.
- $language = '';
- }
+ $paste_language = $request->getStr('language');
$text = $request->getStr('text');
if (!strlen($text)) {
$e_text = 'Required';
$errors[] = 'The paste may not be blank.';
} else {
$e_text = null;
}
+ $parent = id(new PhabricatorPaste())->loadOneWhere(
+ 'phid = %s',
+ $request->getStr('parent'));
+
+ if ($parent) {
+ $paste->setParentPHID($parent->getPHID());
+ }
+
$paste->setTitle($title);
- $paste->setLanguage($language);
if (!$errors) {
+ if ($paste_language == 'infer') {
+ // If it's infer, store an empty string. Otherwise, store the
+ // language name. We do this so we can refer to 'infer' elsewhere
+ // in the code (such as default value) while retaining backwards
+ // compatibility with old posts with no language stored.
+ $paste_language = '';
+ }
+ $paste->setLanguage($paste_language);
+
$paste_file = PhabricatorFile::newFromFileData(
$text,
array(
'name' => $title,
'mime-type' => 'text/plain; charset=utf-8',
'authorPHID' => $user->getPHID(),
));
$paste->setFilePHID($paste_file->getPHID());
$paste->setAuthorPHID($user->getPHID());
$paste->save();
return id(new AphrontRedirectResponse())
->setURI('/P'.$paste->getID());
} else {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
$error_view->setTitle('A problem has occurred!');
}
} else {
- $copy = $request->getInt('copy');
- if ($copy) {
- $copy_paste = id(new PhabricatorPaste())->load($copy);
- if ($copy_paste) {
- $title = nonempty($copy_paste->getTitle(), 'P'.$copy_paste->getID());
- $paste->setTitle('Copy of '.$title);
- $copy_file = id(new PhabricatorFile())->loadOneWhere(
+ if ($fork) {
+ $fork_paste = id(new PhabricatorPaste())->load($fork);
+ if ($fork_paste) {
+ $paste->setTitle('Fork of '.$fork_paste->getID().': '.
+ $fork_paste->getTitle());
+ $fork_file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
- $copy_paste->getFilePHID());
- $paste_text = $copy_file->loadFileData();
+ $fork_paste->getFilePHID());
+ $paste_text = $fork_file->loadFileData();
+ $paste_language = nonempty($fork_paste->getLanguage(), 'infer');
+ $paste_parent = $fork_paste->getPHID();
}
+ } else {
+ $paste_language = PhabricatorEnv::getEnvConfig(
+ 'pygments.dropdown-default');
}
}
$form = new AphrontFormView();
- // If we're coming back from an error and the language was already defined,
- // use that. Otherwise, ask the config for the default.
- if ($paste->getLanguage()) {
- $language_default = $paste->getLanguage();
- } else {
- $language_default = PhabricatorEnv::getEnvConfig(
- 'pygments.dropdown-default');
- }
-
$available_languages = PhabricatorEnv::getEnvConfig(
'pygments.dropdown-choices');
asort($available_languages);
$language_select = id(new AphrontFormSelectControl())
->setLabel('Language')
->setName('language')
- ->setValue($language_default)
+ ->setValue($paste_language)
->setOptions($available_languages);
$form
->setUser($user)
->setAction($request->getRequestURI()->getPath())
+ ->addHiddenInput('parent', $paste_parent)
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Title')
->setValue($paste->getTitle())
->setName('title'))
->appendChild($language_select)
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Text')
->setError($e_text)
->setValue($paste_text)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
->setName('text'))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/paste/')
- ->setValue('Create Paste'));
+ ->setValue('Create Paste'));
$panel = new AphrontPanelView();
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->setHeader('Create a Paste');
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Paste Creation',
'tab' => 'create',
));
}
}
diff --git a/src/applications/paste/controller/view/PhabricatorPasteViewController.php b/src/applications/paste/controller/view/PhabricatorPasteViewController.php
index 90816f9de7..a02e0b30af 100644
--- a/src/applications/paste/controller/view/PhabricatorPasteViewController.php
+++ b/src/applications/paste/controller/view/PhabricatorPasteViewController.php
@@ -1,142 +1,172 @@
<?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 PhabricatorPasteViewController extends PhabricatorPasteController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$paste = id(new PhabricatorPaste())->load($this->id);
if (!$paste) {
return new Aphront404Response();
}
$file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$paste->getFilePHID());
if (!$file) {
return new Aphront400Response();
}
$corpus = $this->buildCorpus($paste, $file);
-
$panel = new AphrontPanelView();
if (strlen($paste->getTitle())) {
$panel->setHeader(
'Viewing Paste '.$paste->getID().' - '.
phutil_escape_html($paste->getTitle()));
} else {
$panel->setHeader('Viewing Paste '.$paste->getID());
}
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$panel->addButton(
phutil_render_tag(
'a',
array(
- 'href' => '/paste/?copy='.$paste->getID(),
+ 'href' => '/paste/?fork='.$paste->getID(),
'class' => 'green button',
),
- 'Copy This'));
+ 'Fork This'));
$raw_uri = PhabricatorFileURI::getViewURIForPHID($paste->getFilePHID());
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => $raw_uri,
'class' => 'button',
),
'View Raw Text'));
$panel->appendChild($corpus);
+ $forks_of_this_paste = id(new PhabricatorPaste())->loadAllWhere(
+ 'parentPHID = %s',
+ $paste->getPHID());
+
+ if ($forks_of_this_paste) {
+ $forks = array();
+ foreach ($forks_of_this_paste as $fork) {
+ $forks[] = array(
+ $fork->getID(),
+ phutil_render_tag(
+ 'a',
+ array(
+ 'href' => '/P'.$fork->getID(),
+ ),
+ phutil_escape_html($fork->getTitle())
+ )
+ );
+ }
+
+ $forks_table = new AphrontTableView($forks);
+ $forks_table->setHeaders(
+ array(
+ 'Paste ID',
+ 'Title',
+ )
+ );
+
+ $panel->setHeader("Forks of this Paste");
+ $panel->appendChild($forks_table);
+ }
+
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Paste: '.nonempty($paste->getTitle(), 'P'.$paste->getID()),
'tab' => 'view',
));
}
private function buildCorpus($paste, $file) {
// Blantently copied from DiffusionBrowseFileController
require_celerity_resource('diffusion-source-css');
require_celerity_resource('syntax-highlighting-css');
$language = $paste->getLanguage();
$source = $file->loadFileData();
if (empty($language)) {
$source = PhabricatorSyntaxHighlighter::highlightWithFilename(
$paste->getTitle(),
$source);
} else {
$source = PhabricatorSyntaxHighlighter::highlightWithLanguage(
$language,
$source);
}
$text_list = explode("\n", $source);
$rows = $this->buildDisplayRows($text_list);
$corpus_table = phutil_render_tag(
'table',
array(
'class' => 'diffusion-source remarkup-code PhabricatorMonospaced',
),
implode("\n", $rows));
$corpus = phutil_render_tag(
'div',
array(
'style' => 'padding: 0pt 2em;',
),
$corpus_table);
return $corpus;
}
private function buildDisplayRows($text_list) {
$rows = array();
$n = 1;
foreach ($text_list as $k => $line) {
// Pardon the ugly for the time being.
// And eventually this will highlight a line that you click
// like diffusion does. Or maybe allow for line comments
// like differential. Either way it will be better than it is now.
$rows[] = '<tr><th>'.$n.'</th>'.
'<td style="white-space: pre-wrap;">'.$line.'</td></tr>';
++$n;
}
return $rows;
}
}
diff --git a/src/applications/paste/controller/view/__init__.php b/src/applications/paste/controller/view/__init__.php
index 527fc99e51..a148c94e13 100644
--- a/src/applications/paste/controller/view/__init__.php
+++ b/src/applications/paste/controller/view/__init__.php
@@ -1,23 +1,24 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/400');
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phabricator', 'applications/markup/syntax');
phutil_require_module('phabricator', 'applications/paste/controller/base');
phutil_require_module('phabricator', 'applications/paste/storage/paste');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
+phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorPasteViewController.php');
diff --git a/src/applications/paste/storage/paste/PhabricatorPaste.php b/src/applications/paste/storage/paste/PhabricatorPaste.php
index 4edeea81ea..c7a75f0669 100644
--- a/src/applications/paste/storage/paste/PhabricatorPaste.php
+++ b/src/applications/paste/storage/paste/PhabricatorPaste.php
@@ -1,38 +1,39 @@
<?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 PhabricatorPaste extends PhabricatorPasteDAO {
protected $phid;
protected $title;
protected $authorPHID;
protected $filePHID;
protected $language;
+ protected $parentPHID;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_PSTE);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jan 19, 14:58 (3 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1125737
Default Alt Text
(14 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment