diff options
Diffstat (limited to 'engine/handlers')
-rw-r--r-- | engine/handlers/action_handler.php | 20 | ||||
-rw-r--r-- | engine/handlers/cache_handler.php | 105 | ||||
-rw-r--r-- | engine/handlers/export_handler.php | 118 | ||||
-rw-r--r-- | engine/handlers/page_handler.php | 48 | ||||
-rw-r--r-- | engine/handlers/service_handler.php | 27 | ||||
-rw-r--r-- | engine/handlers/xml-rpc_handler.php | 44 |
6 files changed, 362 insertions, 0 deletions
diff --git a/engine/handlers/action_handler.php b/engine/handlers/action_handler.php new file mode 100644 index 000000000..bcad110b2 --- /dev/null +++ b/engine/handlers/action_handler.php @@ -0,0 +1,20 @@ +<?php +/** + * Action handler. + * + * This file dispatches actions. It is called via a URL rewrite in .htaccess + * from http://site/action/. Anything after 'action/' is considered the action + * and will be passed to {@link action()}. + * + * @warning This sets the input named 'action' to the current action. When calling + * an action, get_input('action') will always return the action name. + * + * @package Elgg.Core + * @subpackage Actions + * @link http://docs.elgg.org/Tutorials/Actions + */ + +require_once(dirname(dirname(__FILE__)) . "/start.php"); + +$action = get_input("action"); +action($action); diff --git a/engine/handlers/cache_handler.php b/engine/handlers/cache_handler.php new file mode 100644 index 000000000..36fc665bb --- /dev/null +++ b/engine/handlers/cache_handler.php @@ -0,0 +1,105 @@ +<?php +/** + * Cache handler. + * + * External access to cached CSS and JavaScript views. The cached file URLS + * should be of the form: cache/<type>/<viewtype>/<name/of/view>.<unique_id>.<type> where + * type is either css or js, view is the name of the cached view, and + * unique_id is an identifier that is updated every time the cache is flushed. + * The simplest way to maintain a unique identifier is to use the lastcache + * variable in Elgg's config object. + * + * @see elgg_register_simplecache_view() + * + * @package Elgg.Core + * @subpackage Cache + */ + +// Get dataroot +require_once(dirname(dirname(__FILE__)) . '/settings.php'); +$mysql_dblink = mysql_connect($CONFIG->dbhost, $CONFIG->dbuser, $CONFIG->dbpass, true); +if (!$mysql_dblink) { + echo 'Cache error: unable to connect to database server'; + exit; +} + +if (!mysql_select_db($CONFIG->dbname, $mysql_dblink)) { + echo 'Cache error: unable to connect to Elgg database'; + exit; +} + +$query = "select name, value from {$CONFIG->dbprefix}datalists + where name in ('dataroot', 'simplecache_enabled')"; + +$result = mysql_query($query, $mysql_dblink); +if (!$result) { + echo 'Cache error: unable to get the data root'; + exit; +} +while ($row = mysql_fetch_object($result)) { + ${$row->name} = $row->value; +} +mysql_free_result($result); + + +$dirty_request = $_GET['request']; +// only alphanumeric characters plus /, ., and _ and no '..' +$filter = array("options" => array("regexp" => "/^(\.?[_a-zA-Z0-9\/]+)+$/")); +$request = filter_var($dirty_request, FILTER_VALIDATE_REGEXP, $filter); +if (!$request || !$simplecache_enabled) { + echo 'Cache error: bad request'; + exit; +} + +// testing showed regex to be marginally faster than array / string functions over 100000 reps +// it won't make a difference in real life and regex is easier to read. +// <type>/<viewtype>/<name/of/view.and.dots>.<ts>.<type> +$regex = '|([^/]+)/([^/]+)/(.+)\.([^\.]+)\.([^.]+)$|'; +preg_match($regex, $request, $matches); + +$type = $matches[1]; +$viewtype = $matches[2]; +$view = $matches[3]; +$ts = $matches[4]; + +// If is the same ETag, content didn't changed. +$etag = $ts; +if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == "\"$etag\"") { + header("HTTP/1.1 304 Not Modified"); + exit; +} + +switch ($type) { + case 'css': + header("Content-type: text/css", true); + $view = "css/$view"; + break; + case 'js': + header('Content-type: text/javascript', true); + $view = "js/$view"; + break; +} + +header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true); +header("Pragma: public", true); +header("Cache-Control: public", true); +header("ETag: \"$etag\""); + +$filename = $dataroot . 'views_simplecache/' . md5($viewtype . $view); + +if (file_exists($filename)) { + readfile($filename); +} else { + // someone trying to access a non-cached file or a race condition with cache flushing + mysql_close($mysql_dblink); + require_once(dirname(dirname(__FILE__)) . "/start.php"); + + global $CONFIG; + if (!in_array($view, $CONFIG->views->simplecache)) { + header("HTTP/1.1 404 Not Found"); + exit; + } + + elgg_set_viewtype($viewtype); + echo elgg_view($view); +} diff --git a/engine/handlers/export_handler.php b/engine/handlers/export_handler.php new file mode 100644 index 000000000..aa5214c23 --- /dev/null +++ b/engine/handlers/export_handler.php @@ -0,0 +1,118 @@ +<?php +/** + * Export handler. + * + * @package Elgg.Core + * @subpackage Export + */ + +require_once(dirname(dirname(__FILE__)) . "/start.php"); + + +// Get input values, these will be mapped via modrewrite +$guid = get_input("guid"); // guid of the entity + +// For attributes eg http://example.com/odd/73/attr/owner_uuid/ +// or http://example.com/odd/73/metadata/86/ +$type = get_input("type"); // attr, metadata, annotation, relationship +$id_or_name = get_input("idname"); // Either a number or the key name (if attribute) + +$body = ""; +$title = ""; + +// Only export the GUID +if (($guid != "") && ($type == "") && ($id_or_name == "")) { + $entity = get_entity($guid); + + if (!$entity) { + $query = elgg_echo('InvalidParameterException:GUIDNotFound', array($guid)); + throw new InvalidParameterException($query); + } + + $title = "GUID:$guid"; + $body = elgg_view("export/entity", array("entity" => $entity, "uuid" => guid_to_uuid($guid))); + + // Export an individual attribute +} else if (($guid != "") && ($type != "") && ($id_or_name != "")) { + // Get a uuid + $entity = get_entity($guid); + if (!$entity) { + $msg = elgg_echo('InvalidParameterException:GUIDNotFound', array($guid)); + throw new InvalidParameterException($msg); + } + + $uuid = guid_to_uuid($entity->getGUID()) . "$type/$id_or_name/"; + + switch ($type) { + case 'attr' : // @todo: Do this better? - This is a bit of a hack... + $v = $entity->get($id_or_name); + if (!$v) { + $msg = elgg_echo('InvalidParameterException:IdNotExistForGUID', array($id_or_name, $guid)); + throw new InvalidParameterException($msg); + } + + $m = new ElggMetadata(); + + $m->value = $v; + $m->name = $id_or_name; + $m->entity_guid = $guid; + $m->time_created = $entity->time_created; + $m->time_updated = $entity->time_updated; + $m->owner_guid = $entity->owner_guid; + $m->id = $id_or_name; + $m->type = "attr"; + break; + case 'metadata' : + $m = elgg_get_metadata_from_id($id_or_name); + break; + case 'annotation' : + $m = elgg_get_annotation_from_id($id_or_name); + break; + case 'relationship' : + $r = get_relationship($id_or_name); + break; + case 'volatile' : + $m = elgg_trigger_plugin_hook('volatile', 'metadata', array( + 'guid' => $guid, + 'varname' => $id_or_name, + )); + break; + + default : + $msg = elgg_echo('InvalidParameterException:CanNotExportType', array($type)); + throw new InvalidParameterException($msg); + } + + // Render metadata or relationship + if ((!$m) && (!$r)) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:NoDataFound')); + } + + // Exporting metadata? + if ($m) { + if ($m->entity_guid != $entity->guid) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:DoesNotBelong')); + } + + $title = "$type:$id_or_name"; + $body = elgg_view("export/metadata", array("metadata" => $m, "uuid" => $uuid)); + } + + // Exporting relationship + if ($r) { + if (($r->guid_one != $entity->guid) && ($r->guid_two != $entity->guid)) { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:DoesNotBelongOrRefer')); + } + + $title = "$type:$id_or_name"; + $body = elgg_view("export/relationship", array("relationship" => $r, "uuid" => $uuid)); + } + + // Something went wrong +} else { + throw new InvalidParameterException(elgg_echo('InvalidParameterException:MissingParameter')); +} + +$content = elgg_view_title($title) . $body; +$body = elgg_view_layout('one_sidebar', array('content' => $content)); +echo elgg_view_page($title, $body); diff --git a/engine/handlers/page_handler.php b/engine/handlers/page_handler.php new file mode 100644 index 000000000..1ed295b7d --- /dev/null +++ b/engine/handlers/page_handler.php @@ -0,0 +1,48 @@ +<?php +/** + * Pages handler. + * + * This file dispatches pages. It is called via a URL rewrite in .htaccess + * from http://site/handler/page1/page2. The first element after site/ is + * the page handler name as registered by {@link elgg_register_page_handler()}. + * The rest of the string is sent to {@link page_handler()}. + * + * Note that the following handler names are reserved by elgg and should not be + * registered by any plugins: + * * action + * * cache + * * services + * * export + * * mt + * * xml-rpc.php + * * rewrite.php + * * tag (deprecated, reserved for backwards compatibility) + * * pg (deprecated, reserved for backwards compatibility) + * + * {@link page_handler()} explodes the pages string by / and sends it to + * the page handler function as registered by {@link elgg_register_page_handler()}. + * If a valid page handler isn't found, plugins have a chance to provide a 404. + * + * @package Elgg.Core + * @subpackage PageHandler + * @link http://docs.elgg.org/Tutorials/PageHandlers + */ + + +// Permanent redirect to pg-less urls +$url = $_SERVER['REQUEST_URI']; +$new_url = preg_replace('#/pg/#', '/', $url, 1); + +if ($url !== $new_url) { + header("HTTP/1.1 301 Moved Permanently"); + header("Location: $new_url"); +} + +require_once(dirname(dirname(__FILE__)) . "/start.php"); + +$handler = get_input('handler'); +$page = get_input('page'); + +if (!page_handler($handler, $page)) { + forward('', '404'); +} diff --git a/engine/handlers/service_handler.php b/engine/handlers/service_handler.php new file mode 100644 index 000000000..9cfcd230f --- /dev/null +++ b/engine/handlers/service_handler.php @@ -0,0 +1,27 @@ +<?php +/** + * Services handler. + * + * This file dispatches requests to web services. It is called via a URL rewrite + * in .htaccess from http://site/services/api/handler/response_format/request. + * The first element after 'services/api/' is the service handler name as + * registered by {@link register_service_handler()}. + * + * The remaining string is then passed to the {@link service_handler()} + * which explodes by /, extracts the first element as the response format + * (viewtype), and then passes the remaining array to the service handler + * function registered by {@link register_service_handler()}. + * + * If a service handler isn't found, a 404 header is sent. + * + * @package Elgg.Core + * @subpackage WebServices + * @link http://docs.elgg.org/Tutorials/WebServices + */ + +require_once(dirname(dirname(__FILE__)) . "/start.php"); + +$handler = get_input('handler'); +$request = get_input('request'); + +service_handler($handler, $request); diff --git a/engine/handlers/xml-rpc_handler.php b/engine/handlers/xml-rpc_handler.php new file mode 100644 index 000000000..2ee29e5b7 --- /dev/null +++ b/engine/handlers/xml-rpc_handler.php @@ -0,0 +1,44 @@ +<?php +/** + * XML-RPC handler. + * + * @warning This is very old code. Does it work at all? + * + * @package Elgg.Core + * @subpackage XMLRPC + * @link http://docs.elgg.org/Tutorials/XMLRPC + * @todo Does this work? + */ + +require_once(dirname(dirname(__FILE__)) . "/start.php"); + +// Register the error handler +error_reporting(E_ALL); +set_error_handler('_php_xmlrpc_error_handler'); + +// Register a default exception handler +set_exception_handler('_php_xmlrpc_exception_handler'); + +// Set some defaults +$result = null; +set_input('view', 'xml'); // Set default view regardless + +// Get the post data +$input = get_post_data(); + +if ($input) { + // Parse structures from xml + $call = new XMLRPCCall($input); + + // Process call + $result = trigger_xmlrpc_handler($call); +} else { + throw new CallException(elgg_echo('xmlrpc:noinputdata')); +} + +if (!($result instanceof XMLRPCResponse)) { + throw new APIException(elgg_echo('APIException:ApiResultUnknown')); +} + +// Output result +echo elgg_view_page("XML-RPC", elgg_view("xml-rpc/output", array('result' => $result))); |