mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Introduce PHID generation.
This commit is contained in:
parent
eecc003a62
commit
2c7e71cac5
29 changed files with 711 additions and 47 deletions
|
@ -60,6 +60,14 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
|
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
|
||||||
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
|
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
|
||||||
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
|
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
|
||||||
|
'PhabricatorPHID' => 'applications/phid/storage/phid',
|
||||||
|
'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate',
|
||||||
|
'PhabricatorPHIDController' => 'applications/phid/controller/base',
|
||||||
|
'PhabricatorPHIDDAO' => 'applications/phid/storage/base',
|
||||||
|
'PhabricatorPHIDListController' => 'applications/phid/controller/list',
|
||||||
|
'PhabricatorPHIDType' => 'applications/phid/storage/type',
|
||||||
|
'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit',
|
||||||
|
'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist',
|
||||||
'PhabricatorStandardPageView' => 'view/page/standard',
|
'PhabricatorStandardPageView' => 'view/page/standard',
|
||||||
),
|
),
|
||||||
'function' =>
|
'function' =>
|
||||||
|
@ -114,6 +122,14 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
|
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
|
||||||
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
|
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
|
||||||
'PhabricatorLiskDAO' => 'LiskDAO',
|
'PhabricatorLiskDAO' => 'LiskDAO',
|
||||||
|
'PhabricatorPHID' => 'PhabricatorPHIDDAO',
|
||||||
|
'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController',
|
||||||
|
'PhabricatorPHIDController' => 'PhabricatorController',
|
||||||
|
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
|
||||||
|
'PhabricatorPHIDType' => 'PhabricatorPHIDDAO',
|
||||||
|
'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController',
|
||||||
|
'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController',
|
||||||
'PhabricatorStandardPageView' => 'AphrontPageView',
|
'PhabricatorStandardPageView' => 'AphrontPageView',
|
||||||
),
|
),
|
||||||
'requires_interface' =>
|
'requires_interface' =>
|
||||||
|
|
|
@ -35,18 +35,27 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'delete/(?<id>\d+)/$' => 'RepositoryDeleteController',
|
'delete/(?<id>\d+)/$' => 'RepositoryDeleteController',
|
||||||
),
|
),
|
||||||
'/' => array(
|
'/' => array(
|
||||||
'$' => 'AphrontDirectoryMainController',
|
'$' => 'PhabricatorDirectoryMainController',
|
||||||
),
|
),
|
||||||
'/directory/' => array(
|
'/directory/' => array(
|
||||||
'item/$' => 'AphrontDirectoryItemListController',
|
'item/$'
|
||||||
'item/edit/(?:(?<id>\d+)/)?$' => 'AphrontDirectoryItemEditController',
|
=> 'PhabricatorDirectoryItemListController',
|
||||||
'item/delete/(?<id>\d+)/' => 'AphrontDirectoryItemDeleteController',
|
'item/edit/(?:(?<id>\d+)/)?$'
|
||||||
|
=> 'PhabricatorDirectoryItemEditController',
|
||||||
|
'item/delete/(?<id>\d+)/'
|
||||||
|
=> 'PhabricatorDirectoryItemDeleteController',
|
||||||
'category/$'
|
'category/$'
|
||||||
=> 'AphrontDirectoryCategoryListController',
|
=> 'PhabricatorDirectoryCategoryListController',
|
||||||
'category/edit/(?:(?<id>\d+)/)?$'
|
'category/edit/(?:(?<id>\d+)/)?$'
|
||||||
=> 'AphrontDirectoryCategoryEditController',
|
=> 'PhabricatorDirectoryCategoryEditController',
|
||||||
'category/delete/(?<id>\d+)/'
|
'category/delete/(?<id>\d+)/'
|
||||||
=> 'AphrontDirectoryCategoryDeleteController',
|
=> 'PhabricatorDirectoryCategoryDeleteController',
|
||||||
|
),
|
||||||
|
'/phid/' => array(
|
||||||
|
'$' => 'PhabricatorPHIDListController',
|
||||||
|
'type/$' => 'PhabricatorPHIDTypeListController',
|
||||||
|
'type/edit/(?:(?<id>\d+)/)?$' => 'PhabricatorPHIDTypeEditController',
|
||||||
|
'new/$' => 'PhabricatorPHIDAllocateController',
|
||||||
),
|
),
|
||||||
'.*' => 'AphrontDefaultApplicationController',
|
'.*' => 'AphrontDefaultApplicationController',
|
||||||
);
|
);
|
||||||
|
|
|
@ -32,4 +32,10 @@ class AphrontWebpageResponse extends AphrontResponse {
|
||||||
return $this->content;
|
return $this->content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHeaders() {
|
||||||
|
return array(
|
||||||
|
array('Content-Type', 'text/html; charset=UTF-8'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
14
src/applications/base/controller/base/__init__.php
Normal file
14
src/applications/base/controller/base/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/controller');
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
|
phutil_require_module('phabricator', 'view/page/standard');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorController.php');
|
|
@ -42,7 +42,12 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
||||||
if (!strncmp($class, $app, strlen($app))) {
|
if (!strncmp($class, $app, strlen($app))) {
|
||||||
$class = substr($class, strlen($app));
|
$class = substr($class, strlen($app));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($class)) {
|
||||||
return $app.'_'.$class;
|
return $app.'_'.$class;
|
||||||
|
} else {
|
||||||
|
return $app;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public function getApplicationName();
|
abstract public function getApplicationName();
|
||||||
|
|
|
@ -23,7 +23,7 @@ class PhabricatorDirectoryItem extends PhabricatorDirectoryDAO {
|
||||||
protected $href;
|
protected $href;
|
||||||
protected $categoryID;
|
protected $categoryID;
|
||||||
protected $sequence;
|
protected $sequence;
|
||||||
protected $imageGUID;
|
protected $imagePHID;
|
||||||
|
|
||||||
public function getSortKey() {
|
public function getSortKey() {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?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 PhabricatorPHIDAllocateController
|
||||||
|
extends PhabricatorPHIDController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$type = $request->getStr('type');
|
||||||
|
$phid = PhabricatorPHID::generateNewPHID($type);
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/phid/?phid='.phutil_escape_uri($phid));
|
||||||
|
}
|
||||||
|
|
||||||
|
$types = id(new PhabricatorPHIDType())->loadAll();
|
||||||
|
|
||||||
|
$options = array();
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$options[$type->getType()] = $type->getType().': '.$type->getName();
|
||||||
|
}
|
||||||
|
asort($options);
|
||||||
|
|
||||||
|
$form = new AphrontFormView();
|
||||||
|
$form->setAction('/phid/new/');
|
||||||
|
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSelectControl())
|
||||||
|
->setLabel('PHID Type')
|
||||||
|
->setName('type')
|
||||||
|
->setOptions($options))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Allocate')
|
||||||
|
->addCancelButton('/phid/'));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->setHeader('Allocate New PHID');
|
||||||
|
|
||||||
|
$panel->appendChild($form);
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
array($panel),
|
||||||
|
array(
|
||||||
|
'title' => 'Allocate New PHID',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
src/applications/phid/controller/allocate/__init__.php
Normal file
20
src/applications/phid/controller/allocate/__init__.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/phid');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/type');
|
||||||
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHIDAllocateController.php');
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorPHIDController extends PhabricatorController {
|
||||||
|
|
||||||
|
public function buildStandardPageResponse($view, array $data) {
|
||||||
|
$page = new PhabricatorStandardPageView();
|
||||||
|
|
||||||
|
$page->setApplicationName('PHID');
|
||||||
|
$page->setBaseURI('/phid/');
|
||||||
|
$page->setTitle(idx($data, 'title'));
|
||||||
|
$page->setTabs(
|
||||||
|
array(
|
||||||
|
'phids' => array(
|
||||||
|
'href' => '/phid/',
|
||||||
|
'name' => 'PHIDs',
|
||||||
|
),
|
||||||
|
'types' => array(
|
||||||
|
'href' => '/phid/type/',
|
||||||
|
'name' => 'PHID Types',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
idx($data, 'tab'));
|
||||||
|
$page->setGlyph('#');
|
||||||
|
$page->appendChild($view);
|
||||||
|
|
||||||
|
$response = new AphrontWebpageResponse();
|
||||||
|
return $response->setContent($page->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/applications/phid/controller/base/__init__.php
Normal file
16
src/applications/phid/controller/base/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
|
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'view/page/standard');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHIDController.php');
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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 PhabricatorPHIDListController
|
||||||
|
extends PhabricatorPHIDController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$items = id(new PhabricatorPHID())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC limit 100');
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$rows[] = array(
|
||||||
|
phutil_escape_html($item->getPHID()),
|
||||||
|
phutil_escape_html($item->getPHIDType()),
|
||||||
|
phutil_escape_html($item->getOwnerPHID()),
|
||||||
|
phutil_escape_html($item->getParentPHID()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = new AphrontTableView($rows);
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'PHID',
|
||||||
|
'Type',
|
||||||
|
'Owner PHID',
|
||||||
|
'Parent PHID',
|
||||||
|
));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->appendChild($table);
|
||||||
|
$panel->setHeader('PHIDs');
|
||||||
|
$panel->setCreateButton('Allocate New PHID', '/phid/new/');
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse($panel, array(
|
||||||
|
'title' => 'PHIDs',
|
||||||
|
'tab' => 'phids',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/applications/phid/controller/list/__init__.php
Normal file
18
src/applications/phid/controller/list/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/phid');
|
||||||
|
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('PhabricatorPHIDListController.php');
|
|
@ -0,0 +1,132 @@
|
||||||
|
<?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 PhabricatorPHIDTypeEditController
|
||||||
|
extends PhabricatorPHIDController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = idx($data, 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
|
||||||
|
if ($this->id) {
|
||||||
|
$type = id(new PhabricatorPHIDType())->load($this->id);
|
||||||
|
if (!$type) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$type = new PhabricatorPHIDType();
|
||||||
|
}
|
||||||
|
|
||||||
|
$e_type = true;
|
||||||
|
$e_name = true;
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$type->setName($request->getStr('name'));
|
||||||
|
if (!$type->getID()) {
|
||||||
|
$type->setType($request->getStr('type'));
|
||||||
|
}
|
||||||
|
$type->setDescription($request->getStr('description'));
|
||||||
|
|
||||||
|
if (!strlen($type->getType())) {
|
||||||
|
$errors[] = 'Type code is required.';
|
||||||
|
$e_type = 'Required';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strlen($type->getName())) {
|
||||||
|
$errors[] = 'Type name is required.';
|
||||||
|
$e_name = 'Required';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$type->save();
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI('/phid/type/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$error_view = null;
|
||||||
|
if ($errors) {
|
||||||
|
$error_view = id(new AphrontErrorView())
|
||||||
|
->setTitle('Form Errors')
|
||||||
|
->setErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = new AphrontFormView();
|
||||||
|
if ($type->getID()) {
|
||||||
|
$form->setAction('/phid/type/edit/'.$type->getID().'/');
|
||||||
|
} else {
|
||||||
|
$form->setAction('/phid/type/edit/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type->getID()) {
|
||||||
|
$type_immutable = true;
|
||||||
|
} else {
|
||||||
|
$type_immutable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Type')
|
||||||
|
->setName('type')
|
||||||
|
->setValue($type->getType())
|
||||||
|
->setError($e_type)
|
||||||
|
->setCaption(
|
||||||
|
'Four character type identifier. This can not be changed once '.
|
||||||
|
'it is created.')
|
||||||
|
->setDisabled($type_immutable))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Name')
|
||||||
|
->setName('name')
|
||||||
|
->setValue($type->getName())
|
||||||
|
->setError($e_name))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextAreaControl())
|
||||||
|
->setLabel('Description')
|
||||||
|
->setName('description')
|
||||||
|
->setValue($type->getDescription()))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Save')
|
||||||
|
->addCancelButton('/phid/type/'));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
if ($type->getID()) {
|
||||||
|
$panel->setHeader('Edit PHID Type');
|
||||||
|
} else {
|
||||||
|
$panel->setHeader('Create New PHID Type');
|
||||||
|
}
|
||||||
|
|
||||||
|
$panel->appendChild($form);
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
array($error_view, $panel),
|
||||||
|
array(
|
||||||
|
'title' => 'Edit PHID Type',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/applications/phid/controller/typeedit/__init__.php
Normal file
21
src/applications/phid/controller/typeedit/__init__.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?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/phid/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/type');
|
||||||
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
|
phutil_require_module('phabricator', 'view/form/error');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHIDTypeEditController.php');
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?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 PhabricatorPHIDTypeListController
|
||||||
|
extends PhabricatorPHIDController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$items = id(new PhabricatorPHIDType())->loadAll();
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$rows[] = array(
|
||||||
|
$item->getID(),
|
||||||
|
phutil_escape_html($item->getType()),
|
||||||
|
phutil_escape_html($item->getName()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = new AphrontTableView($rows);
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'ID',
|
||||||
|
'Type Code',
|
||||||
|
'Name',
|
||||||
|
));
|
||||||
|
$table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'wide',
|
||||||
|
));
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->appendChild($table);
|
||||||
|
$panel->setHeader('PHID Types');
|
||||||
|
$panel->setCreateButton('New Type', '/phid/type/edit/');
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse($panel, array(
|
||||||
|
'title' => 'PHID Types',
|
||||||
|
'tab' => 'types',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/applications/phid/controller/typelist/__init__.php
Normal file
18
src/applications/phid/controller/typelist/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/type');
|
||||||
|
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('PhabricatorPHIDTypeListController.php');
|
25
src/applications/phid/storage/base/PhabricatorPHIDDAO.php
Normal file
25
src/applications/phid/storage/base/PhabricatorPHIDDAO.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?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 PhabricatorPHIDDAO extends PhabricatorLiskDAO {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'phid';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/applications/phid/storage/base/__init__.php
Normal file
12
src/applications/phid/storage/base/__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/base/storage/lisk');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHIDDAO.php');
|
56
src/applications/phid/storage/phid/PhabricatorPHID.php
Normal file
56
src/applications/phid/storage/phid/PhabricatorPHID.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?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 PhabricatorPHID extends PhabricatorPHIDDAO {
|
||||||
|
|
||||||
|
protected $phid;
|
||||||
|
protected $phidType;
|
||||||
|
protected $ownerPHID;
|
||||||
|
protected $parentPHID;
|
||||||
|
|
||||||
|
public static function generateNewPHID($type, array $config = array()) {
|
||||||
|
$owner = idx($config, 'owner');
|
||||||
|
$parent = idx($config, 'parent');
|
||||||
|
|
||||||
|
if (!$type) {
|
||||||
|
throw new Exception("Can not generate PHID with no type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$urandom = @fopen('/dev/urandom', 'r');
|
||||||
|
if (!$urandom) {
|
||||||
|
throw new Exception("Failed to open /dev/urandom!");
|
||||||
|
}
|
||||||
|
$entropy = fread($urandom, 16);
|
||||||
|
if (strlen($entropy) != 16) {
|
||||||
|
throw new Exception("Failed to read from /dev/urandom!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$uniq = sha1($entropy);
|
||||||
|
$phid = 'PHID-'.$type.'-X-'.$uniq;
|
||||||
|
|
||||||
|
$phid_rec = new PhabricatorPHID();
|
||||||
|
$phid_rec->setPHIDType($type);
|
||||||
|
$phid_rec->setOwnerPHID($owner);
|
||||||
|
$phid_rec->setParentPHID($parent);
|
||||||
|
$phid_rec->setPHID($phid);
|
||||||
|
$phid_rec->save();
|
||||||
|
|
||||||
|
return $phid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/applications/phid/storage/phid/__init__.php
Normal file
14
src/applications/phid/storage/phid/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/phid/storage/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHID.php');
|
25
src/applications/phid/storage/type/PhabricatorPHIDType.php
Normal file
25
src/applications/phid/storage/type/PhabricatorPHIDType.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?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 PhabricatorPHIDType extends PhabricatorPHIDDAO {
|
||||||
|
|
||||||
|
protected $type;
|
||||||
|
protected $name;
|
||||||
|
protected $description;
|
||||||
|
|
||||||
|
}
|
12
src/applications/phid/storage/type/__init__.php
Normal file
12
src/applications/phid/storage/type/__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/phid/storage/base');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorPHIDType.php');
|
|
@ -148,7 +148,7 @@ abstract class LiskDAO {
|
||||||
const CONFIG_OPTIMISTIC_LOCKS = 'enable-locks';
|
const CONFIG_OPTIMISTIC_LOCKS = 'enable-locks';
|
||||||
const CONFIG_IDS = 'id-mechanism';
|
const CONFIG_IDS = 'id-mechanism';
|
||||||
const CONFIG_TIMESTAMPS = 'timestamps';
|
const CONFIG_TIMESTAMPS = 'timestamps';
|
||||||
const CONFIG_AUX_GUID = 'auxiliary-guid';
|
const CONFIG_AUX_PHID = 'auxiliary-phid';
|
||||||
const CONFIG_SERIALIZATION = 'col-serialization';
|
const CONFIG_SERIALIZATION = 'col-serialization';
|
||||||
|
|
||||||
const SERIALIZATION_NONE = 'id';
|
const SERIALIZATION_NONE = 'id';
|
||||||
|
@ -156,7 +156,7 @@ abstract class LiskDAO {
|
||||||
const SERIALIZATION_PHP = 'php';
|
const SERIALIZATION_PHP = 'php';
|
||||||
|
|
||||||
const IDS_AUTOINCREMENT = 'ids-auto';
|
const IDS_AUTOINCREMENT = 'ids-auto';
|
||||||
const IDS_GUID = 'ids-guid';
|
const IDS_PHID = 'ids-phid';
|
||||||
const IDS_MANUAL = 'ids-manual';
|
const IDS_MANUAL = 'ids-manual';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,8 +208,8 @@ abstract class LiskDAO {
|
||||||
* CONFIG_IDS
|
* CONFIG_IDS
|
||||||
* Lisk objects need to have a unique identifying ID. The three mechanisms
|
* Lisk objects need to have a unique identifying ID. The three mechanisms
|
||||||
* available for generating this ID are IDS_AUTOINCREMENT (default, assumes
|
* available for generating this ID are IDS_AUTOINCREMENT (default, assumes
|
||||||
* the ID column is an autoincrement primary key), IDS_GUID (to generate a
|
* the ID column is an autoincrement primary key), IDS_PHID (to generate a
|
||||||
* unique GUID for each object) or IDS_MANUAL (you are taking full
|
* unique PHID for each object) or IDS_MANUAL (you are taking full
|
||||||
* responsibility for ID management).
|
* responsibility for ID management).
|
||||||
*
|
*
|
||||||
* CONFIG_TIMESTAMPS
|
* CONFIG_TIMESTAMPS
|
||||||
|
@ -218,12 +218,12 @@ abstract class LiskDAO {
|
||||||
* an object. If you don't want to do this, you may disable this option.
|
* an object. If you don't want to do this, you may disable this option.
|
||||||
* By default, this option is ON.
|
* By default, this option is ON.
|
||||||
*
|
*
|
||||||
* CONFIG_AUX_GUID
|
* CONFIG_AUX_PHID
|
||||||
* This option can be enabled by being set to some truthy value. The meaning
|
* This option can be enabled by being set to some truthy value. The meaning
|
||||||
* of this value is defined by your guid generation mechanism. If this option
|
* of this value is defined by your PHID generation mechanism. If this option
|
||||||
* is enabled, a `guid' property will be populated with a unique GUID when an
|
* is enabled, a `phid' property will be populated with a unique PHID when an
|
||||||
* object is created (or if it is saved and does not currently have one). You
|
* object is created (or if it is saved and does not currently have one). You
|
||||||
* need to override generateGUID() and hook it into your GUID generation
|
* need to override generatePHID() and hook it into your PHID generation
|
||||||
* mechanism for this to work. By default, this option is OFF.
|
* mechanism for this to work. By default, this option is OFF.
|
||||||
*
|
*
|
||||||
* CONFIG_SERIALIZATION
|
* CONFIG_SERIALIZATION
|
||||||
|
@ -554,9 +554,9 @@ abstract class LiskDAO {
|
||||||
$properties['datemodified'] = 'dateModified';
|
$properties['datemodified'] = 'dateModified';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->isGUIDPrimaryID() &&
|
if (!$this->isPHIDPrimaryID() &&
|
||||||
$this->getConfigOption(self::CONFIG_AUX_GUID)) {
|
$this->getConfigOption(self::CONFIG_AUX_PHID)) {
|
||||||
$properties['guid'] = 'guid';
|
$properties['phid'] = 'phid';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $properties;
|
return $properties;
|
||||||
|
@ -792,11 +792,11 @@ abstract class LiskDAO {
|
||||||
case self::IDS_AUTOINCREMENT:
|
case self::IDS_AUTOINCREMENT:
|
||||||
unset($data[$this->getIDKeyForUse()]);
|
unset($data[$this->getIDKeyForUse()]);
|
||||||
break;
|
break;
|
||||||
case self::IDS_GUID:
|
case self::IDS_PHID:
|
||||||
if (empty($data[$this->getIDKeyForUse()])) {
|
if (empty($data[$this->getIDKeyForUse()])) {
|
||||||
$guid = $this->generateGUID();
|
$phid = $this->generatePHID();
|
||||||
$this->setID($guid);
|
$this->setID($phid);
|
||||||
$data[$this->getIDKeyForUse()] = $guid;
|
$data[$this->getIDKeyForUse()] = $phid;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case self::IDS_MANUAL:
|
case self::IDS_MANUAL:
|
||||||
|
@ -888,11 +888,11 @@ abstract class LiskDAO {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: Whether this class is configured to use GUIDs as the primary ID.
|
* Helper: Whether this class is configured to use PHIDs as the primary ID.
|
||||||
* @task internal
|
* @task internal
|
||||||
*/
|
*/
|
||||||
private function isGUIDPrimaryID() {
|
private function isPHIDPrimaryID() {
|
||||||
return ($this->getConfigOption(self::CONFIG_IDS) === self::IDS_GUID);
|
return ($this->getConfigOption(self::CONFIG_IDS) === self::IDS_PHID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -906,8 +906,8 @@ abstract class LiskDAO {
|
||||||
*/
|
*/
|
||||||
public function getIDKey() {
|
public function getIDKey() {
|
||||||
return
|
return
|
||||||
$this->isGUIDPrimaryID() ?
|
$this->isPHIDPrimaryID() ?
|
||||||
'guid' :
|
'phid' :
|
||||||
'id';
|
'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,16 +924,16 @@ abstract class LiskDAO {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new GUID, used by CONFIG_AUX_GUID and IDS_GUID.
|
* Generate a new PHID, used by CONFIG_AUX_PHID and IDS_PHID.
|
||||||
*
|
*
|
||||||
* @return guid Unique, newly allocated GUID.
|
* @return phid Unique, newly allocated PHID.
|
||||||
*
|
*
|
||||||
* @task hook
|
* @task hook
|
||||||
*/
|
*/
|
||||||
protected function generateGUID() {
|
protected function generatePHID() {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
"To use CONFIG_AUX_GUID or IDS_GUID, you need to overload ".
|
"To use CONFIG_AUX_PHID or IDS_PHID, you need to overload ".
|
||||||
"generateGUID() to perform GUID generation.");
|
"generatePHID() to perform PHID generation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -987,14 +987,14 @@ abstract class LiskDAO {
|
||||||
$this->setDateModified(time());
|
$this->setDateModified(time());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($this->isGUIDPrimaryID() && !$this->getID())) {
|
if (($this->isPHIDPrimaryID() && !$this->getID())) {
|
||||||
// If GUIDs are the primary ID, the subclass could have overridden the
|
// If PHIDs are the primary ID, the subclass could have overridden the
|
||||||
// name of the ID column.
|
// name of the ID column.
|
||||||
$this->setID($this->generateGUID());
|
$this->setID($this->generatePHID());
|
||||||
} else if ($this->getConfigOption(self::CONFIG_AUX_GUID) &&
|
} else if ($this->getConfigOption(self::CONFIG_AUX_PHID) &&
|
||||||
!$this->getGUID()) {
|
!$this->getPHID()) {
|
||||||
// The subclass could still want GUIDs.
|
// The subclass could still want PHIDs.
|
||||||
$this->setGUID($this->generateGUID());
|
$this->setPHID($this->generatePHID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ abstract class AphrontFormControl extends AphrontView {
|
||||||
private $error;
|
private $error;
|
||||||
private $name;
|
private $name;
|
||||||
private $value;
|
private $value;
|
||||||
|
private $disabled;
|
||||||
|
|
||||||
public function setLabel($label) {
|
public function setLabel($label) {
|
||||||
$this->label = $label;
|
$this->label = $label;
|
||||||
|
@ -69,6 +70,15 @@ abstract class AphrontFormControl extends AphrontView {
|
||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setDisabled($disabled) {
|
||||||
|
$this->disabled = $disabled;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisabled() {
|
||||||
|
return $this->disabled;
|
||||||
|
}
|
||||||
|
|
||||||
abstract protected function renderInput();
|
abstract protected function renderInput();
|
||||||
abstract protected function getCustomControlClass();
|
abstract protected function getCustomControlClass();
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ class AphrontFormSelectControl extends AphrontFormControl {
|
||||||
'select',
|
'select',
|
||||||
array(
|
array(
|
||||||
'name' => $this->getName(),
|
'name' => $this->getName(),
|
||||||
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
),
|
),
|
||||||
implode("\n", $options));
|
implode("\n", $options));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ class AphrontFormSubmitControl extends AphrontFormControl {
|
||||||
'button',
|
'button',
|
||||||
array(
|
array(
|
||||||
'name' => '__submit__',
|
'name' => '__submit__',
|
||||||
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
),
|
),
|
||||||
phutil_escape_html($this->getValue())).
|
phutil_escape_html($this->getValue())).
|
||||||
$this->cancelButton;
|
$this->cancelButton;
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AphrontFormTextControl extends AphrontFormControl {
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'name' => $this->getName(),
|
'name' => $this->getName(),
|
||||||
'value' => $this->getValue(),
|
'value' => $this->getValue(),
|
||||||
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ class AphrontFormTextAreaControl extends AphrontFormControl {
|
||||||
'textarea',
|
'textarea',
|
||||||
array(
|
array(
|
||||||
'name' => $this->getName(),
|
'name' => $this->getName(),
|
||||||
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
),
|
),
|
||||||
phutil_escape_html($this->getValue()));
|
phutil_escape_html($this->getValue()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,6 +476,8 @@ a.small:visited {
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-right: 25%;
|
margin-right: 25%;
|
||||||
margin-left: 15%;
|
margin-left: 15%;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.aphront-error-view {
|
.aphront-error-view {
|
||||||
|
|
Loading…
Reference in a new issue