1
0
Fork 0
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:
epriestley 2011-01-16 13:51:39 -08:00
parent 081689d61a
commit 76258ce0e1
116 changed files with 6203 additions and 0 deletions

10
.arcconfig Normal file
View 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
View file

@ -0,0 +1,7 @@
{
"name" : "differential",
"src_base" : "https://github.com/facebook/differential/blob/master",
"groups" : {
}
}

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.DS_Store
._*
/docs/

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

View 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(
),
));

View file

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

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

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

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

View file

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

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

View file

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

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

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

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontURIMapper.php');

View 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();
}
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontRequest.php');

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

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

View 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();
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontResponse.php');

View 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();
}
}

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

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

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

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

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

View 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();
}

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

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

View file

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

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

View file

@ -0,0 +1,25 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class AphrontDirectoryDAO extends AphrontLiskDAO {
public function getApplicationName() {
return 'directory';
}
}

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

View file

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

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

View file

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

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

View 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"';
}
}
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('DifferentialAction.php');

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

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

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

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('DifferentialLintStatus.php');

View file

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

View 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('DifferentialRevisionStatus.php');

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

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('DifferentialUnitStatus.php');

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

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

View 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}");
}
}
}

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

View 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 { }

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontQueryException.php');

View 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 AphrontQueryConnectionException extends AphrontQueryException { }

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

View file

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

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

View 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 { }

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

View 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 AphrontQueryObjectMissingException extends AphrontQueryException { }

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

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

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

View 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 AphrontQueryRecoverableException extends AphrontQueryException { }

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

File diff suppressed because it is too large Load diff

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

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

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

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

View 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
View 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();
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontView.php');

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

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

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

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

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

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

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

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

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

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

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

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

View 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