mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 00:02:41 +01:00
Import some code, some of which may be relevant to the project.
This commit is contained in:
parent
081689d61a
commit
76258ce0e1
116 changed files with 6203 additions and 0 deletions
10
.arcconfig
Normal file
10
.arcconfig
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"project_id" : "aphront",
|
||||
"conduit_uri" : "http://tools.epriestley-conduit.dev1557.facebook.com/api/",
|
||||
"lint_engine" : "PhutilLintEngine",
|
||||
"unit_engine" : "PhutilUnitTestEngine",
|
||||
"copyright_holder" : "Facebook, Inc.",
|
||||
"phutil_libraries" : {
|
||||
"aphront" : "src/"
|
||||
}
|
||||
}
|
7
.divinerconfig
Normal file
7
.divinerconfig
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name" : "differential",
|
||||
"src_base" : "https://github.com/facebook/differential/blob/master",
|
||||
"groups" : {
|
||||
}
|
||||
}
|
||||
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
.DS_Store
|
||||
._*
|
||||
/docs/
|
19
src/__phutil_library_init__.php
Normal file
19
src/__phutil_library_init__.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
phutil_register_library('aphront', __FILE__);
|
120
src/__phutil_library_map__.php
Normal file
120
src/__phutil_library_map__.php
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is automatically generated. Use 'phutil_mapper.php' to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
phutil_register_library_map(array(
|
||||
'class' =>
|
||||
array(
|
||||
'Aphront404Response' => 'aphront/response/404',
|
||||
'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration',
|
||||
'AphrontController' => 'aphront/controller',
|
||||
'AphrontDatabaseConnection' => 'storage/connection/base',
|
||||
'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration',
|
||||
'AphrontDefaultApplicationController' => 'aphront/default/controller',
|
||||
'AphrontDialogResponse' => 'aphront/response/dialog',
|
||||
'AphrontDialogView' => 'view/dialog',
|
||||
'AphrontDirectoryCategory' => 'applications/directory/storage/category',
|
||||
'AphrontDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete',
|
||||
'AphrontDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit',
|
||||
'AphrontDirectoryCategoryListController' => 'applications/directory/controller/categorylist',
|
||||
'AphrontDirectoryController' => 'applications/directory/controller/base',
|
||||
'AphrontDirectoryDAO' => 'applications/directory/storage/base',
|
||||
'AphrontDirectoryItem' => 'applications/directory/storage/item',
|
||||
'AphrontDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete',
|
||||
'AphrontDirectoryItemEditController' => 'applications/directory/controller/itemedit',
|
||||
'AphrontDirectoryItemListController' => 'applications/directory/controller/itemlist',
|
||||
'AphrontDirectoryMainController' => 'applications/directory/controller/main',
|
||||
'AphrontErrorView' => 'view/form/error',
|
||||
'AphrontFormControl' => 'view/form/control/base',
|
||||
'AphrontFormSelectControl' => 'view/form/control/select',
|
||||
'AphrontFormSubmitControl' => 'view/form/control/submit',
|
||||
'AphrontFormTextAreaControl' => 'view/form/control/textarea',
|
||||
'AphrontFormTextControl' => 'view/form/control/text',
|
||||
'AphrontFormView' => 'view/form/base',
|
||||
'AphrontLiskDAO' => 'aphront/storage/lisk',
|
||||
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
|
||||
'AphrontNullView' => 'view/null',
|
||||
'AphrontPageView' => 'view/page/base',
|
||||
'AphrontPanelView' => 'view/layout/panel',
|
||||
'AphrontQueryConnectionException' => 'storage/exception/connection',
|
||||
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
|
||||
'AphrontQueryCountException' => 'storage/exception/count',
|
||||
'AphrontQueryException' => 'storage/exception/base',
|
||||
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
|
||||
'AphrontQueryParameterException' => 'storage/exception/parameter',
|
||||
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
|
||||
'AphrontRedirectResponse' => 'aphront/response/redirect',
|
||||
'AphrontRequest' => 'aphront/request',
|
||||
'AphrontResponse' => 'aphront/response/base',
|
||||
'AphrontStandardPageView' => 'view/page/standard',
|
||||
'AphrontTableView' => 'view/control/table',
|
||||
'AphrontURIMapper' => 'aphront/mapper',
|
||||
'AphrontView' => 'view/base',
|
||||
'AphrontWebpageResponse' => 'aphront/response/webpage',
|
||||
'DifferentialAction' => 'applications/review/constants/action',
|
||||
'DifferentialChangeType' => 'applications/review/constants/changetype',
|
||||
'DifferentialLintStatus' => 'applications/review/constants/lintstatus',
|
||||
'DifferentialRevisionStatus' => 'applications/review/constants/revisionstatus',
|
||||
'DifferentialUnitStatus' => 'applications/review/constants/unitstatus',
|
||||
'LiskDAO' => 'storage/lisk/dao',
|
||||
),
|
||||
'function' =>
|
||||
array(
|
||||
'_qsprintf_check_scalar_type' => 'storage/qsprintf',
|
||||
'_qsprintf_check_type' => 'storage/qsprintf',
|
||||
'qsprintf' => 'storage/qsprintf',
|
||||
'queryfx' => 'storage/queryfx',
|
||||
'queryfx_all' => 'storage/queryfx',
|
||||
'queryfx_one' => 'storage/queryfx',
|
||||
'vqsprintf' => 'storage/qsprintf',
|
||||
'vqueryfx' => 'storage/queryfx',
|
||||
'xsprintf_query' => 'storage/qsprintf',
|
||||
),
|
||||
'requires_class' =>
|
||||
array(
|
||||
'Aphront404Response' => 'AphrontResponse',
|
||||
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
|
||||
'AphrontDefaultApplicationController' => 'AphrontController',
|
||||
'AphrontDialogResponse' => 'AphrontResponse',
|
||||
'AphrontDialogView' => 'AphrontView',
|
||||
'AphrontDirectoryCategory' => 'AphrontDirectoryDAO',
|
||||
'AphrontDirectoryCategoryDeleteController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryCategoryEditController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryCategoryListController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryController' => 'AphrontController',
|
||||
'AphrontDirectoryDAO' => 'AphrontLiskDAO',
|
||||
'AphrontDirectoryItem' => 'AphrontDirectoryDAO',
|
||||
'AphrontDirectoryItemDeleteController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryItemEditController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryItemListController' => 'AphrontDirectoryController',
|
||||
'AphrontDirectoryMainController' => 'AphrontDirectoryController',
|
||||
'AphrontErrorView' => 'AphrontView',
|
||||
'AphrontFormControl' => 'AphrontView',
|
||||
'AphrontFormSelectControl' => 'AphrontFormControl',
|
||||
'AphrontFormSubmitControl' => 'AphrontFormControl',
|
||||
'AphrontFormTextAreaControl' => 'AphrontFormControl',
|
||||
'AphrontFormTextControl' => 'AphrontFormControl',
|
||||
'AphrontFormView' => 'AphrontView',
|
||||
'AphrontLiskDAO' => 'LiskDAO',
|
||||
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
|
||||
'AphrontNullView' => 'AphrontView',
|
||||
'AphrontPageView' => 'AphrontView',
|
||||
'AphrontPanelView' => 'AphrontView',
|
||||
'AphrontQueryConnectionException' => 'AphrontQueryException',
|
||||
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
|
||||
'AphrontQueryCountException' => 'AphrontQueryException',
|
||||
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
|
||||
'AphrontQueryParameterException' => 'AphrontQueryException',
|
||||
'AphrontQueryRecoverableException' => 'AphrontQueryException',
|
||||
'AphrontRedirectResponse' => 'AphrontResponse',
|
||||
'AphrontStandardPageView' => 'AphrontPageView',
|
||||
'AphrontTableView' => 'AphrontView',
|
||||
'AphrontWebpageResponse' => 'AphrontResponse',
|
||||
),
|
||||
'requires_interface' =>
|
||||
array(
|
||||
),
|
||||
));
|
|
@ -0,0 +1,72 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
abstract class AphrontApplicationConfiguration {
|
||||
|
||||
private $request;
|
||||
private $host;
|
||||
private $path;
|
||||
|
||||
abstract public function getApplicationName();
|
||||
abstract public function getURIMap();
|
||||
abstract public function buildRequest();
|
||||
|
||||
final public function setRequest(AphrontRequest $request) {
|
||||
$this->request = $request;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
final public function buildController() {
|
||||
$map = $this->getURIMap();
|
||||
$mapper = new AphrontURIMapper($map);
|
||||
$request = $this->getRequest();
|
||||
$path = $request->getPath();
|
||||
list($controller_class, $uri_data) = $mapper->mapPath($path);
|
||||
|
||||
PhutilSymbolLoader::loadClass($controller_class);
|
||||
$controller = newv($controller_class, array($request));
|
||||
|
||||
return array($controller, $uri_data);
|
||||
}
|
||||
|
||||
final public function setHost($host) {
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getHost() {
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
final public function setPath($path) {
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getPath() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
}
|
15
src/aphront/applicationconfiguration/__init__.php
Normal file
15
src/aphront/applicationconfiguration/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/mapper');
|
||||
|
||||
phutil_require_module('phutil', 'symbols');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontApplicationConfiguration.php');
|
48
src/aphront/controller/AphrontController.php
Normal file
48
src/aphront/controller/AphrontController.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
abstract class AphrontController {
|
||||
|
||||
private $request;
|
||||
|
||||
public function willProcessRequest(array $uri_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
abstract public function processRequest();
|
||||
|
||||
final public function __construct(AphrontRequest $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
final public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function buildStandardPageResponse($view) {
|
||||
$page = new AphrontStandardPageView();
|
||||
$page->appendChild($view);
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($page->render());
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
13
src/aphront/controller/__init__.php
Normal file
13
src/aphront/controller/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/webpage');
|
||||
phutil_require_module('aphront', 'view/page/standard');
|
||||
|
||||
|
||||
phutil_require_source('AphrontController.php');
|
|
@ -0,0 +1,100 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class AphrontDefaultApplicationConfiguration
|
||||
extends AphrontApplicationConfiguration {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'aphront-default';
|
||||
}
|
||||
|
||||
public function getURIMap() {
|
||||
return array(
|
||||
'/repository/' => array(
|
||||
'$' => 'RepositoryListController',
|
||||
'new/$' => 'RepositoryEditController',
|
||||
'edit/(?<id>\d+)/$' => 'RepositoryEditController',
|
||||
'delete/(?<id>\d+)/$' => 'RepositoryDeleteController',
|
||||
),
|
||||
'/' => array(
|
||||
'$' => 'AphrontDirectoryMainController',
|
||||
),
|
||||
'/directory/' => array(
|
||||
'item/$' => 'AphrontDirectoryItemListController',
|
||||
'item/edit/(?:(?<id>\d+)/)?$' => 'AphrontDirectoryItemEditController',
|
||||
'item/delete/(?<id>\d+)/' => 'AphrontDirectoryItemDeleteController',
|
||||
'category/$'
|
||||
=> 'AphrontDirectoryCategoryListController',
|
||||
'category/edit/(?:(?<id>\d+)/)?$'
|
||||
=> 'AphrontDirectoryCategoryEditController',
|
||||
'category/delete/(?<id>\d+)/'
|
||||
=> 'AphrontDirectoryCategoryDeleteController',
|
||||
),
|
||||
'.*' => 'AphrontDefaultApplicationController',
|
||||
);
|
||||
}
|
||||
|
||||
public function buildRequest() {
|
||||
$request = new AphrontRequest($this->getHost(), $this->getPath());
|
||||
$request->setRequestData($_GET + $_POST);
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function handleException(Exception $ex) {
|
||||
|
||||
$class = phutil_escape_html(get_class($ex));
|
||||
$message = phutil_escape_html($ex->getMessage());
|
||||
|
||||
$content =
|
||||
'<div class="aphront-unhandled-exception">'.
|
||||
'<h1>Unhandled Exception "'.$class.'": '.$message.'</h1>'.
|
||||
'<code>'.phutil_escape_html((string)$ex).'</code>'.
|
||||
'</div>';
|
||||
|
||||
$view = new AphrontStandardPageView();
|
||||
$view->appendChild($content);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($view->render());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function willSendResponse(AphrontResponse $response) {
|
||||
$request = $this->getRequest();
|
||||
if ($response instanceof AphrontDialogResponse) {
|
||||
if (!$request->isAjax()) {
|
||||
$view = new AphrontStandardPageView();
|
||||
$view->appendChild(
|
||||
'<div style="padding: 2em 0;">'.
|
||||
$response->buildResponseString().
|
||||
'</div>');
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($view->render());
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
}
|
17
src/aphront/default/configuration/__init__.php
Normal file
17
src/aphront/default/configuration/__init__.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/applicationconfiguration');
|
||||
phutil_require_module('aphront', 'aphront/request');
|
||||
phutil_require_module('aphront', 'aphront/response/webpage');
|
||||
phutil_require_module('aphront', 'view/page/standard');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDefaultApplicationConfiguration.php');
|
|
@ -0,0 +1,38 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class AphrontDefaultApplicationController extends AphrontController {
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
|
||||
$path = phutil_escape_html($request->getPath());
|
||||
$host = phutil_escape_html($request->getHost());
|
||||
$controller_name = phutil_escape_html(get_class($this));
|
||||
|
||||
$page = new AphrontStandardPageView();
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
$response->setContent($page->render());
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
16
src/aphront/default/controller/__init__.php
Normal file
16
src/aphront/default/controller/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/controller');
|
||||
phutil_require_module('aphront', 'aphront/response/webpage');
|
||||
phutil_require_module('aphront', 'view/page/standard');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDefaultApplicationController.php');
|
68
src/aphront/mapper/AphrontURIMapper.php
Normal file
68
src/aphront/mapper/AphrontURIMapper.php
Normal file
|
@ -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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
final class AphrontURIMapper {
|
||||
|
||||
private $map;
|
||||
|
||||
final public function __construct(array $map) {
|
||||
$this->map = $map;
|
||||
}
|
||||
|
||||
final public function mapPath($path) {
|
||||
$map = $this->map;
|
||||
foreach ($map as $rule => $value) {
|
||||
list($controller, $data) = $this->tryRule($rule, $value, $path);
|
||||
if ($controller) {
|
||||
foreach ($data as $k => $v) {
|
||||
if (is_numeric($k)) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
return array($controller, $data);
|
||||
}
|
||||
}
|
||||
|
||||
return array(null, null);
|
||||
}
|
||||
|
||||
final private function tryRule($rule, $value, $path) {
|
||||
$match = null;
|
||||
if (!preg_match('#^'.$rule.'#', $path, $match)) {
|
||||
return array(null, null);
|
||||
}
|
||||
|
||||
if (!is_array($value)) {
|
||||
return array($value, $match);
|
||||
}
|
||||
|
||||
$path = substr($path, strlen($match[0]));
|
||||
foreach ($value as $srule => $sval) {
|
||||
list($controller, $data) = $this->tryRule($srule, $sval, $path);
|
||||
if ($controller) {
|
||||
return array($controller, $data + $match);
|
||||
}
|
||||
}
|
||||
|
||||
return array(null, null);
|
||||
}
|
||||
}
|
10
src/aphront/mapper/__init__.php
Normal file
10
src/aphront/mapper/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('AphrontURIMapper.php');
|
91
src/aphront/request/AphrontRequest.php
Normal file
91
src/aphront/request/AphrontRequest.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class AphrontRequest {
|
||||
|
||||
const TYPE_AJAX = '__ajax__';
|
||||
const TYPE_FORM = '__form__';
|
||||
|
||||
private $host;
|
||||
private $path;
|
||||
private $requestData;
|
||||
|
||||
final public function __construct($host, $path) {
|
||||
$this->host = $host;
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
final public function setRequestData(array $request_data) {
|
||||
$this->requestData = $request_data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getPath() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
final public function getHost() {
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
final public function getInt($name, $default = null) {
|
||||
if (isset($this->requestData[$name])) {
|
||||
return (int)$this->requestData[$name];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
final public function getStr($name, $default = null) {
|
||||
if (isset($this->requestData[$name])) {
|
||||
return (string)$this->requestData[$name];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
final public function getArr($name, $default = null) {
|
||||
if (isset($this->requestData[$name]) &&
|
||||
is_array($this->requestData[$name])) {
|
||||
return $this->requestData[$name];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
final public function getExists($name) {
|
||||
return array_key_exists($name, $this->requestData);
|
||||
}
|
||||
|
||||
final public function isHTTPPost() {
|
||||
return ($_SERVER['REQUEST_METHOD'] == 'POST');
|
||||
}
|
||||
|
||||
final public function isAjax() {
|
||||
return $this->getExists(self::TYPE_AJAX);
|
||||
}
|
||||
|
||||
final public function isFormPost() {
|
||||
return $this->getExists(self::TYPE_FORM) && $this->isHTTPPost();
|
||||
}
|
||||
|
||||
}
|
10
src/aphront/request/__init__.php
Normal file
10
src/aphront/request/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('AphrontRequest.php');
|
28
src/aphront/response/404/Aphront404Response.php
Normal file
28
src/aphront/response/404/Aphront404Response.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class Aphront404Response extends AphrontResponse {
|
||||
|
||||
public function buildResponseString() {
|
||||
return '404 Not Found';
|
||||
}
|
||||
|
||||
}
|
12
src/aphront/response/404/__init__.php
Normal file
12
src/aphront/response/404/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/base');
|
||||
|
||||
|
||||
phutil_require_source('Aphront404Response.php');
|
48
src/aphront/response/base/AphrontResponse.php
Normal file
48
src/aphront/response/base/AphrontResponse.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
abstract class AphrontResponse {
|
||||
|
||||
private $request;
|
||||
|
||||
public function setRequest($request) {
|
||||
$this->request = $request;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function getHeaders() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getCacheHeaders() {
|
||||
return array(
|
||||
array('Cache-Control', 'private, no-cache, no-store, must-revalidate'),
|
||||
array('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT'),
|
||||
);
|
||||
}
|
||||
|
||||
abstract public function buildResponseString();
|
||||
|
||||
}
|
10
src/aphront/response/base/__init__.php
Normal file
10
src/aphront/response/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('AphrontResponse.php');
|
35
src/aphront/response/dialog/AphrontDialogResponse.php
Normal file
35
src/aphront/response/dialog/AphrontDialogResponse.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
final class AphrontDialogResponse extends AphrontResponse {
|
||||
|
||||
private $dialog;
|
||||
|
||||
public function setDialog(AphrontDialogView $dialog) {
|
||||
$this->dialog = $dialog;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildResponseString() {
|
||||
return $this->dialog->render();
|
||||
}
|
||||
|
||||
}
|
12
src/aphront/response/dialog/__init__.php
Normal file
12
src/aphront/response/dialog/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDialogResponse.php');
|
41
src/aphront/response/redirect/AphrontRedirectResponse.php
Normal file
41
src/aphront/response/redirect/AphrontRedirectResponse.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class AphrontRedirectResponse extends AphrontResponse {
|
||||
|
||||
private $uri;
|
||||
|
||||
public function setURI($uri) {
|
||||
$this->uri = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeaders() {
|
||||
return array(
|
||||
array('Location', $this->uri),
|
||||
);
|
||||
}
|
||||
|
||||
public function buildResponseString() {
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
12
src/aphront/response/redirect/__init__.php
Normal file
12
src/aphront/response/redirect/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontRedirectResponse.php');
|
35
src/aphront/response/webpage/AphrontWebpageResponse.php
Normal file
35
src/aphront/response/webpage/AphrontWebpageResponse.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
class AphrontWebpageResponse extends AphrontResponse {
|
||||
|
||||
private $content;
|
||||
|
||||
public function setContent($content) {
|
||||
$this->content = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function buildResponseString() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
}
|
12
src/aphront/response/webpage/__init__.php
Normal file
12
src/aphront/response/webpage/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontWebpageResponse.php');
|
46
src/aphront/storage/lisk/AphrontLiskDAO.php
Normal file
46
src/aphront/storage/lisk/AphrontLiskDAO.php
Normal file
|
@ -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 AphrontLiskDAO extends LiskDAO {
|
||||
|
||||
public function establishConnection($mode) {
|
||||
return new AphrontMySQLDatabaseConnection(
|
||||
array(
|
||||
'user' => 'root',
|
||||
'pass' => '',
|
||||
'host' => 'localhost',
|
||||
'database' => 'aphront_'.$this->getApplicationName(),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
public function getTableName() {
|
||||
$class = strtolower(get_class($this));
|
||||
if (!strncmp($class, 'aphront', 7)) {
|
||||
$class = substr($class, 7);
|
||||
}
|
||||
$app = $this->getApplicationName();
|
||||
if (!strncmp($class, $app, strlen($app))) {
|
||||
$class = substr($class, strlen($app));
|
||||
}
|
||||
return $app.'_'.$class;
|
||||
}
|
||||
|
||||
abstract public function getApplicationName();
|
||||
}
|
13
src/aphront/storage/lisk/__init__.php
Normal file
13
src/aphront/storage/lisk/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/connection/mysql');
|
||||
phutil_require_module('aphront', 'storage/lisk/dao');
|
||||
|
||||
|
||||
phutil_require_source('AphrontLiskDAO.php');
|
|
@ -0,0 +1,50 @@
|
|||
<?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 AphrontDirectoryController extends AphrontController {
|
||||
|
||||
public function buildStandardPageResponse($view, array $data) {
|
||||
$page = new AphrontStandardPageView();
|
||||
|
||||
$page->setApplicationName('Directory');
|
||||
$page->setBaseURI('/');
|
||||
$page->setTitle(idx($data, 'title'));
|
||||
$page->setTabs(
|
||||
array(
|
||||
'directory' => array(
|
||||
'href' => '/',
|
||||
'name' => 'Directory',
|
||||
),
|
||||
'categories' => array(
|
||||
'href' => '/directory/category/',
|
||||
'name' => 'Categories',
|
||||
),
|
||||
'items' => array(
|
||||
'href' => '/directory/item/',
|
||||
'name' => 'Items',
|
||||
),
|
||||
),
|
||||
idx($data, 'tab'));
|
||||
$page->setGlyph("\xE2\x9A\x92");
|
||||
$page->appendChild($view);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
}
|
16
src/applications/directory/controller/base/__init__.php
Normal file
16
src/applications/directory/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('aphront', 'aphront/controller');
|
||||
phutil_require_module('aphront', 'aphront/response/webpage');
|
||||
phutil_require_module('aphront', 'view/page/standard');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryController.php');
|
|
@ -0,0 +1,51 @@
|
|||
<?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 AphrontDirectoryCategoryDeleteController
|
||||
extends AphrontDirectoryController {
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$category = id(new AphrontDirectoryCategory())->load($this->id);
|
||||
if (!$category) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$category->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/directory/category/');
|
||||
}
|
||||
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setTitle('Really delete this category?');
|
||||
$dialog->appendChild("Are you sure you want to delete this category?");
|
||||
$dialog->addSubmitButton('Delete');
|
||||
$dialog->addCancelButton('/directory/category/');
|
||||
$dialog->setSubmitURI($request->getPath());
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/404');
|
||||
phutil_require_module('aphront', 'aphront/response/dialog');
|
||||
phutil_require_module('aphront', 'aphront/response/redirect');
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'view/dialog');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryCategoryDeleteController.php');
|
|
@ -0,0 +1,110 @@
|
|||
<?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 AphrontDirectoryCategoryEditController
|
||||
extends AphrontDirectoryController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
if ($this->id) {
|
||||
$category = id(new AphrontDirectoryCategory())->load($this->id);
|
||||
if (!$category) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
} else {
|
||||
$category = new AphrontDirectoryCategory();
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$errors = array();
|
||||
|
||||
$request = $this->getRequest();
|
||||
if ($request->isFormPost()) {
|
||||
$category->setName($request->getStr('name'));
|
||||
$category->setSequence($request->getStr('sequence'));
|
||||
|
||||
if (!strlen($category->getName())) {
|
||||
$errors[] = 'Category name is required.';
|
||||
$e_name = 'Required';
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$category->save();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/directory/category/');
|
||||
}
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle('Form Errors')
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
$form = new AphrontFormView();
|
||||
if ($category->getID()) {
|
||||
$form->setAction('/directory/category/edit/'.$category->getID().'/');
|
||||
} else {
|
||||
$form->setAction('/directory/category/edit/');
|
||||
}
|
||||
|
||||
$categories = id(new AphrontDirectoryCategory())->loadAll();
|
||||
$category_map = mpull($categories, 'getName', 'getID');
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue($category->getName())
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Order')
|
||||
->setName('sequence')
|
||||
->setValue((int)$category->getSequence()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Save')
|
||||
->addCancelButton('/directory/category/'));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
if ($category->getID()) {
|
||||
$panel->setHeader('Edit Directory Category');
|
||||
} else {
|
||||
$panel->setHeader('Create New Directory Category');
|
||||
}
|
||||
|
||||
$panel->appendChild($form);
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array($error_view, $panel),
|
||||
array(
|
||||
'title' => 'Edit Directory Category',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/404');
|
||||
phutil_require_module('aphront', 'aphront/response/redirect');
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'view/form/base');
|
||||
phutil_require_module('aphront', 'view/form/control/submit');
|
||||
phutil_require_module('aphront', 'view/form/error');
|
||||
phutil_require_module('aphront', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryCategoryEditController.php');
|
|
@ -0,0 +1,72 @@
|
|||
<?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 AphrontDirectoryCategoryListController
|
||||
extends AphrontDirectoryController {
|
||||
|
||||
public function processRequest() {
|
||||
$categories = id(new AphrontDirectoryCategory())->loadAll();
|
||||
$categories = msort($categories, 'getSequence');
|
||||
|
||||
$rows = array();
|
||||
foreach ($categories as $category) {
|
||||
$rows[] = array(
|
||||
$category->getID(),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/directory/category/edit/'.$category->getID().'/',
|
||||
),
|
||||
phutil_escape_html($category->getName())),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/directory/category/delete/'.$category->getID().'/',
|
||||
'class' => 'button grey small',
|
||||
),
|
||||
'Delete'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
'ID',
|
||||
'Name',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
null,
|
||||
'wide',
|
||||
'action',
|
||||
));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->appendChild($table);
|
||||
$panel->setHeader('Directory Categories');
|
||||
$panel->setCreateButton('New Category', '/directory/category/edit/');
|
||||
|
||||
return $this->buildStandardPageResponse($panel, array(
|
||||
'title' => 'Directory Category List',
|
||||
'tab' => 'categories',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'view/control/table');
|
||||
phutil_require_module('aphront', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryCategoryListController.php');
|
|
@ -0,0 +1,50 @@
|
|||
<?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 AphrontDirectoryItemDeleteController extends AphrontDirectoryController {
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$item = id(new AphrontDirectoryItem())->load($this->id);
|
||||
if (!$item) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$item->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/directory/item/');
|
||||
}
|
||||
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setTitle('Really delete this item?');
|
||||
$dialog->appendChild("Are you sure you want to delete this item?");
|
||||
$dialog->addSubmitButton('Delete');
|
||||
$dialog->addCancelButton('/directory/item/');
|
||||
$dialog->setSubmitURI($request->getPath());
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/404');
|
||||
phutil_require_module('aphront', 'aphront/response/dialog');
|
||||
phutil_require_module('aphront', 'aphront/response/redirect');
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/item');
|
||||
phutil_require_module('aphront', 'view/dialog');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryItemDeleteController.php');
|
|
@ -0,0 +1,137 @@
|
|||
<?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 AphrontDirectoryItemEditController extends AphrontDirectoryController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->id = idx($data, 'id');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
if ($this->id) {
|
||||
$item = id(new AphrontDirectoryItem())->load($this->id);
|
||||
if (!$item) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
} else {
|
||||
$item = new AphrontDirectoryItem();
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$e_href = true;
|
||||
$errors = array();
|
||||
|
||||
$request = $this->getRequest();
|
||||
if ($request->isFormPost()) {
|
||||
$item->setName($request->getStr('name'));
|
||||
$item->setHref($request->getStr('href'));
|
||||
$item->setDescription($request->getStr('description'));
|
||||
$item->setCategoryID($request->getStr('categoryID'));
|
||||
$item->setSequence($request->getStr('sequence'));
|
||||
|
||||
if (!strlen($item->getName())) {
|
||||
$errors[] = 'Item name is required.';
|
||||
$e_name = 'Required';
|
||||
}
|
||||
|
||||
if (!strlen($item->getHref())) {
|
||||
$errors[] = 'Item link is required.';
|
||||
$e_href = 'Required';
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$item->save();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/directory/item/');
|
||||
}
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle('Form Errors')
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
$form = new AphrontFormView();
|
||||
if ($item->getID()) {
|
||||
$form->setAction('/directory/item/edit/'.$item->getID().'/');
|
||||
} else {
|
||||
$form->setAction('/directory/item/edit/');
|
||||
}
|
||||
|
||||
$categories = id(new AphrontDirectoryCategory())->loadAll();
|
||||
$category_map = mpull($categories, 'getName', 'getID');
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue($item->getName())
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel('Category')
|
||||
->setName('categoryID')
|
||||
->setOptions($category_map)
|
||||
->setValue($item->getCategoryID()))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Link')
|
||||
->setName('href')
|
||||
->setValue($item->getHref())
|
||||
->setError($e_href))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel('Description')
|
||||
->setName('description')
|
||||
->setValue($item->getDescription()))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Order')
|
||||
->setName('sequence')
|
||||
->setCaption(
|
||||
'Items in a category are sorted by "order", then by name.')
|
||||
->setValue((int)$item->getSequence()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Save')
|
||||
->addCancelButton('/directory/item/'));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
if ($item->getID()) {
|
||||
$panel->setHeader('Edit Directory Item');
|
||||
} else {
|
||||
$panel->setHeader('Create New Directory Item');
|
||||
}
|
||||
|
||||
$panel->appendChild($form);
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array($error_view, $panel),
|
||||
array(
|
||||
'title' => 'Edit Directory Item',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
22
src/applications/directory/controller/itemedit/__init__.php
Normal file
22
src/applications/directory/controller/itemedit/__init__.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'aphront/response/404');
|
||||
phutil_require_module('aphront', 'aphront/response/redirect');
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/item');
|
||||
phutil_require_module('aphront', 'view/form/base');
|
||||
phutil_require_module('aphront', 'view/form/control/submit');
|
||||
phutil_require_module('aphront', 'view/form/error');
|
||||
phutil_require_module('aphront', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryItemEditController.php');
|
|
@ -0,0 +1,77 @@
|
|||
<?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 AphrontDirectoryItemListController extends AphrontDirectoryController {
|
||||
|
||||
public function processRequest() {
|
||||
$items = id(new AphrontDirectoryItem())->loadAll();
|
||||
$items = msort($items, 'getSortKey');
|
||||
|
||||
$categories = id(new AphrontDirectoryCategory())->loadAll();
|
||||
$category_names = mpull($categories, 'getName', 'getID');
|
||||
|
||||
$rows = array();
|
||||
foreach ($items as $item) {
|
||||
$rows[] = array(
|
||||
$item->getID(),
|
||||
phutil_escape_html(idx($category_names, $item->getCategoryID())),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/directory/item/edit/'.$item->getID().'/',
|
||||
),
|
||||
phutil_escape_html($item->getName())),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/directory/item/delete/'.$item->getID().'/',
|
||||
'class' => 'button grey small',
|
||||
),
|
||||
'Delete'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
'ID',
|
||||
'Category',
|
||||
'Name',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
null,
|
||||
null,
|
||||
'wide',
|
||||
'action',
|
||||
));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->appendChild($table);
|
||||
$panel->setHeader('Directory Items');
|
||||
$panel->setCreateButton('New Item', '/directory/item/edit/');
|
||||
|
||||
return $this->buildStandardPageResponse($panel, array(
|
||||
'title' => 'Directory Items',
|
||||
'tab' => 'items',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
19
src/applications/directory/controller/itemlist/__init__.php
Normal file
19
src/applications/directory/controller/itemlist/__init__.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/item');
|
||||
phutil_require_module('aphront', 'view/control/table');
|
||||
phutil_require_module('aphront', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryItemListController.php');
|
|
@ -0,0 +1,75 @@
|
|||
<?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 AphrontDirectoryMainController extends AphrontDirectoryController {
|
||||
|
||||
public function processRequest() {
|
||||
$items = id(new AphrontDirectoryItem())->loadAll();
|
||||
$items = msort($items, 'getSortKey');
|
||||
|
||||
$categories = id(new AphrontDirectoryCategory())->loadAll();
|
||||
$categories = msort($categories, 'getSequence');
|
||||
|
||||
$category_map = mpull($categories, 'getName', 'getID');
|
||||
$category_map[0] = 'Free Radicals';
|
||||
$items = mgroup($items, 'getCategoryID');
|
||||
|
||||
$content = array();
|
||||
foreach ($category_map as $id => $category_name) {
|
||||
$category_items = idx($items, $id);
|
||||
if (!$category_items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item_markup = array();
|
||||
foreach ($category_items as $item) {
|
||||
$item_markup[] =
|
||||
'<div>'.
|
||||
'<h2>'.
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $item->getHref(),
|
||||
),
|
||||
phutil_escape_html($item->getName())).
|
||||
'</h2>'.
|
||||
'<p>'.phutil_escape_html($item->getDescription()).'</p>'.
|
||||
'</div>';
|
||||
}
|
||||
|
||||
$content[] =
|
||||
'<div class="aphront-directory-category">'.
|
||||
'<h1>'.phutil_escape_html($category_name).'</h1>'.
|
||||
'<div class="aphront-directory-group">'.
|
||||
implode("\n", $item_markup).
|
||||
'</div>'.
|
||||
'</div>';
|
||||
}
|
||||
|
||||
$content =
|
||||
'<div class="aphront-directory-list">'.
|
||||
implode("\n", $content).
|
||||
'</div>';
|
||||
|
||||
return $this->buildStandardPageResponse($content, array(
|
||||
'title' => 'Directory',
|
||||
'tab' => 'directory',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
17
src/applications/directory/controller/main/__init__.php
Normal file
17
src/applications/directory/controller/main/__init__.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'applications/directory/controller/base');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/category');
|
||||
phutil_require_module('aphront', 'applications/directory/storage/item');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryMainController.php');
|
|
@ -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.
|
||||
*/
|
||||
|
||||
abstract class AphrontDirectoryDAO extends AphrontLiskDAO {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'directory';
|
||||
}
|
||||
|
||||
}
|
12
src/applications/directory/storage/base/__init__.php
Normal file
12
src/applications/directory/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('aphront', 'aphront/storage/lisk');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryDAO.php');
|
|
@ -0,0 +1,24 @@
|
|||
<?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 AphrontDirectoryCategory extends AphrontDirectoryDAO {
|
||||
|
||||
protected $name;
|
||||
protected $sequence;
|
||||
|
||||
}
|
12
src/applications/directory/storage/category/__init__.php
Normal file
12
src/applications/directory/storage/category/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'applications/directory/storage/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryCategory.php');
|
|
@ -0,0 +1,36 @@
|
|||
<?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 AphrontDirectoryItem extends AphrontDirectoryDAO {
|
||||
|
||||
protected $name;
|
||||
protected $description;
|
||||
protected $href;
|
||||
protected $categoryID;
|
||||
protected $sequence;
|
||||
protected $imageGUID;
|
||||
|
||||
public function getSortKey() {
|
||||
return sprintf(
|
||||
'%08d:%08d:%s',
|
||||
$this->getCategoryID(),
|
||||
$this->getSequence(),
|
||||
$this->getName());
|
||||
}
|
||||
|
||||
}
|
12
src/applications/directory/storage/item/__init__.php
Normal file
12
src/applications/directory/storage/item/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'applications/directory/storage/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDirectoryItem.php');
|
59
src/applications/review/constants/action/DifferentialAction.php
Executable file
59
src/applications/review/constants/action/DifferentialAction.php
Executable file
|
@ -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.
|
||||
*/
|
||||
|
||||
final class DifferentialAction {
|
||||
|
||||
const ACTION_COMMIT = 'commit';
|
||||
const ACTION_COMMENT = 'none';
|
||||
const ACTION_ACCEPT = 'accept';
|
||||
const ACTION_REJECT = 'reject';
|
||||
const ACTION_ABANDON = 'abandon';
|
||||
const ACTION_REQUEST = 'request_review';
|
||||
const ACTION_RECLAIM = 'reclaim';
|
||||
const ACTION_UPDATE = 'update';
|
||||
const ACTION_RESIGN = 'resign';
|
||||
const ACTION_SUMMARIZE = 'summarize';
|
||||
const ACTION_TESTPLAN = 'testplan';
|
||||
const ACTION_CREATE = 'create';
|
||||
const ACTION_ADDREVIEWERS = 'add_reviewers';
|
||||
|
||||
public static function getActionVerb($action) {
|
||||
static $verbs = array(
|
||||
self::ACTION_COMMENT => 'commented on',
|
||||
self::ACTION_ACCEPT => 'accepted',
|
||||
self::ACTION_REJECT => 'requested changes to',
|
||||
self::ACTION_ABANDON => 'abandoned',
|
||||
self::ACTION_COMMIT => 'committed',
|
||||
self::ACTION_REQUEST => 'requested a review of',
|
||||
self::ACTION_RECLAIM => 'reclaimed',
|
||||
self::ACTION_UPDATE => 'updated',
|
||||
self::ACTION_RESIGN => 'resigned from',
|
||||
self::ACTION_SUMMARIZE => 'summarized',
|
||||
self::ACTION_TESTPLAN => 'explained the test plan for',
|
||||
self::ACTION_CREATE => 'created',
|
||||
self::ACTION_ADDREVIEWERS => 'added reviewers to',
|
||||
);
|
||||
|
||||
if (empty($verbs[$action])) {
|
||||
return $verbs[$action];
|
||||
} else {
|
||||
return 'brazenly "'.$action.'ed"';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
10
src/applications/review/constants/action/__init__.php
Normal file
10
src/applications/review/constants/action/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('DifferentialAction.php');
|
125
src/applications/review/constants/changetype/DifferentialChangeType.php
Executable file
125
src/applications/review/constants/changetype/DifferentialChangeType.php
Executable file
|
@ -0,0 +1,125 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class DifferentialChangeType {
|
||||
|
||||
const TYPE_ADD = 1;
|
||||
const TYPE_CHANGE = 2;
|
||||
const TYPE_DELETE = 3;
|
||||
const TYPE_MOVE_AWAY = 4;
|
||||
const TYPE_COPY_AWAY = 5;
|
||||
const TYPE_MOVE_HERE = 6;
|
||||
const TYPE_COPY_HERE = 7;
|
||||
const TYPE_MULTICOPY = 8;
|
||||
const TYPE_MESSAGE = 9;
|
||||
const TYPE_CHILD = 10;
|
||||
|
||||
const FILE_TEXT = 1;
|
||||
const FILE_IMAGE = 2;
|
||||
const FILE_BINARY = 3;
|
||||
const FILE_DIRECTORY = 4;
|
||||
const FILE_SYMLINK = 5;
|
||||
const FILE_DELETED = 6;
|
||||
const FILE_NORMAL = 7;
|
||||
|
||||
public static function getSummaryCharacterForChangeType($type) {
|
||||
static $types = array(
|
||||
self::TYPE_ADD => 'A',
|
||||
self::TYPE_CHANGE => 'M',
|
||||
self::TYPE_DELETE => 'D',
|
||||
self::TYPE_MOVE_AWAY => 'V',
|
||||
self::TYPE_COPY_AWAY => 'P',
|
||||
self::TYPE_MOVE_HERE => 'V',
|
||||
self::TYPE_COPY_HERE => 'P',
|
||||
self::TYPE_MULTICOPY => 'P',
|
||||
self::TYPE_MESSAGE => 'Q',
|
||||
self::TYPE_CHILD => '@',
|
||||
);
|
||||
return idx($types, coalesce($type, '?'), '~');
|
||||
}
|
||||
|
||||
public static function getShortNameForFileType($type) {
|
||||
static $names = array(
|
||||
self::FILE_TEXT => null,
|
||||
self::FILE_DIRECTORY => 'dir',
|
||||
self::FILE_IMAGE => 'img',
|
||||
self::FILE_BINARY => 'bin',
|
||||
self::FILE_SYMLINK => 'sym',
|
||||
);
|
||||
return idx($names, coalesce($type, '?'), '???');
|
||||
}
|
||||
|
||||
public static function isOldLocationChangeType($type) {
|
||||
static $types = array(
|
||||
DifferentialChangeType::TYPE_MOVE_AWAY => true,
|
||||
DifferentialChangeType::TYPE_COPY_AWAY => true,
|
||||
DifferentialChangeType::TYPE_MULTICOPY => true,
|
||||
);
|
||||
return isset($types[$type]);
|
||||
}
|
||||
|
||||
public static function isNewLocationChangeType($type) {
|
||||
static $types = array(
|
||||
DifferentialChangeType::TYPE_MOVE_HERE => true,
|
||||
DifferentialChangeType::TYPE_COPY_HERE => true,
|
||||
);
|
||||
return isset($types[$type]);
|
||||
}
|
||||
|
||||
public static function isDeleteChangeType($type) {
|
||||
static $types = array(
|
||||
DifferentialChangeType::TYPE_DELETE => true,
|
||||
DifferentialChangeType::TYPE_MOVE_AWAY => true,
|
||||
DifferentialChangeType::TYPE_MULTICOPY => true,
|
||||
);
|
||||
return isset($types[$type]);
|
||||
}
|
||||
|
||||
public static function isCreateChangeType($type) {
|
||||
static $types = array(
|
||||
DifferentialChangeType::TYPE_ADD => true,
|
||||
DifferentialChangeType::TYPE_COPY_HERE => true,
|
||||
DifferentialChangeType::TYPE_MOVE_HERE => true,
|
||||
);
|
||||
return isset($types[$type]);
|
||||
}
|
||||
|
||||
public static function isModifyChangeType($type) {
|
||||
static $types = array(
|
||||
DifferentialChangeType::TYPE_CHANGE => true,
|
||||
);
|
||||
return isset($types[$type]);
|
||||
}
|
||||
|
||||
public static function getFullNameForChangeType($type) {
|
||||
static $types = array(
|
||||
self::TYPE_ADD => 'Added',
|
||||
self::TYPE_CHANGE => 'Modified',
|
||||
self::TYPE_DELETE => 'Deleted',
|
||||
self::TYPE_MOVE_AWAY => 'Moved Away',
|
||||
self::TYPE_COPY_AWAY => 'Copied Away',
|
||||
self::TYPE_MOVE_HERE => 'Moved Here',
|
||||
self::TYPE_COPY_HERE => 'Copied Here',
|
||||
self::TYPE_MULTICOPY => 'Deleted After Multiple Copy',
|
||||
self::TYPE_MESSAGE => 'Commit Message',
|
||||
self::TYPE_CHILD => 'Contents Modified',
|
||||
);
|
||||
return idx($types, coalesce($type, '?'), 'Unknown');
|
||||
}
|
||||
|
||||
}
|
12
src/applications/review/constants/changetype/__init__.php
Normal file
12
src/applications/review/constants/changetype/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('DifferentialChangeType.php');
|
27
src/applications/review/constants/lintstatus/DifferentialLintStatus.php
Executable file
27
src/applications/review/constants/lintstatus/DifferentialLintStatus.php
Executable file
|
@ -0,0 +1,27 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class DifferentialLintStatus {
|
||||
|
||||
const LINT_NO = 0;
|
||||
const LINT_WARNINGS = 1;
|
||||
const LINT_OKAY = 2;
|
||||
const LINT_NOT_APPLICABLE = 3;
|
||||
const LINT_SKIP = 4;
|
||||
|
||||
}
|
10
src/applications/review/constants/lintstatus/__init__.php
Normal file
10
src/applications/review/constants/lintstatus/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('DifferentialLintStatus.php');
|
|
@ -0,0 +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.
|
||||
*/
|
||||
|
||||
final class DifferentialRevisionStatus {
|
||||
|
||||
const NEEDS_REVIEW = 0;
|
||||
const NEEDS_REVISION = 1;
|
||||
const ACCEPTED = 2;
|
||||
const COMMITTED = 3;
|
||||
const ABANDONED = 4;
|
||||
|
||||
public static function getNameForRevisionStatus($status) {
|
||||
static $map = array(
|
||||
self::NEEDS_REVIEW => 'Needs Review',
|
||||
self::NEEDS_REVISION => 'Needs Revision',
|
||||
self::ACCEPTED => 'Accepted',
|
||||
self::COMMITTED => 'Committed',
|
||||
self::ABANDONED => 'Abandoned',
|
||||
);
|
||||
|
||||
return idx($map, coalesce($status, '?'), 'Unknown');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('DifferentialRevisionStatus.php');
|
27
src/applications/review/constants/unitstatus/DifferentialUnitStatus.php
Executable file
27
src/applications/review/constants/unitstatus/DifferentialUnitStatus.php
Executable file
|
@ -0,0 +1,27 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class DifferentialUnitStatus {
|
||||
|
||||
const UNIT_NO = 0;
|
||||
const UNIT_FAIL = 1;
|
||||
const UNIT_OKAY = 2;
|
||||
const UNIT_NO_TESTS = 3;
|
||||
const UNIT_NOT_APPLICABLE = 4;
|
||||
|
||||
}
|
10
src/applications/review/constants/unitstatus/__init__.php
Normal file
10
src/applications/review/constants/unitstatus/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('DifferentialUnitStatus.php');
|
225
src/storage/connection/base/AphrontDatabaseConnection.php
Normal file
225
src/storage/connection/base/AphrontDatabaseConnection.php
Normal file
|
@ -0,0 +1,225 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
abstract class AphrontDatabaseConnection {
|
||||
|
||||
private static $transactionStacks = array();
|
||||
private static $transactionShutdownRegistered = false;
|
||||
|
||||
abstract public function getInsertID();
|
||||
abstract public function getAffectedRows();
|
||||
abstract public function selectAllResults();
|
||||
abstract public function executeRawQuery($raw_query);
|
||||
abstract protected function getTransactionKey();
|
||||
|
||||
abstract public function escapeString($string);
|
||||
abstract public function escapeColumnName($string);
|
||||
abstract public function escapeMultilineComment($string);
|
||||
abstract public function escapeStringForLikeClause($string);
|
||||
|
||||
public function queryData($pattern/*, $arg, $arg, ... */) {
|
||||
$args = func_get_args();
|
||||
array_unshift($args, $this);
|
||||
return call_user_func_array('queryfx_all', $args);
|
||||
}
|
||||
|
||||
public function query($pattern/*, $arg, $arg, ... */) {
|
||||
$args = func_get_args();
|
||||
array_unshift($args, $this);
|
||||
return call_user_func_array('queryfx', $args);
|
||||
}
|
||||
|
||||
// TODO: Probably need to reset these when we catch a connection exception
|
||||
// in the transaction stack.
|
||||
protected function &getLockLevels() {
|
||||
static $levels = array();
|
||||
$key = $this->getTransactionKey();
|
||||
if (!isset($levels[$key])) {
|
||||
$levels[$key] = array(
|
||||
'read' => 0,
|
||||
'write' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
return $levels[$key];
|
||||
}
|
||||
|
||||
public function isReadLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
return ($levels['read'] > 0);
|
||||
}
|
||||
|
||||
public function isWriteLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
return ($levels['write'] > 0);
|
||||
}
|
||||
|
||||
public function startReadLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
++$levels['read'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function startWriteLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
++$levels['write'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function stopReadLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
if ($levels['read'] < 1) {
|
||||
throw new Exception('Unable to stop read locking: not read locking.');
|
||||
}
|
||||
--$levels['read'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function stopWriteLocking() {
|
||||
$levels = &$this->getLockLevels();
|
||||
if ($levels['write'] < 1) {
|
||||
throw new Exception('Unable to stop read locking: not write locking.');
|
||||
}
|
||||
--$levels['write'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function &getTransactionStack($key) {
|
||||
if (!self::$transactionShutdownRegistered) {
|
||||
self::$transactionShutdownRegistered = true;
|
||||
register_shutdown_function(
|
||||
array(
|
||||
'LiskConnection',
|
||||
'shutdownTransactionStacks',
|
||||
));
|
||||
}
|
||||
|
||||
if (!isset(self::$transactionStacks[$key])) {
|
||||
self::$transactionStacks[$key] = array();
|
||||
}
|
||||
|
||||
return self::$transactionStacks[$key];
|
||||
}
|
||||
|
||||
public static function shutdownTransactionStacks() {
|
||||
foreach (self::$transactionStacks as $stack) {
|
||||
if ($stack === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$count = count($stack);
|
||||
if ($count) {
|
||||
throw new Exception(
|
||||
'Script exited with '.$count.' open transactions! The '.
|
||||
'transactions will be implicitly rolled back. Calls to '.
|
||||
'openTransaction() should always be paired with a call to '.
|
||||
'saveTransaction() or killTransaction(); you have an unpaired '.
|
||||
'call somewhere.',
|
||||
$count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function openTransaction() {
|
||||
$key = $this->getTransactionKey();
|
||||
$stack = &$this->getTransactionStack($key);
|
||||
|
||||
$new_transaction = !count($stack);
|
||||
|
||||
// TODO: At least in development, push context information instead of
|
||||
// `true' so we can report (or, at least, guess) where unpaired
|
||||
// transaction calls happened.
|
||||
$stack[] = true;
|
||||
|
||||
end($stack);
|
||||
$key = key($stack);
|
||||
|
||||
if ($new_transaction) {
|
||||
$this->query('START TRANSACTION');
|
||||
} else {
|
||||
$this->query('SAVEPOINT '.$this->getSavepointName($key));
|
||||
}
|
||||
}
|
||||
|
||||
public function isInsideTransaction() {
|
||||
$key = $this->getTransactionKey();
|
||||
$stack = &$this->getTransactionStack($key);
|
||||
return (bool)count($stack);
|
||||
}
|
||||
|
||||
public function saveTransaction() {
|
||||
$key = $this->getTransactionKey();
|
||||
$stack = &$this->getTransactionStack($key);
|
||||
|
||||
if (!count($stack)) {
|
||||
throw new Exception(
|
||||
"No open transaction! Unable to save transaction, since there ".
|
||||
"isn't one.");
|
||||
}
|
||||
|
||||
array_pop($stack);
|
||||
|
||||
if (!count($stack)) {
|
||||
$this->query('COMMIT');
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTransactionUnless($cond) {
|
||||
if ($cond) {
|
||||
$this->killTransaction();
|
||||
} else {
|
||||
$this->saveTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTransactionIf($cond) {
|
||||
$this->saveTransactionUnless(!$cond);
|
||||
}
|
||||
|
||||
public function killTransaction() {
|
||||
$key = $this->getTransactionKey();
|
||||
$stack = &$this->getTransactionStack($key);
|
||||
|
||||
if (!count($stack)) {
|
||||
throw new Exception(
|
||||
"No open transaction! Unable to kill transaction, since there ".
|
||||
"isn't one.");
|
||||
}
|
||||
|
||||
$count = count($stack);
|
||||
|
||||
end($stack);
|
||||
$key = key($stack);
|
||||
array_pop($stack);
|
||||
|
||||
if (!count($stack)) {
|
||||
$this->query('ROLLBACK');
|
||||
} else {
|
||||
$this->query(
|
||||
'ROLLBACK TO SAVEPOINT '.$this->getSavepointName($key)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getSavepointName($key) {
|
||||
return 'LiskSavepoint_'.$key;
|
||||
}
|
||||
}
|
12
src/storage/connection/base/__init__.php
Normal file
12
src/storage/connection/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('aphront', 'storage/queryfx');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDatabaseConnection.php');
|
198
src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
Normal file
198
src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php
Normal file
|
@ -0,0 +1,198 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection {
|
||||
|
||||
private $config;
|
||||
private $connection;
|
||||
|
||||
public function __construct(array $configuration) {
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
public function escapeString($string) {
|
||||
if (!$this->connection) {
|
||||
$this->establishConnection();
|
||||
}
|
||||
return mysql_real_escape_string($string, $this->connection);
|
||||
}
|
||||
|
||||
public function escapeColumnName($name) {
|
||||
return '`'.str_replace('`', '\\`', $name).'`';
|
||||
}
|
||||
|
||||
public function escapeMultilineComment($comment) {
|
||||
// These can either terminate a comment, confuse the hell out of the parser,
|
||||
// make MySQL execute the comment as a query, or, in the case of semicolon,
|
||||
// are quasi-dangerous because the semicolon could turn a broken query into
|
||||
// a working query plus an ignored query.
|
||||
|
||||
static $map = array(
|
||||
'--' => '(DOUBLEDASH)',
|
||||
'*/' => '(STARSLASH)',
|
||||
'//' => '(SLASHSLASH)',
|
||||
'#' => '(HASH)',
|
||||
'!' => '(BANG)',
|
||||
';' => '(SEMICOLON)',
|
||||
);
|
||||
|
||||
$comment = str_replace(
|
||||
array_keys($map),
|
||||
array_values($map),
|
||||
$comment);
|
||||
|
||||
// For good measure, kill anything else that isn't a nice printable
|
||||
// character.
|
||||
$comment = preg_replace('/[^\x20-\x7F]+/', ' ', $comment);
|
||||
|
||||
return '/* '.$comment.' */';
|
||||
}
|
||||
|
||||
public function escapeStringForLikeClause($value) {
|
||||
$value = $this->escapeString($value);
|
||||
// Ideally the query shouldn't be modified after safely escaping it,
|
||||
// but we need to escape _ and % within LIKE terms.
|
||||
$value = str_replace(
|
||||
// Even though we've already escaped, we need to replace \ with \\
|
||||
// because MYSQL unescapes twice inside a LIKE clause. See note
|
||||
// at mysql.com. However, if the \ is being used to escape a single
|
||||
// quote ('), then the \ should not be escaped. Thus, after all \
|
||||
// are replaced with \\, we need to revert instances of \\' back to
|
||||
// \'.
|
||||
array('\\', '\\\\\'', '_', '%'),
|
||||
array('\\\\', '\\\'', '\_', '\%'),
|
||||
$value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function getConfiguration($key, $default = null) {
|
||||
return idx($this->configuration, $key, $default);
|
||||
}
|
||||
|
||||
private function establishConnection() {
|
||||
$this->connection = null;
|
||||
|
||||
$user = $this->getConfiguration('user');
|
||||
$host = $this->getConfiguration('host');
|
||||
|
||||
$conn = @mysql_connect(
|
||||
$host,
|
||||
$user,
|
||||
$this->getConfiguration('pass'),
|
||||
$new_link = true,
|
||||
$flags = 0);
|
||||
|
||||
if (!$conn) {
|
||||
$errno = mysql_errno();
|
||||
$error = mysql_error();
|
||||
throw new AphrontQueryConnectionException(
|
||||
"Attempt to connect to {$user}@{$host} failed with error #{$errno}: ".
|
||||
"{$error}.");
|
||||
}
|
||||
|
||||
$ret = @mysql_select_db($this->getConfiguration('database'), $conn);
|
||||
if (!$ret) {
|
||||
$this->throwQueryException($conn);
|
||||
}
|
||||
|
||||
$this->connection = $conn;
|
||||
}
|
||||
|
||||
public function getInsertID() {
|
||||
return mysql_insert_id($this->requireConnection());
|
||||
}
|
||||
|
||||
public function getAffectedRows() {
|
||||
return mysql_affected_rows($this->requireConnection());
|
||||
}
|
||||
|
||||
public function getTransactionKey() {
|
||||
return (int)$this->requireConnection();
|
||||
}
|
||||
|
||||
private function requireConnection() {
|
||||
if (!$this->connection) {
|
||||
$this->establishConnection();
|
||||
}
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
public function selectAllResults() {
|
||||
$result = array();
|
||||
$res = $this->lastResult;
|
||||
if ($res == null) {
|
||||
throw new Exception('No query result to fetch from!');
|
||||
}
|
||||
while (($row = mysql_fetch_assoc($res)) !== false) {
|
||||
$result[] = $row;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function executeRawQuery($raw_query) {
|
||||
$this->lastResult = null;
|
||||
$retries = 3;
|
||||
while ($retries--) {
|
||||
try {
|
||||
if (!$this->connection) {
|
||||
$this->establishConnection();
|
||||
}
|
||||
|
||||
$result = mysql_query($raw_query, $this->connection);
|
||||
|
||||
if ($result) {
|
||||
$this->lastResult = $result;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->throwQueryException($this->connection);
|
||||
} catch (AphrontQueryConnectionLostException $ex) {
|
||||
if (!$retries) {
|
||||
throw $ex;
|
||||
}
|
||||
if ($this->isInsideTransaction()) {
|
||||
throw $ex;
|
||||
}
|
||||
$this->connection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function throwQueryException($connection) {
|
||||
$errno = mysql_errno($connection);
|
||||
$error = mysql_error($connection);
|
||||
|
||||
switch ($errno) {
|
||||
case 2013: // Connection Dropped
|
||||
case 2006: // Gone Away
|
||||
throw new AphrontQueryConnectionLostException("#{$errno}: {$error}");
|
||||
break;
|
||||
case 1213: // Deadlock
|
||||
case 1205: // Lock wait timeout exceeded
|
||||
throw new AphrontQueryRecoverableException("#{$errno}: {$error}");
|
||||
break;
|
||||
default:
|
||||
// TODO: 1062 is syntax error, and quite terrible in production.
|
||||
throw new AphrontQueryException("#{$errno}: {$error}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
18
src/storage/connection/mysql/__init__.php
Normal file
18
src/storage/connection/mysql/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/connection/base');
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
phutil_require_module('aphront', 'storage/exception/connection');
|
||||
phutil_require_module('aphront', 'storage/exception/connectionlost');
|
||||
phutil_require_module('aphront', 'storage/exception/recoverable');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontMySQLDatabaseConnection.php');
|
22
src/storage/exception/base/AphrontQueryException.php
Normal file
22
src/storage/exception/base/AphrontQueryException.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryException extends Exception { }
|
10
src/storage/exception/base/__init__.php
Normal file
10
src/storage/exception/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryException.php');
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryConnectionException extends AphrontQueryException { }
|
12
src/storage/exception/connection/__init__.php
Normal file
12
src/storage/exception/connection/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryConnectionException.php');
|
|
@ -0,0 +1,23 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryConnectionLostException
|
||||
extends AphrontQueryRecoverableException { }
|
12
src/storage/exception/connectionlost/__init__.php
Normal file
12
src/storage/exception/connectionlost/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/recoverable');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryConnectionLostException.php');
|
22
src/storage/exception/count/AphrontQueryCountException.php
Normal file
22
src/storage/exception/count/AphrontQueryCountException.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryCountException extends AphrontQueryException { }
|
12
src/storage/exception/count/__init__.php
Normal file
12
src/storage/exception/count/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryCountException.php');
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryObjectMissingException extends AphrontQueryException { }
|
12
src/storage/exception/objectmissing/__init__.php
Normal file
12
src/storage/exception/objectmissing/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryObjectMissingException.php');
|
|
@ -0,0 +1,35 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryParameterException extends AphrontQueryException {
|
||||
|
||||
private $query;
|
||||
|
||||
public function __construct($query, $message) {
|
||||
parent::__construct($message." Query: ".$query);
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
public function getQuery() {
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
}
|
12
src/storage/exception/parameter/__init__.php
Normal file
12
src/storage/exception/parameter/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryParameterException.php');
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
class AphrontQueryRecoverableException extends AphrontQueryException { }
|
12
src/storage/exception/recoverable/__init__.php
Normal file
12
src/storage/exception/recoverable/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/base');
|
||||
|
||||
|
||||
phutil_require_source('AphrontQueryRecoverableException.php');
|
1109
src/storage/lisk/dao/LiskDAO.php
Normal file
1109
src/storage/lisk/dao/LiskDAO.php
Normal file
File diff suppressed because it is too large
Load diff
16
src/storage/lisk/dao/__init__.php
Normal file
16
src/storage/lisk/dao/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/count');
|
||||
phutil_require_module('aphront', 'storage/exception/objectmissing');
|
||||
phutil_require_module('aphront', 'storage/qsprintf');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('LiskDAO.php');
|
14
src/storage/qsprintf/__init__.php
Normal file
14
src/storage/qsprintf/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/parameter');
|
||||
|
||||
phutil_require_module('phutil', 'xsprintf');
|
||||
|
||||
|
||||
phutil_require_source('qsprintf.php');
|
309
src/storage/qsprintf/qsprintf.php
Normal file
309
src/storage/qsprintf/qsprintf.php
Normal file
|
@ -0,0 +1,309 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format an SQL query. This function behaves like sprintf(), except that
|
||||
* all the normal conversions (like %s) will be properly escaped, and
|
||||
* additional conversions are supported:
|
||||
*
|
||||
* %nd, %ns, %nf
|
||||
* "Nullable" versions of %d, %s and %f. Will produce 'NULL' if the
|
||||
* argument is a strict null.
|
||||
*
|
||||
* %=d, %=s, %=f
|
||||
* "Nullable Test" versions of %d, %s and %f. If you pass a value, you
|
||||
* get "= 3"; if you pass null, you get "IS NULL". For instance, this
|
||||
* will work properly if `hatID' is a nullable column and $hat is null.
|
||||
*
|
||||
* qsprintf($conn, 'WHERE hatID %=d', $hat);
|
||||
*
|
||||
* %Ld, %Ls, %Lf
|
||||
* "List" versions of %d, %s and %f. These are appropriate for use in
|
||||
* an "IN" clause. For example:
|
||||
*
|
||||
* qsprintf($conn, 'WHERE hatID IN(%Ld)', $list_of_hats);
|
||||
*
|
||||
* %T ("Table")
|
||||
* Escapes a table name.
|
||||
*
|
||||
* %C, %LC
|
||||
* Escapes a column name or a list of column names.
|
||||
*
|
||||
* %K ("Comment")
|
||||
* Escapes a comment.
|
||||
*
|
||||
* %Q ("Query Fragment")
|
||||
* Injects a raw query fragment. Extremely dangerous! Not escaped!
|
||||
*
|
||||
* %~ ("Substring")
|
||||
* Escapes a substring query for a LIKE (or NOT LIKE) clause. For example:
|
||||
*
|
||||
* // Find all rows with $search as a substing of `name`.
|
||||
* qsprintf($conn, 'WHERE name LIKE %~', $search);
|
||||
*
|
||||
* See also %> and %<.
|
||||
*
|
||||
* %> ("Prefix")
|
||||
* Escapes a prefix query for a LIKE clause. For example:
|
||||
*
|
||||
* // Find all rows where `name` starts with $prefix.
|
||||
* qsprintf($conn, 'WHERE name LIKE %>', $prefix);
|
||||
*
|
||||
* %< ("Suffix")
|
||||
* Escapes a suffix query for a LIKE clause. For example:
|
||||
*
|
||||
* // Find all rows where `name` ends with $suffix.
|
||||
* qsprintf($conn, 'WHERE name LIKE %<', $suffix);
|
||||
*
|
||||
* @group storage
|
||||
*/
|
||||
function qsprintf($conn, $pattern/*, ... */) {
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
return xsprintf('xsprintf_query', $conn, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function vqsprintf($conn, $pattern, array $argv) {
|
||||
array_unshift($argv, $pattern);
|
||||
return xsprintf('xsprintf_query', $conn, $argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* xsprintf() callback for encoding SQL queries. See qsprintf().
|
||||
* @group storage
|
||||
*/
|
||||
function xsprintf_query($userdata, &$pattern, &$pos, &$value, &$length) {
|
||||
$type = $pattern[$pos];
|
||||
$conn = $userdata;
|
||||
$next = (strlen($pattern) > $pos + 1) ? $pattern[$pos + 1] : null;
|
||||
|
||||
$nullable = false;
|
||||
$done = false;
|
||||
|
||||
$prefix = '';
|
||||
|
||||
switch ($type) {
|
||||
case '=': // Nullable test
|
||||
switch ($next) {
|
||||
case 'd':
|
||||
case 'f':
|
||||
case 's':
|
||||
$pattern = substr_replace($pattern, '', $pos, 1);
|
||||
$length = strlen($pattern);
|
||||
$type = 's';
|
||||
if ($value === null) {
|
||||
$value = 'IS NULL';
|
||||
$done = true;
|
||||
} else {
|
||||
$prefix = '= ';
|
||||
$type = $next;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Unknown conversion, try %=d, %=s, or %=f.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n': // Nullable...
|
||||
switch ($next) {
|
||||
case 'd': // ...integer.
|
||||
case 'f': // ...float.
|
||||
case 's': // ...string.
|
||||
$pattern = substr_replace($pattern, '', $pos, 1);
|
||||
$length = strlen($pattern);
|
||||
$type = $next;
|
||||
$nullable = true;
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Unknown conversion, try %nd or %ns.');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L': // List of..
|
||||
_qsprintf_check_type($value, "L{$next}", $pattern);
|
||||
$pattern = substr_replace($pattern, '', $pos, 1);
|
||||
$length = strlen($pattern);
|
||||
$type = 's';
|
||||
$done = true;
|
||||
|
||||
switch ($next) {
|
||||
case 'd': // ...integers.
|
||||
$value = implode(', ', array_map('intval', $value));
|
||||
break;
|
||||
case 's': // ...strings.
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = "'".$conn->escapeString($v)."'";
|
||||
}
|
||||
$value = implode(', ', $value);
|
||||
break;
|
||||
case 'C': // ...columns.
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = $conn->escapeColumnName($v);
|
||||
}
|
||||
$value = implode(', ', $value);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown conversion %L{$next}.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$done) {
|
||||
_qsprintf_check_type($value, $type, $pattern);
|
||||
switch ($type) {
|
||||
case 's': // String
|
||||
if ($nullable && $value === null) {
|
||||
$value = 'NULL';
|
||||
} else {
|
||||
$value = "'".$conn->escapeString($value)."'";
|
||||
}
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case 'Q': // Query Fragment
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case '~': // Like Substring
|
||||
case '>': // Like Prefix
|
||||
case '<': // Like Suffix
|
||||
$value = $conn->escapeStringForLikeClause($value);
|
||||
switch ($type) {
|
||||
case '~': $value = "'%".$value."%'"; break;
|
||||
case '>': $value = "'" .$value."%'"; break;
|
||||
case '<': $value = "'%".$value. "'"; break;
|
||||
}
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case 'f': // Float
|
||||
if ($nullable && $value === null) {
|
||||
$value = 'NULL';
|
||||
} else {
|
||||
$value = (float)$value;
|
||||
}
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case 'd': // Integer
|
||||
if ($nullable && $value === null) {
|
||||
$value = 'NULL';
|
||||
} else {
|
||||
$value = (int)$value;
|
||||
}
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case 'T': // Table
|
||||
case 'C': // Column
|
||||
$value = $conn->escapeColumnName($value);
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
case 'K': // Komment
|
||||
$value = $conn->escapeMultilineComment($value);
|
||||
$type = 's';
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("Unknown conversion '%{$type}'.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ($prefix) {
|
||||
$value = $prefix.$value;
|
||||
}
|
||||
$pattern[$pos] = $type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function _qsprintf_check_type($value, $type, $query) {
|
||||
switch ($type) {
|
||||
case 'Ld': case 'Ls': case 'LC': case 'LA': case 'LO':
|
||||
if (!is_array($value)) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Expected array argument for %{$type} conversion.");
|
||||
}
|
||||
if (empty($value)) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Array for %{$type} conversion is empty.");
|
||||
}
|
||||
|
||||
foreach ($value as $scalar) {
|
||||
_qsprintf_check_scalar_type($scalar, $type, $query);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_qsprintf_check_scalar_type($value, $type, $query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function _qsprintf_check_scalar_type($value, $type, $query) {
|
||||
switch ($type) {
|
||||
case 'Q': case 'LC': case 'T': case 'C':
|
||||
if (!is_string($value)) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Expected a string for %{$type} conversion.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Ld': case 'd': case 'f':
|
||||
if (!is_null($value) && !is_scalar($value)) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Expected a scalar or null for %{$type} conversion.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Ls': case 's':
|
||||
case '~': case '>': case '<': case 'K':
|
||||
if (!is_null($value) && !is_scalar($value)) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Expected a scalar or null for %{$type} conversion.");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'LA': case 'LO':
|
||||
if (!is_null($value) && !is_scalar($value) &&
|
||||
!(is_array($value) && !empty($value))) {
|
||||
throw new AphrontQueryParameterException(
|
||||
$query,
|
||||
"Expected a scalar or null or non-empty array for ".
|
||||
"%{$type} conversion.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown conversion '{$type}'.");
|
||||
}
|
||||
}
|
13
src/storage/queryfx/__init__.php
Normal file
13
src/storage/queryfx/__init__.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'storage/exception/count');
|
||||
phutil_require_module('aphront', 'storage/qsprintf');
|
||||
|
||||
|
||||
phutil_require_source('queryfx.php');
|
58
src/storage/queryfx/queryfx.php
Normal file
58
src/storage/queryfx/queryfx.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function queryfx(AphrontDatabaseConnection $conn, $sql/*, ... */) {
|
||||
$argv = func_get_args();
|
||||
$query = call_user_func_array('qsprintf', $argv);
|
||||
return $conn->executeRawQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function vqueryfx($conn, $sql, $argv) {
|
||||
array_unshift($argv, $conn, $sql);
|
||||
return call_user_func_array('queryfx', $argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function queryfx_all($conn, $sql/*, ... */) {
|
||||
$argv = func_get_args();
|
||||
$ret = call_user_func_array('queryfx', $argv);
|
||||
return $conn->selectAllResults($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group storage
|
||||
*/
|
||||
function queryfx_one($conn, $sql/*, ... */) {
|
||||
$argv = func_get_args();
|
||||
$ret = call_user_func_array('queryfx_all', $argv);
|
||||
if (count($ret) > 1) {
|
||||
throw new AphrontQueryCountException(
|
||||
'Query returned more than one row.');
|
||||
} else if (count($ret)) {
|
||||
return reset($ret);
|
||||
}
|
||||
return null;
|
||||
}
|
52
src/view/base/AphrontView.php
Executable file
52
src/view/base/AphrontView.php
Executable file
|
@ -0,0 +1,52 @@
|
|||
<?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 AphrontView {
|
||||
|
||||
protected $children = array();
|
||||
|
||||
final public function appendChild($child) {
|
||||
$this->children[] = $child;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final protected function renderChildren() {
|
||||
$out = array();
|
||||
foreach ($this->children as $child) {
|
||||
$out[] = $this->renderChild($child);
|
||||
}
|
||||
return implode('', $out);
|
||||
}
|
||||
|
||||
private function renderChild($child) {
|
||||
if ($child instanceof AphrontView) {
|
||||
return $child->render();
|
||||
} else if (is_array($child)) {
|
||||
$out = array();
|
||||
foreach ($child as $element) {
|
||||
$out[] = $this->renderChild($element);
|
||||
}
|
||||
return implode('', $out);
|
||||
} else {
|
||||
return $child;
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function render();
|
||||
|
||||
}
|
10
src/view/base/__init__.php
Normal file
10
src/view/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('AphrontView.php');
|
134
src/view/control/table/AphrontTableView.php
Executable file
134
src/view/control/table/AphrontTableView.php
Executable file
|
@ -0,0 +1,134 @@
|
|||
<?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 AphrontTableView extends AphrontView {
|
||||
|
||||
protected $data;
|
||||
protected $headers;
|
||||
protected $rowClasses = array();
|
||||
protected $columnClasses = array();
|
||||
protected $zebraStripes = true;
|
||||
protected $noDataString;
|
||||
protected $className;
|
||||
|
||||
public function __construct(array $data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function setHeaders(array $headers) {
|
||||
$this->headers = $headers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setColumnClasses(array $column_classes) {
|
||||
$this->columnClasses = $column_classes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRowClasses(array $row_classes) {
|
||||
$this->rowClasses = $row_classes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setNoDataString($no_data_string) {
|
||||
$this->noDataString = $no_data_string;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClassName($class_name) {
|
||||
$this->className = $class_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setZebraStripes($zebra_stripes) {
|
||||
$this->zebraStripes = $zebra_stripes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$class = $this->className;
|
||||
if ($class !== null) {
|
||||
$class = ' class="aphront-table-view '.$class.'"';
|
||||
} else {
|
||||
$class = ' class="aphront-table-view"';
|
||||
}
|
||||
$table = array('<table'.$class.'>');
|
||||
|
||||
$col_classes = array();
|
||||
foreach ($this->columnClasses as $key => $class) {
|
||||
if (strlen($class)) {
|
||||
$col_classes[] = ' class="'.$class.'"';
|
||||
} else {
|
||||
$col_classes[] = null;
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->headers;
|
||||
if ($headers) {
|
||||
$table[] = '<tr>';
|
||||
foreach ($headers as $col_num => $header) {
|
||||
$class = idx($col_classes, $col_num);
|
||||
$table[] = '<th'.$class.'>'.$header.'</th>';
|
||||
}
|
||||
$table[] = '</tr>';
|
||||
}
|
||||
|
||||
$data = $this->data;
|
||||
if ($data) {
|
||||
$row_num = 0;
|
||||
foreach ($data as $row) {
|
||||
while (count($row) > count($col_classes)) {
|
||||
$col_classes[] = null;
|
||||
}
|
||||
$class = idx($this->rowClasses, $row_num);
|
||||
if ($this->zebraStripes && ($row_num % 2)) {
|
||||
if ($class !== null) {
|
||||
$class = 'alt alt-'.$class;
|
||||
} else {
|
||||
$class = 'alt';
|
||||
}
|
||||
}
|
||||
if ($class !== null) {
|
||||
$class = ' class="'.$class.'"';
|
||||
}
|
||||
$table[] = '<tr'.$class.'>';
|
||||
$col_num = 0;
|
||||
foreach ($row as $value) {
|
||||
$class = $col_classes[$col_num];
|
||||
if ($class !== null) {
|
||||
$table[] = '<td'.$class.'>';
|
||||
} else {
|
||||
$table[] = '<td>';
|
||||
}
|
||||
$table[] = $value.'</td>';
|
||||
++$col_num;
|
||||
}
|
||||
++$row_num;
|
||||
}
|
||||
} else {
|
||||
$colspan = max(count($headers), 1);
|
||||
$table[] =
|
||||
'<tr class="no-data"><td colspan="'.$colspan.'">'.
|
||||
coalesce($this->noDataString, 'No data available.').
|
||||
'</td></tr>';
|
||||
}
|
||||
$table[] = '</table>';
|
||||
return implode('', $table);
|
||||
}
|
||||
}
|
||||
|
14
src/view/control/table/__init__.php
Normal file
14
src/view/control/table/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontTableView.php');
|
90
src/view/dialog/AphrontDialogView.php
Executable file
90
src/view/dialog/AphrontDialogView.php
Executable file
|
@ -0,0 +1,90 @@
|
|||
<?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 AphrontDialogView extends AphrontView {
|
||||
|
||||
private $title;
|
||||
private $submitButton;
|
||||
private $cancelURI;
|
||||
private $submitURI;
|
||||
|
||||
public function setSubmitURI($uri) {
|
||||
$this->submitURI = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitle($title) {
|
||||
$this->title = $title;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function addSubmitButton($text = 'Okay') {
|
||||
$this->submitButton = $text;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addCancelButton($uri) {
|
||||
$this->cancelURI = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function render() {
|
||||
|
||||
$buttons = array();
|
||||
if ($this->submitButton) {
|
||||
$buttons[] =
|
||||
'<button name="__submit__">'.
|
||||
phutil_escape_html($this->submitButton).
|
||||
'</button>';
|
||||
}
|
||||
|
||||
if ($this->cancelURI) {
|
||||
$buttons[] = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $this->cancelURI,
|
||||
'class' => 'button grey',
|
||||
),
|
||||
'Cancel');
|
||||
}
|
||||
|
||||
return phutil_render_tag(
|
||||
'form',
|
||||
array(
|
||||
'class' => 'aphront-dialog-view',
|
||||
'action' => $this->submitURI,
|
||||
'method' => 'post',
|
||||
),
|
||||
'<input type="hidden" name="__form__" value="1" />'.
|
||||
'<div class="aphront-dialog-head">'.
|
||||
phutil_escape_html($this->title).
|
||||
'</div>'.
|
||||
'<div class="aphront-dialog-body">'.
|
||||
$this->renderChildren().
|
||||
'</div>'.
|
||||
'<div class="aphront-dialog-tail">'.
|
||||
implode('', $buttons).
|
||||
'<div style="clear: both;"></div>'.
|
||||
'</div>');
|
||||
}
|
||||
|
||||
}
|
14
src/view/dialog/__init__.php
Normal file
14
src/view/dialog/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontDialogView.php');
|
65
src/view/form/base/AphrontFormView.php
Executable file
65
src/view/form/base/AphrontFormView.php
Executable file
|
@ -0,0 +1,65 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class AphrontFormView extends AphrontView {
|
||||
|
||||
private $action;
|
||||
private $method = 'POST';
|
||||
private $header;
|
||||
private $data = array();
|
||||
|
||||
public function setAction($action) {
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMethod($method) {
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return phutil_render_tag(
|
||||
'form',
|
||||
array(
|
||||
'action' => $this->action,
|
||||
'method' => $this->method,
|
||||
'class' => 'aphront-form-view',
|
||||
),
|
||||
$this->renderDataInputs().
|
||||
$this->renderChildren());
|
||||
}
|
||||
|
||||
private function renderDataInputs() {
|
||||
$data = $this->data + array(
|
||||
'__form__' => 1,
|
||||
);
|
||||
$inputs = array();
|
||||
foreach ($data as $key => $value) {
|
||||
$inputs[] = phutil_render_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => $key,
|
||||
'value' => $value,
|
||||
));
|
||||
}
|
||||
return implode("\n", $inputs);
|
||||
}
|
||||
|
||||
}
|
14
src/view/form/base/__init__.php
Normal file
14
src/view/form/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('aphront', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormView.php');
|
127
src/view/form/control/base/AphrontFormControl.php
Executable file
127
src/view/form/control/base/AphrontFormControl.php
Executable file
|
@ -0,0 +1,127 @@
|
|||
<?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 AphrontFormControl extends AphrontView {
|
||||
|
||||
private $label;
|
||||
private $caption;
|
||||
private $error;
|
||||
private $name;
|
||||
private $value;
|
||||
|
||||
public function setLabel($label) {
|
||||
$this->label = $label;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLabel() {
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setCaption($caption) {
|
||||
$this->caption = $caption;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCaption() {
|
||||
return $this->caption;
|
||||
}
|
||||
|
||||
public function setError($error) {
|
||||
$this->error = $error;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getError() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setValue($value) {
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
abstract protected function renderInput();
|
||||
abstract protected function getCustomControlClass();
|
||||
|
||||
final public function render() {
|
||||
$custom_class = $this->getCustomControlClass();
|
||||
|
||||
if (strlen($this->getLabel())) {
|
||||
$label =
|
||||
'<label>'.
|
||||
phutil_escape_html($this->getLabel()).
|
||||
':'.
|
||||
'</label>';
|
||||
} else {
|
||||
$label = null;
|
||||
$custom_class .= ' aphront-form-control-nolabel';
|
||||
}
|
||||
|
||||
$input =
|
||||
'<div class="aphront-form-input">'.
|
||||
$this->renderInput().
|
||||
'</div>';
|
||||
|
||||
if (strlen($this->getError())) {
|
||||
$error = $this->getError();
|
||||
if ($error === true) {
|
||||
$error = '*';
|
||||
} else {
|
||||
$error = "\xC2\xAB ".$error;
|
||||
}
|
||||
$error =
|
||||
'<div class="aphront-form-error">'.
|
||||
phutil_escape_html($error).
|
||||
'</div>';
|
||||
} else {
|
||||
$error = null;
|
||||
}
|
||||
|
||||
if (strlen($this->getCaption())) {
|
||||
$caption =
|
||||
'<div class="aphront-form-caption">'.
|
||||
phutil_escape_html($this->getCaption()).
|
||||
'</div>';
|
||||
} else {
|
||||
$caption = null;
|
||||
}
|
||||
|
||||
return
|
||||
'<div class="aphront-form-control '.$custom_class.'">'.
|
||||
$error.
|
||||
$label.
|
||||
$input.
|
||||
$caption.
|
||||
'<div style="clear: both;"></div>'.
|
||||
'</div>';
|
||||
}
|
||||
}
|
14
src/view/form/control/base/__init__.php
Normal file
14
src/view/form/control/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('aphront', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormControl.php');
|
56
src/view/form/control/select/AphrontFormSelectControl.php
Executable file
56
src/view/form/control/select/AphrontFormSelectControl.php
Executable 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 AphrontFormSelectControl extends AphrontFormControl {
|
||||
|
||||
protected function getCustomControlClass() {
|
||||
return 'aphront-form-control-select';
|
||||
}
|
||||
|
||||
private $options;
|
||||
|
||||
public function setOptions(array $options) {
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOptions() {
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
$options = array();
|
||||
foreach ($this->getOptions() as $value => $label) {
|
||||
$options[] = phutil_render_tag(
|
||||
'option',
|
||||
array(
|
||||
'selected' => ($value == $this->getValue()) ? 'selected' : null,
|
||||
'value' => $value,
|
||||
),
|
||||
phutil_escape_html($label));
|
||||
}
|
||||
|
||||
return phutil_render_tag(
|
||||
'select',
|
||||
array(
|
||||
'name' => $this->getName(),
|
||||
),
|
||||
implode("\n", $options));
|
||||
}
|
||||
|
||||
}
|
14
src/view/form/control/select/__init__.php
Normal file
14
src/view/form/control/select/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'view/form/control/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormSelectControl.php');
|
48
src/view/form/control/submit/AphrontFormSubmitControl.php
Executable file
48
src/view/form/control/submit/AphrontFormSubmitControl.php
Executable file
|
@ -0,0 +1,48 @@
|
|||
<?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 AphrontFormSubmitControl extends AphrontFormControl {
|
||||
|
||||
protected $cancelButton;
|
||||
|
||||
public function addCancelButton($href, $label = 'Cancel') {
|
||||
$this->cancelButton = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
'class' => 'button grey',
|
||||
),
|
||||
phutil_escape_html($label));
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getCustomControlClass() {
|
||||
return 'aphront-form-control-submit';
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
return phutil_render_tag(
|
||||
'button',
|
||||
array(
|
||||
'name' => '__submit__',
|
||||
),
|
||||
phutil_escape_html($this->getValue())).
|
||||
$this->cancelButton;
|
||||
}
|
||||
|
||||
}
|
14
src/view/form/control/submit/__init__.php
Normal file
14
src/view/form/control/submit/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('aphront', 'view/form/control/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormSubmitControl.php');
|
35
src/view/form/control/text/AphrontFormTextControl.php
Executable file
35
src/view/form/control/text/AphrontFormTextControl.php
Executable file
|
@ -0,0 +1,35 @@
|
|||
<?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 AphrontFormTextControl extends AphrontFormControl {
|
||||
|
||||
protected function getCustomControlClass() {
|
||||
return 'aphront-form-control-text';
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
return phutil_render_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => $this->getName(),
|
||||
'value' => $this->getValue(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue