diff options
-rw-r--r-- | index.php | 25 | ||||
-rw-r--r-- | lib/action.php | 6 | ||||
-rw-r--r-- | lib/clientexception.php | 56 | ||||
-rw-r--r-- | lib/common.php | 10 | ||||
-rw-r--r-- | lib/event.php | 113 | ||||
-rw-r--r-- | lib/serverexception.php | 55 |
6 files changed, 257 insertions, 8 deletions
@@ -47,7 +47,10 @@ if (!$user && common_config('site', 'private') && $actionfile = INSTALLDIR."/actions/$action.php"; -if (file_exists($actionfile)) { +if (!file_exists($actionfile)) { + $cac = new ClientErrorAction(_('Unknown action'), 404); + $cac->showPage(); +} else { include_once $actionfile; @@ -66,9 +69,19 @@ if (file_exists($actionfile)) { } $config['db']['database'] = $mirror; } - if (call_user_func(array($action_obj, 'prepare'), $_REQUEST)) { - call_user_func(array($action_obj, 'handle'), $_REQUEST); + + try { + if ($action_obj->prepare($_REQUEST)) { + $action_obj->handle($_REQUEST); + } + } catch (ClientException $cex) { + $cac = new ClientErrorAction($cex->getMessage(), $cex->getCode()); + $cac->showPage(); + } catch (ServerException $sex) { // snort snort guffaw + $sac = new ServerErrorAction($sex->getMessage(), $sex->getCode()); + $sac->showPage(); + } catch (Exception $ex) { + $sac = new ServerErrorAction($ex->getMessage()); + $sac->showPage(); } -} else { - common_user_error(_('Unknown action')); -}
\ No newline at end of file +} diff --git a/lib/action.php b/lib/action.php index c4172ada1..9fbabb4fc 100644 --- a/lib/action.php +++ b/lib/action.php @@ -789,11 +789,12 @@ class Action extends HTMLOutputter // lawsuit * * @return nothing */ + function serverError($msg, $code=500) { $action = $this->trimmed('action'); common_debug("Server error '$code' on '$action': $msg", __FILE__); - common_server_error($msg, $code); + throw new ServerException($msg, $code); } /** @@ -804,11 +805,12 @@ class Action extends HTMLOutputter // lawsuit * * @return nothing */ + function clientError($msg, $code=400) { $action = $this->trimmed('action'); common_debug("User error '$code' on '$action': $msg", __FILE__); - common_user_error($msg, $code); + throw new ClientException($msg, $code); } /** diff --git a/lib/clientexception.php b/lib/clientexception.php new file mode 100644 index 000000000..3020d7f50 --- /dev/null +++ b/lib/clientexception.php @@ -0,0 +1,56 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * class for a client exception (user error) + * + * PHP version 5 + * + * LICENCE: This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2008 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Class for client exceptions + * + * Subclass of PHP Exception for user errors. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class ClientException extends Exception +{ + public function __construct($message = null, $code = 400) { + parent::__construct($message, $code); + } + + // custom string representation of object + public function __toString() { + return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; + } +} diff --git a/lib/common.php b/lib/common.php index 5b4e3c40c..64c7f2410 100644 --- a/lib/common.php +++ b/lib/common.php @@ -49,6 +49,11 @@ require_once('DB/DataObject/Cast.php'); # for dates require_once(INSTALLDIR.'/lib/language.php'); +// This gets included before the config file, so that admin code and plugins +// can use it + +require_once(INSTALLDIR.'/lib/event.php'); + // try to figure out where we are $_server = array_key_exists('SERVER_NAME', $_SERVER) ? @@ -177,6 +182,8 @@ foreach ($_config_files as $_config_file) { } } +// XXX: how many of these could be auto-loaded on use? + require_once('Validate.php'); require_once('markdown.php'); @@ -188,6 +195,9 @@ require_once(INSTALLDIR.'/lib/subs.php'); require_once(INSTALLDIR.'/lib/Shorturl_api.php'); require_once(INSTALLDIR.'/lib/twitter.php'); +require_once(INSTALLDIR.'/lib/clientexception.php'); +require_once(INSTALLDIR.'/lib/serverexception.php'); + // XXX: other formats here define('NICKNAME_FMT', VALIDATE_NUM.VALIDATE_ALPHA_LOWER); diff --git a/lib/event.php b/lib/event.php new file mode 100644 index 000000000..f5406d07a --- /dev/null +++ b/lib/event.php @@ -0,0 +1,113 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * utilities for defining and running event handlers + * + * PHP version 5 + * + * LICENCE: This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category Event + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2008 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Class for events + * + * This "class" two static functions for managing events in the Laconica code. + * + * @category Event + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @todo Define a system for using Event instances + */ + +class Event { + + /* Global array of hooks, mapping eventname => array of callables */ + + protected static $_handlers = array(); + + /** + * Add an event handler + * + * To run some code at a particular point in Laconica processing. + * Named events include receiving an XMPP message, adding a new notice, + * or showing part of an HTML page. + * + * The arguments to the handler vary by the event. Handlers can return + * two possible values: false means that the event has been replaced by + * the handler completely, and no default processing should be done. + * Non-false means successful handling, and that the default processing + * should succeed. (Note that this only makes sense for some events.) + * + * Handlers can also abort processing by throwing an exception; these will + * be caught by the closest code and displayed as errors. + * + * @param string $name Name of the event + * @param callable $handler Code to run + * + * @return void + */ + + public static function addHandler($name, $handler) { + if (array_key_exists($name, Event::$_handlers)) { + Event::$_handlers[$name][] = $handler; + } else { + Event::$_handlers[$name] = array($handler); + } + } + + /** + * Handle an event + * + * Events are any point in the code that we want to expose for admins + * or third-party developers to use. + * + * We pass in an array of arguments (including references, for stuff + * that can be changed), and each assigned handler gets run with those + * arguments. Exceptions can be thrown to indicate an error. + * + * @param string $name Name of the event that's happening + * @param array $args Arguments for handlers + * + * @return boolean flag saying whether to continue processing, based + * on results of handlers. + */ + + public static function handle($name, $args) { + $result = null; + if (array_key_exists($name, Event::$_handlers)) { + foreach (Event::$_handlers[$name] as $handler) { + $result = call_user_func_array($handler, $args); + if ($result === false) { + break; + } + } + } + return ($result === false); + } +} diff --git a/lib/serverexception.php b/lib/serverexception.php new file mode 100644 index 000000000..b8ed6846e --- /dev/null +++ b/lib/serverexception.php @@ -0,0 +1,55 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * class for a server exception (user error) + * + * PHP version 5 + * + * LICENCE: This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2008 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * Class for server exceptions + * + * Subclass of PHP Exception for server errors. The user typically can't fix these. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +class ServerException extends Exception +{ + public function __construct($message = null, $code = 400) { + parent::__construct($message, $code); + } + + public function __toString() { + return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; + } +} |