From a64a88860908429a2e2297565f292ebdfe68415f Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Sat, 7 Feb 2009 23:47:37 +0000 Subject: Using rel="external" instead of class="exlink" --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index 7ce4e229e..c5a092f63 100644 --- a/lib/util.php +++ b/lib/util.php @@ -478,7 +478,7 @@ function common_linkify($url) { } else $title = ''; - return "$display"; + return "$display"; } function common_longurl($short_url) -- cgit v1.2.3-54-g00ecf From b1f9dec20e0a6c9c25fe873bffa81e632f2fc146 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 06:51:08 -0500 Subject: First events code Add the basic code for adding events. --- lib/event.php | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 lib/event.php (limited to 'lib') 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 @@ +. + * + * @category Event + * @package Laconica + * @author Evan Prodromou + * @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 + * @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); + } +} -- cgit v1.2.3-54-g00ecf From 12d7c30ef79c5ad84b7bac5e4863db3ce4e23621 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 06:52:39 -0500 Subject: Add event.php before config.php is called --- lib/common.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/common.php b/lib/common.php index 5b4e3c40c..7d3ec108c 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) ? -- cgit v1.2.3-54-g00ecf From 9152c0bdc8e23ca0ff03c72c5891d3db9c5e9d4f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 07:12:08 -0500 Subject: First steps to using exceptions for error handling Added two exception classes: one for client errors (= user can fix) and one for server errors (only admin or coder can fix). The web entry point now tries to catch exceptions and show them in the browser. The main code for showing errors in Action class now throws an exception and lets top-level handle it. --- lib/clientexception.php | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/serverexception.php | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 lib/clientexception.php create mode 100644 lib/serverexception.php (limited to 'lib') 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 @@ +. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou + * @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 + * @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/serverexception.php b/lib/serverexception.php new file mode 100644 index 000000000..b8ed6846e --- /dev/null +++ b/lib/serverexception.php @@ -0,0 +1,55 @@ +. + * + * @category Exception + * @package Laconica + * @author Evan Prodromou + * @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 + * @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"; + } +} -- cgit v1.2.3-54-g00ecf From aa06d760b375c0cc9bbc693bf4bd412e9fda8f50 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 07:15:52 -0500 Subject: Index and Action use Exceptions Main Web entry point accepts exceptions, and main code in Action throws them. --- index.php | 29 +++++++++++++++++++++++------ lib/action.php | 6 ++++-- 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/index.php b/index.php index 387b642e2..075ee9676 100644 --- a/index.php +++ b/index.php @@ -47,7 +47,11 @@ if (!$user && common_config('site', 'private') && $actionfile = INSTALLDIR."/actions/$action.php"; -if (file_exists($actionfile)) { +if (!file_exists($actionfile)) { + $cac = new ClientErrorAction(); + $cac->handle(array('code' => 404, + 'message' => _('Unknown action'))); +} else { include_once $actionfile; @@ -66,9 +70,22 @@ 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(); + $cac->handle(array('code' => $cex->code, + 'message' => $cex->message)); + } catch (ServerException sex) { // snort snort guffaw + $sac = new ServerErrorAction(); + $sac->handle(array('code' => $sex->code, + 'message' => $sex->message)); + } catch (Exception ex) { + $sac = new ServerErrorAction(); + $sac->handle(array('code' => 500, + 'message' => $ex->message)); } -} 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); } /** -- cgit v1.2.3-54-g00ecf From 5466f6a6d0950331a4cb54e09b44ea4524751fb4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 07:25:35 -0500 Subject: Better exception handling in index Some better exception handling in Web entry point. --- index.php | 26 +++++++++++--------------- lib/common.php | 5 +++++ 2 files changed, 16 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/index.php b/index.php index 075ee9676..dac5a8071 100644 --- a/index.php +++ b/index.php @@ -48,9 +48,8 @@ if (!$user && common_config('site', 'private') && $actionfile = INSTALLDIR."/actions/$action.php"; if (!file_exists($actionfile)) { - $cac = new ClientErrorAction(); - $cac->handle(array('code' => 404, - 'message' => _('Unknown action'))); + $cac = new ClientErrorAction(_('Unknown action'), 404); + $cac->showPage(); } else { include_once $actionfile; @@ -75,17 +74,14 @@ if (!file_exists($actionfile)) { if ($action_obj->prepare($_REQUEST)) { $action_obj->handle($_REQUEST); } - } catch (ClientException cex) { - $cac = new ClientErrorAction(); - $cac->handle(array('code' => $cex->code, - 'message' => $cex->message)); - } catch (ServerException sex) { // snort snort guffaw - $sac = new ServerErrorAction(); - $sac->handle(array('code' => $sex->code, - 'message' => $sex->message)); - } catch (Exception ex) { - $sac = new ServerErrorAction(); - $sac->handle(array('code' => 500, - 'message' => $ex->message)); + } 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(); } } diff --git a/lib/common.php b/lib/common.php index 7d3ec108c..64c7f2410 100644 --- a/lib/common.php +++ b/lib/common.php @@ -182,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'); @@ -193,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); -- cgit v1.2.3-54-g00ecf From 55cba5007e37245de1059b3de4774040850076c2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 07:51:23 -0500 Subject: Fix indentation in lib/action.php --- lib/action.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/action.php b/lib/action.php index 9fbabb4fc..e905b091e 100644 --- a/lib/action.php +++ b/lib/action.php @@ -329,10 +329,10 @@ class Action extends HTMLOutputter // lawsuit if (common_config('xmpp', 'enabled')) { $this->menuItem(common_local_url('imsettings'), - _('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect'); + _('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect'); } else { $this->menuItem(common_local_url('smssettings'), - _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); + _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); } $this->menuItem(common_local_url('logout'), _('Logout'), _('Logout from the site'), false, 'nav_logout'); -- cgit v1.2.3-54-g00ecf From e40d503dfb1b929c7e91422e7ee103a2cf37288d Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:02:08 -0500 Subject: had the logic on event handler reversed --- lib/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/event.php b/lib/event.php index f5406d07a..10ef5ec0a 100644 --- a/lib/event.php +++ b/lib/event.php @@ -108,6 +108,6 @@ class Event { } } } - return ($result === false); + return ($result !== false); } } -- cgit v1.2.3-54-g00ecf From 05991e2206cab8008a981411b35224b9cd86fce7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:02:23 -0500 Subject: First events for adding menu items --- lib/action.php | 89 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 41 deletions(-) (limited to 'lib') diff --git a/lib/action.php b/lib/action.php index e905b091e..36f598c57 100644 --- a/lib/action.php +++ b/lib/action.php @@ -312,42 +312,46 @@ class Action extends HTMLOutputter // lawsuit */ function showPrimaryNav() { + $user = common_current_user(); + $this->elementStart('dl', array('id' => 'site_nav_global_primary')); $this->element('dt', null, _('Primary site navigation')); $this->elementStart('dd'); - $user = common_current_user(); $this->elementStart('ul', array('class' => 'nav')); - if ($user) { - $this->menuItem(common_local_url('all', array('nickname' => $user->nickname)), - _('Home'), _('Personal profile and friends timeline'), false, 'nav_home'); - } - $this->menuItem(common_local_url('peoplesearch'), - _('Search'), _('Search for people or text'), false, 'nav_search'); - if ($user) { - $this->menuItem(common_local_url('profilesettings'), - _('Account'), _('Change your email, avatar, password, profile'), false, 'nav_account'); - - if (common_config('xmpp', 'enabled')) { - $this->menuItem(common_local_url('imsettings'), - _('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect'); - } else { - $this->menuItem(common_local_url('smssettings'), - _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); + if (Event::handle('StartPrimaryNav', array($this))) { + if ($user) { + $this->menuItem(common_local_url('all', array('nickname' => $user->nickname)), + _('Home'), _('Personal profile and friends timeline'), false, 'nav_home'); } - $this->menuItem(common_local_url('logout'), - _('Logout'), _('Logout from the site'), false, 'nav_logout'); - } else { - $this->menuItem(common_local_url('login'), - _('Login'), _('Login to the site'), false, 'nav_login'); - if (!common_config('site', 'closed')) { - $this->menuItem(common_local_url('register'), - _('Register'), _('Create an account'), false, 'nav_register'); + $this->menuItem(common_local_url('peoplesearch'), + _('Search'), _('Search for people or text'), false, 'nav_search'); + if ($user) { + $this->menuItem(common_local_url('profilesettings'), + _('Account'), _('Change your email, avatar, password, profile'), false, 'nav_account'); + + if (common_config('xmpp', 'enabled')) { + $this->menuItem(common_local_url('imsettings'), + _('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect'); + } else { + $this->menuItem(common_local_url('smssettings'), + _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); + } + $this->menuItem(common_local_url('logout'), + _('Logout'), _('Logout from the site'), false, 'nav_logout'); + } else { + $this->menuItem(common_local_url('login'), + _('Login'), _('Login to the site'), false, 'nav_login'); + if (!common_config('site', 'closed')) { + $this->menuItem(common_local_url('register'), + _('Register'), _('Create an account'), false, 'nav_register'); + } + $this->menuItem(common_local_url('openidlogin'), + _('OpenID'), _('Login with OpenID'), false, 'nav_openid'); } - $this->menuItem(common_local_url('openidlogin'), - _('OpenID'), _('Login with OpenID'), false, 'nav_openid'); + $this->menuItem(common_local_url('doc', array('title' => 'help')), + _('Help'), _('Help me!'), false, 'nav_help'); + Event::handle('EndPrimaryNav', array($this)); } - $this->menuItem(common_local_url('doc', array('title' => 'help')), - _('Help'), _('Help me!'), false, 'nav_help'); $this->elementEnd('ul'); $this->elementEnd('dd'); $this->elementEnd('dl'); @@ -570,18 +574,21 @@ class Action extends HTMLOutputter // lawsuit $this->element('dt', null, _('Secondary site navigation')); $this->elementStart('dd', null); $this->elementStart('ul', array('class' => 'nav')); - $this->menuItem(common_local_url('doc', array('title' => 'help')), - _('Help')); - $this->menuItem(common_local_url('doc', array('title' => 'about')), - _('About')); - $this->menuItem(common_local_url('doc', array('title' => 'faq')), - _('FAQ')); - $this->menuItem(common_local_url('doc', array('title' => 'privacy')), - _('Privacy')); - $this->menuItem(common_local_url('doc', array('title' => 'source')), - _('Source')); - $this->menuItem(common_local_url('doc', array('title' => 'contact')), - _('Contact')); + if (Event::handle('StartSecondaryNav', array($this))) { + $this->menuItem(common_local_url('doc', array('title' => 'help')), + _('Help')); + $this->menuItem(common_local_url('doc', array('title' => 'about')), + _('About')); + $this->menuItem(common_local_url('doc', array('title' => 'faq')), + _('FAQ')); + $this->menuItem(common_local_url('doc', array('title' => 'privacy')), + _('Privacy')); + $this->menuItem(common_local_url('doc', array('title' => 'source')), + _('Source')); + $this->menuItem(common_local_url('doc', array('title' => 'contact')), + _('Contact')); + Event::handle('EndSecondaryNav', array($this)); + } $this->elementEnd('ul'); $this->elementEnd('dd'); $this->elementEnd('dl'); -- cgit v1.2.3-54-g00ecf From 5d246299b630c55d98cc03eeb650561defbeeff4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:24:23 -0500 Subject: add hooks for JavaScript handling --- EVENTS.txt | 20 ++++++++++++++++++++ lib/action.php | 33 +++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/EVENTS.txt b/EVENTS.txt index bd511d75e..68e25fa3b 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -9,3 +9,23 @@ StartSecondaryNav: Showing the secondary nav menu EndSecondaryNav: At the end of the secondary nav menu - $action: the current action + +StartShowScripts: Showing JavaScript links +- $action: the current action + +EndShowScripts: End showing JavaScript links; good place to add custom + links like Google Analytics +- $action: the current action + +StartShowJQueryScripts: Showing JQuery script links (use this to link to e.g. Google mirrors) +- $action: the current action + +EndShowJQueryScripts: End showing JQuery script links +- $action: the current action + +StartShowLaconicaScripts: Showing Laconica script links (use this to link to a CDN or something) +- $action: the current action + +EndShowLaconicaScripts: End showing Laconica script links +- $action: the current action + diff --git a/lib/action.php b/lib/action.php index 36f598c57..0628dc70d 100644 --- a/lib/action.php +++ b/lib/action.php @@ -179,18 +179,27 @@ class Action extends HTMLOutputter // lawsuit */ function showScripts() { - $this->element('script', array('type' => 'text/javascript', - 'src' => common_path('js/jquery.min.js')), - ' '); - $this->element('script', array('type' => 'text/javascript', - 'src' => common_path('js/jquery.form.js')), - ' '); - $this->element('script', array('type' => 'text/javascript', - 'src' => common_path('js/xbImportNode.js')), - ' '); - $this->element('script', array('type' => 'text/javascript', - 'src' => common_path('js/util.js?version='.LACONICA_VERSION)), - ' '); + if (Event::handle('StartShowScripts', array($this))) { + if (Event::handle('StartShowJQueryScripts', array($this))) { + $this->element('script', array('type' => 'text/javascript', + 'src' => common_path('js/jquery.min.js')), + ' '); + $this->element('script', array('type' => 'text/javascript', + 'src' => common_path('js/jquery.form.js')), + ' '); + Event::handle('EndShowJQueryScripts', array($this)); + } + if (Event::handle('StartShowLaconicaScripts', array($this))) { + $this->element('script', array('type' => 'text/javascript', + 'src' => common_path('js/xbImportNode.js')), + ' '); + $this->element('script', array('type' => 'text/javascript', + 'src' => common_path('js/util.js?version='.LACONICA_VERSION)), + ' '); + Event::handle('EndShowLaconicaScripts', array($this)); + } + Event::handle('EndShowScripts', array($this)); + } } /** -- cgit v1.2.3-54-g00ecf From f4e8cc6d9f88e78876baa54d0ffba77694c56a1b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:44:30 -0500 Subject: Add InitializePlugin and CleanupPlugin events We add two events to allow plugins to initialize and cleanup. --- EVENTS.txt | 5 +++++ index.php | 5 +++++ lib/common.php | 4 ++++ 3 files changed, 14 insertions(+) (limited to 'lib') diff --git a/EVENTS.txt b/EVENTS.txt index 68e25fa3b..4b8260b3c 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -1,3 +1,8 @@ +InitializePlugin: a chance to initialize a plugin in a complete + environment + +CleanupPlugin: a chance to cleanup a plugin at the end of a program + StartPrimaryNav: Showing the primary nav menu - $action: the current action diff --git a/index.php b/index.php index dac5a8071..0a79b9731 100644 --- a/index.php +++ b/index.php @@ -85,3 +85,8 @@ if (!file_exists($actionfile)) { $sac->showPage(); } } + +// XXX: cleanup exit() calls or add an exit handler so +// this always gets called + +Event::handle('CleanupPlugin'); diff --git a/lib/common.php b/lib/common.php index 64c7f2410..2f85eb7c5 100644 --- a/lib/common.php +++ b/lib/common.php @@ -212,3 +212,7 @@ function __autoload($class) require_once(INSTALLDIR.'/lib/' . strtolower($class) . '.php'); } } + +// Give plugins a chance to initialize in a fully-prepared environment + +Event::handle('InitializePlugin'); -- cgit v1.2.3-54-g00ecf From 175f1e73950ab80c799944af8f69391113906394 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:47:11 -0500 Subject: utility superclass for plugins --- lib/plugin.php | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 lib/plugin.php (limited to 'lib') diff --git a/lib/plugin.php b/lib/plugin.php new file mode 100644 index 000000000..7b2436e54 --- /dev/null +++ b/lib/plugin.php @@ -0,0 +1,79 @@ +. + * + * @category Plugin + * @package Laconica + * @author Evan Prodromou + * @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); +} + +/** + * Base class for plugins + * + * A base class for Laconica plugins. Mostly a light wrapper around + * the Event framework. + * + * Subclasses of Plugin will automatically handle an event if they define + * a method called "onEventName". (Well, OK -- only if they call parent::__construct() + * in their constructors.) + * + * They will also automatically handle the InitializePlugin and CleanupPlugin with the + * initialize() and cleanup() methods, respectively. + * + * @category Plugin + * @package Laconica + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see Event + */ + +class Plugin +{ + function __construct() + { + Event::addHandler('InitializePlugin', array($this, 'initialize')); + Event::addHandler('CleanupPlugin', array($this, 'cleanup')); + + foreach (get_class_methods($this) as $method) { + if (mb_substr($method, 0, 2) == 'on') { + Event::addHandler(mb_substr($method, 2), array($this, $method)); + } + } + } + + function initialize() + { + return true; + } + + function cleanup() + { + return true; + } +} -- cgit v1.2.3-54-g00ecf From dce975e33b95e455c671207054a1d4c0237e075f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:48:50 -0500 Subject: allow events without arguments --- lib/event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/event.php b/lib/event.php index 10ef5ec0a..d815ae54b 100644 --- a/lib/event.php +++ b/lib/event.php @@ -98,7 +98,7 @@ class Event { * on results of handlers. */ - public static function handle($name, $args) { + public static function handle($name, $args=array()) { $result = null; if (array_key_exists($name, Event::$_handlers)) { foreach (Event::$_handlers[$name] as $handler) { -- cgit v1.2.3-54-g00ecf From ee4ee388ff6d66e2e6198ec1b5d1100733b63fd8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 08:49:28 -0500 Subject: include plugin.php early so config can use it --- lib/common.php | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/common.php b/lib/common.php index 2f85eb7c5..041459cf3 100644 --- a/lib/common.php +++ b/lib/common.php @@ -53,6 +53,7 @@ require_once(INSTALLDIR.'/lib/language.php'); // can use it require_once(INSTALLDIR.'/lib/event.php'); +require_once(INSTALLDIR.'/lib/plugin.php'); // try to figure out where we are -- cgit v1.2.3-54-g00ecf From 43888b523919f816e45a956a2e9f7d10416067df Mon Sep 17 00:00:00 2001 From: Robin Millette Date: Mon, 9 Feb 2009 15:35:38 +0000 Subject: trac #1160 fix dropdown xmloutput function for the selected attribute and fix newmessage auto-selected dropdown. --- actions/newmessage.php | 2 +- lib/htmloutputter.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/actions/newmessage.php b/actions/newmessage.php index f83015a37..82276ff34 100644 --- a/actions/newmessage.php +++ b/actions/newmessage.php @@ -201,7 +201,7 @@ class NewmessageAction extends Action function showNoticeForm() { - $message_form = new MessageForm($this, $this->to, $this->content); + $message_form = new MessageForm($this, $this->other, $this->content); $message_form->show(); } } diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index 7780b1c19..e2319b1fd 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -255,7 +255,7 @@ class HTMLOutputter extends XMLOutputter foreach ($content as $value => $option) { if ($value == $selected) { $this->element('option', array('value' => $value, - 'selected' => $value), + 'selected' => 'selected'), $option); } else { $this->element('option', array('value' => $value), $option); -- cgit v1.2.3-54-g00ecf From 9e23b5c5d706f4573261d6530688a44a8b80bcf4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 11:46:26 -0500 Subject: Change action autoloading to allow actions in plugins Since plugins may define custom actions, we shouldn't require that there be a file in our actions/ subdir for every action. So, I changed the (admittedly hackish) auto-loading code in index.php so it instead checks whether a class exists with the expected name. This, in turn, uses the increasingly hacking __autoload() function, which I changed to auto-load stuff named "BlahblahAction" from the actions subdir if available. --- index.php | 13 ++++++------- lib/common.php | 3 +++ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/index.php b/index.php index 0a79b9731..e62d9469a 100644 --- a/index.php +++ b/index.php @@ -22,6 +22,8 @@ define('LACONICA', true); require_once INSTALLDIR . '/lib/common.php'; +// XXX: we need a little more structure in this script + // get and cache current user $user = common_current_user(); @@ -45,19 +47,16 @@ if (!$user && common_config('site', 'private') && common_redirect(common_local_url('login')); } -$actionfile = INSTALLDIR."/actions/$action.php"; +$action_class = ucfirst($action).'Action'; -if (!file_exists($actionfile)) { +if (!class_exists($action_class)) { $cac = new ClientErrorAction(_('Unknown action'), 404); $cac->showPage(); } else { - - include_once $actionfile; - - $action_class = ucfirst($action).'Action'; - $action_obj = new $action_class(); + // XXX: find somewhere for this little block to live + if ($config['db']['mirror'] && $action_obj->isReadOnly()) { if (is_array($config['db']['mirror'])) { // "load balancing", ha ha diff --git a/lib/common.php b/lib/common.php index 041459cf3..7bfd14c42 100644 --- a/lib/common.php +++ b/lib/common.php @@ -211,6 +211,9 @@ function __autoload($class) require_once(INSTALLDIR.'/classes/' . $class . '.php'); } else if (file_exists(INSTALLDIR.'/lib/' . strtolower($class) . '.php')) { require_once(INSTALLDIR.'/lib/' . strtolower($class) . '.php'); + } else if (mb_substr($class, -6) == 'Action' && + file_exists(INSTALLDIR.'/actions/' . strtolower(mb_substr($class, 0, -6)) . '.php')) { + require_once(INSTALLDIR.'/actions/' . strtolower(mb_substr($class, 0, -6)) . '.php'); } } -- cgit v1.2.3-54-g00ecf From c1bc77efd968aecd465fb6173d20bd386016eae2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 12:06:06 -0500 Subject: whitespace and formatting --- lib/imagefile.php | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'lib') diff --git a/lib/imagefile.php b/lib/imagefile.php index ea24029a3..0c93b257e 100644 --- a/lib/imagefile.php +++ b/lib/imagefile.php @@ -68,17 +68,17 @@ class ImageFile static function fromUpload($param='upload') { switch ($_FILES[$param]['error']) { - case UPLOAD_ERR_OK: // success, jump out + case UPLOAD_ERR_OK: // success, jump out break; - case UPLOAD_ERR_INI_SIZE: - case UPLOAD_ERR_FORM_SIZE: + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'), $this->maxFileSize())); return; - case UPLOAD_ERR_PARTIAL: + case UPLOAD_ERR_PARTIAL: @unlink($_FILES[$param]['tmp_name']); throw new Exception(_('Partial upload.')); return; - default: + default: throw new Exception(_('System error uploading file.')); return; } @@ -112,19 +112,19 @@ class ImageFile throw new Exception(_('Lost our file.')); return; } - + // Don't crop/scale if it isn't necessary - if ($size === $this->width - && $size === $this->height - && $x === 0 - && $y === 0 + if ($size === $this->width + && $size === $this->height + && $x === 0 + && $y === 0 && $w === $this->width && $h === $this->height) { - + $outname = Avatar::filename($this->id, - image_type_to_extension($this->type), - $size, - common_timestamp()); + image_type_to_extension($this->type), + $size, + common_timestamp()); $outpath = Avatar::path($outname); @copy($this->filepath, $outpath); return $outname; @@ -171,9 +171,9 @@ class ImageFile imagecopyresampled($image_dest, $image_src, 0, 0, $x, $y, $size, $size, $w, $h); $outname = Avatar::filename($this->id, - image_type_to_extension($this->type), - $size, - common_timestamp()); + image_type_to_extension($this->type), + $size, + common_timestamp()); $outpath = Avatar::path($outname); @@ -191,7 +191,7 @@ class ImageFile throw new Exception(_('Unknown file type')); return; } - + imagedestroy($image_src); imagedestroy($image_dest); @@ -229,12 +229,12 @@ class ImageFile $num = substr($str, 0, -1); switch(strtoupper($unit)){ - case 'G': - $num *= 1024; - case 'M': - $num *= 1024; - case 'K': - $num *= 1024; + case 'G': + $num *= 1024; + case 'M': + $num *= 1024; + case 'K': + $num *= 1024; } return $num; -- cgit v1.2.3-54-g00ecf From 32744124bcb8aa0683490a56defd4a79f072d278 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 9 Feb 2009 16:56:38 -0500 Subject: Add a hook for showing sidebar sections --- EVENTS.txt | 5 +++++ lib/action.php | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/EVENTS.txt b/EVENTS.txt index 4b8260b3c..d9634325d 100644 --- a/EVENTS.txt +++ b/EVENTS.txt @@ -34,3 +34,8 @@ StartShowLaconicaScripts: Showing Laconica script links (use this to link to a C EndShowLaconicaScripts: End showing Laconica script links - $action: the current action +StartShowSections: Start the list of sections in the sidebar +- $action: the current action + +EndShowSections: End the list of sections in the sidebar +- $action: the current action diff --git a/lib/action.php b/lib/action.php index 0628dc70d..ce92addf5 100644 --- a/lib/action.php +++ b/lib/action.php @@ -524,12 +524,16 @@ class Action extends HTMLOutputter // lawsuit * * @return nothing */ + function showAside() { $this->elementStart('div', array('id' => 'aside_primary', 'class' => 'aside')); $this->showExportData(); - $this->showSections(); + if (Event::handle('StartShowSections', array($this))) { + $this->showSections(); + Event::handle('EndShowSections', array($this)); + } $this->elementEnd('div'); } -- cgit v1.2.3-54-g00ecf