diff options
-rw-r--r-- | engine/lib/views.php | 950 |
1 files changed, 476 insertions, 474 deletions
diff --git a/engine/lib/views.php b/engine/lib/views.php index 2612c2363..e4592d4b7 100644 --- a/engine/lib/views.php +++ b/engine/lib/views.php @@ -113,6 +113,24 @@ function elgg_get_viewtype() { } /** + * Checks if $view_type is valid on this installation. + * + * @param string $view_type View type + * + * @return bool + * @since 1.7.2 + */ +function elgg_is_valid_view_type($view_type) { + global $CONFIG; + + if (!isset($CONFIG->view_types) || !is_array($CONFIG->view_types)) { + return FALSE; + } + + return in_array($view_type, $CONFIG->view_types); +} + +/** * Register a viewtype to fall back to a default view if a view isn't * found for that viewtype. * @@ -189,6 +207,91 @@ function elgg_get_view_location($view, $viewtype = '') { } /** + * Set an alternative base location for a view. + * + * Views are expected to be in plugin_name/views/. This function can + * be used to change that location. + * + * @internal Core view locations are stored in $CONFIG->viewpath. + * + * @tip This is useful to optionally register views in a plugin. + * + * @param string $view The name of the view + * @param string $location The base location path + * @param string $viewtype The view type + * + * @return void + */ +function set_view_location($view, $location, $viewtype = '') { + global $CONFIG; + + if (empty($viewtype)) { + $viewtype = 'default'; + } + + if (!isset($CONFIG->views)) { + $CONFIG->views = new stdClass; + } + + if (!isset($CONFIG->views->locations)) { + $CONFIG->views->locations = array($viewtype => array($view => $location)); + + } else if (!isset($CONFIG->views->locations[$viewtype])) { + $CONFIG->views->locations[$viewtype] = array($view => $location); + + } else { + $CONFIG->views->locations[$viewtype][$view] = $location; + } +} + +/** + * Returns whether the specified view exists + * + * @note If $recurse is strue, also checks if a view exists only as an extension. + * + * @param string $view The view name + * @param string $viewtype If set, forces the viewtype + * @param bool $recurse If false, do not check extensions + * + * @return bool + */ +function elgg_view_exists($view, $viewtype = '', $recurse = true) { + global $CONFIG; + + // Detect view type + if (empty($viewtype)) { + $viewtype = elgg_get_viewtype(); + } + + if (!isset($CONFIG->views->locations[$viewtype][$view])) { + if (!isset($CONFIG->viewpath)) { + $location = dirname(dirname(dirname(__FILE__))) . "/views/"; + } else { + $location = $CONFIG->viewpath; + } + } else { + $location = $CONFIG->views->locations[$viewtype][$view]; + } + + if (file_exists($location . "{$viewtype}/{$view}.php")) { + return true; + } + + // If we got here then check whether this exists as an extension + // We optionally recursively check whether the extended view exists also for the viewtype + if ($recurse && isset($CONFIG->views->extensions[$view])) { + foreach ($CONFIG->views->extensions[$view] as $view_extension) { + // do not recursively check to stay away from infinite loops + if (elgg_view_exists($view_extension, $viewtype, false)) { + return true; + } + } + } + + return false; +} + +/** * Return a parsed view. * * Views are rendered by a template handler and returned as strings. @@ -341,357 +444,203 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie } /** - * Returns whether the specified view exists - * - * @note If $recurse is strue, also checks if a view exists only as an extension. - * - * @param string $view The view name - * @param string $viewtype If set, forces the viewtype - * @param bool $recurse If false, do not check extensions + * Extends a view with another view. * - * @return bool - */ -function elgg_view_exists($view, $viewtype = '', $recurse = true) { - global $CONFIG; - - // Detect view type - if (empty($viewtype)) { - $viewtype = elgg_get_viewtype(); - } - - if (!isset($CONFIG->views->locations[$viewtype][$view])) { - if (!isset($CONFIG->viewpath)) { - $location = dirname(dirname(dirname(__FILE__))) . "/views/"; - } else { - $location = $CONFIG->viewpath; - } - } else { - $location = $CONFIG->views->locations[$viewtype][$view]; - } - - if (file_exists($location . "{$viewtype}/{$view}.php")) { - return true; - } - - // If we got here then check whether this exists as an extension - // We optionally recursively check whether the extended view exists also for the viewtype - if ($recurse && isset($CONFIG->views->extensions[$view])) { - foreach ($CONFIG->views->extensions[$view] as $view_extension) { - // do not recursively check to stay away from infinite loops - if (elgg_view_exists($view_extension, $viewtype, false)) { - return true; - } - } - } - - return false; -} - -/** - * Registers a view to simple cache. + * The output of any view can be prepended or appended to any other view. * - * Simple cache is a caching mechanism that saves the output of - * views and its extensions into a file. If the view is called - * by the {@link simplecache/view.php} file, the Elgg framework will - * not be loaded and the contents of the view will returned - * from file. + * The default action is to append a view. If the priority is less than 500, + * the output of the extended view will be appended to the original view. * - * @warning Simple cached views must take no parameters and return - * the same content no matter who is logged in. + * Priority can be specified and affects the order in which extensions + * are appended or prepended. * - * @note CSS and the basic JS views are cached by the engine. + * @internal View extensions are stored in + * $CONFIG->views->extensions[$view][$priority] = $view_extension * - * @param string $viewname View name + * @param string $view The view to extend. + * @param string $view_extension This view is added to $view + * @param int $priority The priority, from 0 to 1000, + * to add at (lowest numbers displayed first) + * @param string $viewtype Not used * * @return void - * @link http://docs.elgg.org/Views/Simplecache - * @see elgg_view_regenerate_simplecache() + * @since 1.7.0 + * @link http://docs.elgg.org/Views/Ejxtend + * @example views/extend.php */ -function elgg_view_register_simplecache($viewname) { +function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') { global $CONFIG; if (!isset($CONFIG->views)) { $CONFIG->views = new stdClass; } - if (!isset($CONFIG->views->simplecache)) { - $CONFIG->views->simplecache = array(); + if (!isset($CONFIG->views->extensions)) { + $CONFIG->views->extensions = array(); } - $CONFIG->views->simplecache[] = $viewname; -} + if (!isset($CONFIG->views->extensions[$view])) { + $CONFIG->views->extensions[$view][500] = "{$view}"; + } -/** - * Get the URL for the cached file - * - * @param string $type The file type: css or js - * @param string $view The view name - * @return string - * @since 1.8.0 - */ -function elgg_view_get_simplecache_url($type, $view) { - global $CONFIG; - $lastcache = (int)$CONFIG->lastcache; - - if (elgg_view_is_simplecache_enabled()) { - $viewtype = elgg_get_viewtype(); - $url = elgg_get_site_url() . "cache/$type/$view/$viewtype/$view.$lastcache.$type"; - } else { - $url = elgg_get_site_url() . "pg/$type/$view.$lastcache.$type"; + while (isset($CONFIG->views->extensions[$view][$priority])) { + $priority++; } - return $url; + + $CONFIG->views->extensions[$view][$priority] = "{$view_extension}"; + ksort($CONFIG->views->extensions[$view]); } /** - * Regenerates the simple cache. - * - * @warning This does not invalidate the cache, but actively resets it. + * Unextends a view. * - * @param string $viewtype Optional viewtype to regenerate + * @param string $view The view that was extended. + * @param string $view_extension This view that was added to $view * - * @return void - * @see elgg_view_register_simplecache() + * @return bool + * @since 1.7.2 */ -function elgg_view_regenerate_simplecache($viewtype = NULL) { +function elgg_unextend_view($view, $view_extension) { global $CONFIG; - if (!isset($CONFIG->views->simplecache) || !is_array($CONFIG->views->simplecache)) { - return; + if (!isset($CONFIG->views)) { + return FALSE; } - $lastcached = time(); - - // @todo elgg_view() checks if the page set is done (isset($CONFIG->pagesetupdone)) and - // triggers an event if it's not. Calling elgg_view() here breaks submenus - // (at least) because the page setup hook is called before any - // contexts can be correctly set (since this is called before page_handler()). - // To avoid this, lie about $CONFIG->pagehandlerdone to force - // the trigger correctly when the first view is actually being output. - $CONFIG->pagesetupdone = TRUE; - - if (!file_exists($CONFIG->dataroot . 'views_simplecache')) { - mkdir($CONFIG->dataroot . 'views_simplecache'); + if (!isset($CONFIG->views->extensions)) { + return FALSE; } - if (isset($viewtype)) { - $viewtypes = array($viewtype); - } else { - $viewtypes = $CONFIG->view_types; + if (!isset($CONFIG->views->extensions[$view])) { + return FALSE; } - $original_viewtype = elgg_get_viewtype(); - - foreach ($viewtypes as $viewtype) { - elgg_set_viewtype($viewtype); - foreach ($CONFIG->views->simplecache as $view) { - $viewcontents = elgg_view($view); - $viewname = md5(elgg_get_viewtype() . $view); - if ($handle = fopen($CONFIG->dataroot . 'views_simplecache/' . $viewname, 'w')) { - fwrite($handle, $viewcontents); - fclose($handle); - } - } - - datalist_set("simplecache_lastupdate_$viewtype", $lastcached); - datalist_set("simplecache_lastcached_$viewtype", $lastcached); + $priority = array_search($view_extension, $CONFIG->views->extensions[$view]); + if ($priority === FALSE) { + return FALSE; } - elgg_set_viewtype($original_viewtype); - - // needs to be set for links in html head - $CONFIG->lastcache = $lastcached; + unset($CONFIG->views->extensions[$view][$priority]); - unset($CONFIG->pagesetupdone); + return TRUE; } /** - * Is simple cache enabled + * Extend a view * - * @return bool - * @since 1.8.0 - */ -function elgg_view_is_simplecache_enabled() { - global $CONFIG; - - if ($CONFIG->simplecache_enabled) { - return true; - } - - return false; -} - -/** - * Enables the simple cache. + * @deprecated 1.7. Use elgg_extend_view(). + * + * @param string $view The view to extend. + * @param string $view_name This view is added to $view + * @param int $priority The priority, from 0 to 1000, + * to add at (lowest numbers displayed first) + * @param string $viewtype Not used * - * @access private - * @see elgg_view_register_simplecache() * @return void */ -function elgg_view_enable_simplecache() { - global $CONFIG; - - datalist_set('simplecache_enabled', 1); - $CONFIG->simplecache_enabled = 1; - elgg_view_regenerate_simplecache(); +function extend_view($view, $view_name, $priority = 501, $viewtype = '') { + elgg_deprecated_notice('extend_view() was deprecated by elgg_extend_view()!', 1.7); + elgg_extend_view($view, $view_name, $priority, $viewtype); } /** - * Disables the simple cache. + * Assembles and outputs a full page. * - * @warning Simplecache is also purged when disabled. + * A "page" in Elgg is determined by the current view type and + * can be HTML for a browser, RSS for a feed reader, or + * Javascript, PHP and a number of other formats. * - * @access private - * @see elgg_view_register_simplecache() - * @return void + * @param string $title Title + * @param string $body Body + * @param string $page_shell Optional page shell to use. See page_shells view directory + * @param array $vars Optional vars array to pass to the page + * shell. Automatically adds title, body, and sysmessages + * + * @return string The contents of the page + * @since 1.8 */ -function elgg_view_disable_simplecache() { - global $CONFIG; - if ($CONFIG->simplecache_enabled) { - datalist_set('simplecache_enabled', 0); - $CONFIG->simplecache_enabled = 0; +function elgg_view_page($title, $body, $page_shell = 'default', $vars = array()) { - // purge simple cache - if ($handle = opendir($CONFIG->dataroot . 'views_simplecache')) { - while (false !== ($file = readdir($handle))) { - if ($file != "." && $file != "..") { - unlink($CONFIG->dataroot . 'views_simplecache/' . $file); - } - } - closedir($handle); + if (count_messages()) { + // get messages - try for errors first + $sysmessages = system_messages(NULL, "errors"); + if (count($sysmessages["errors"]) == 0) { + // no errors so grab rest of messages + $sysmessages = system_messages(null, ""); + } else { + // we have errors - clear out remaining messages + system_messages(null, ""); } } -} -/** - * Invalidates all cached views in the simplecache - * - * @return bool - * @since 1.7.4 - */ -function elgg_invalidate_simplecache() { - global $CONFIG; + $vars['title'] = $title; + $vars['body'] = $body; + $vars['sysmessages'] = $sysmessages; - $return = TRUE; + // Draw the page + $output = elgg_view("page_shells/$page_shell", $vars); - if ($handle = opendir($CONFIG->dataroot . 'views_simplecache')) { - while (false !== ($file = readdir($handle))) { - if ($file != "." && $file != "..") { - $return = $return && unlink($CONFIG->dataroot . 'views_simplecache/' . $file); - } - } - closedir($handle); - } else { - $return = FALSE; - } + $vars['page_shell'] = $page_shell; - return $return; + // Allow plugins to mod output + return elgg_trigger_plugin_hook('output', 'page', $vars, $output); } /** - * Returns the name of views for in a directory. - * - * Use this to get all namespaced views under the first element. - * - * @param string $dir The main directory that holds the views. (mod/profile/views/) - * @param string $base The root name of the view to use, without the viewtype. (profile) - * - * @return array - * @since 1.7.0 - * @todo Why isn't this used anywhere else but in elgg_view_tree()? - * Seems like a useful function for autodiscovery. + * @deprecated 1.8 Use elgg_view_page() */ -function elgg_get_views($dir, $base) { - $return = array(); - if (file_exists($dir) && is_dir($dir)) { - if ($handle = opendir($dir)) { - while ($view = readdir($handle)) { - if (!in_array($view, array('.', '..', '.svn', 'CVS'))) { - if (is_dir($dir . '/' . $view)) { - if ($val = elgg_get_views($dir . '/' . $view, $base . '/' . $view)) { - $return = array_merge($return, $val); - } - } else { - $view = str_replace('.php', '', $view); - $return[] = $base . '/' . $view; - } - } - } - } - } +function page_draw($title, $body, $sidebar = "") { + elgg_deprecated_notice("page_draw() was deprecated in favor of elgg_view_page() in 1.8.", 1.8); - return $return; + $vars = array( + 'sidebar' => $sidebar + ); + echo elgg_view_page($title, $body, 'default', $vars); } /** - * Get views in a dir - * - * @deprecated 1.7. Use elgg_get_views(). - * - * @param string $dir Dir - * @param string $base Base view + * Displays a layout with optional parameters. * - * @return array - */ -function get_views($dir, $base) { - elgg_deprecated_notice('get_views() was deprecated by elgg_get_views()!', 1.7); - elgg_get_views($dir, $base); -} - -/** - * Returns all views below a partial view. + * Layouts provide consistent organization of pages and other blocks of content. + * There are a few default layouts in core: + * - administration A special layout for the admin area. + * - one_column A single content column. + * - one_column_with_sidebar A content column with sidebar. + * - widgets A widget canvas. * - * Settings $view_root = 'profile' will show all available views under - * the "profile" namespace. + * The layout views take the form canvas/layouts/$layout_name + * See the individual layouts for what options are supported. The two most + * common layouts have these parameters: + * one_column + * content => string + * one_column_with_sidebar + * content => string + * sidebar => string (optional) * - * @param string $view_root The root view - * @param string $viewtype Optionally specify a view type - * other than the current one. + * @param string $layout The name of the view in canvas/layouts/. + * @param array $vars Associative array of parameters for the layout view * - * @return array A list of view names underneath that root view - * @todo This is used once in the deprecated get_activity_stream_data() function. + * @return string The layout */ -function elgg_view_tree($view_root, $viewtype = "") { - global $CONFIG; - static $treecache; - - // Get viewtype - if (!$viewtype) { - $viewtype = elgg_get_viewtype(); - } - - // Has the treecache been initialised? - if (!isset($treecache)) { - $treecache = array(); - } - // A little light internal caching - if (!empty($treecache[$view_root])) { - return $treecache[$view_root]; - } +function elgg_view_layout($layout_name, $vars = array()) { - // Examine $CONFIG->views->locations - if (isset($CONFIG->views->locations[$viewtype])) { - foreach ($CONFIG->views->locations[$viewtype] as $view => $path) { - $pos = strpos($view, $view_root); - if ($pos === 0) { - $treecache[$view_root][] = $view; - } + if (is_string($vars)) { + elgg_deprecated_notice("The use of unlimited optional string arguments in elgg_view_layout() was deprecated in favor of an options array", 1.8); + $arg = 1; + $param_array = array(); + while ($arg < func_num_args()) { + $param_array['area' . $arg] = func_get_arg($arg); + $arg++; } + } else { + $param_array = $vars; } - // Now examine core - $location = $CONFIG->viewpath; - $viewtype = elgg_get_viewtype(); - $root = $location . $viewtype . '/' . $view_root; - - if (file_exists($root) && is_dir($root)) { - $val = elgg_get_views($root, $view_root); - if (!is_array($treecache[$view_root])) { - $treecache[$view_root] = array(); - } - $treecache[$view_root] = array_merge($treecache[$view_root], $val); + if (elgg_view_exists("layouts/{$layout_name}")) { + return elgg_view("layouts/{$layout_name}", $param_array); + } else { + return elgg_view("layouts/default", $param_array); } - - return $treecache[$view_root]; } /** @@ -824,7 +773,6 @@ function elgg_view_annotation(ElggAnnotation $annotation, $full = true, $bypass } } - /** * Returns a rendered list of entities with pagination. This function should be * called by wrapper functions. @@ -954,61 +902,20 @@ function elgg_view_entity_annotations(ElggEntity $entity, $full = true) { } /** - * Displays a layout with optional parameters. - * - * Layouts provide consistent organization of pages and other blocks of content. - * There are a few default layouts in core: - * - administration A special layout for the admin area. - * - one_column A single content column. - * - one_column_with_sidebar A content column with sidebar. - * - widgets A widget canvas. - * - * The layout views take the form canvas/layouts/$layout_name - * See the individual layouts for what options are supported. The two most - * common layouts have these parameters: - * one_column - * content => string - * one_column_with_sidebar - * content => string - * sidebar => string (optional) - * - * @param string $layout The name of the view in canvas/layouts/. - * @param array $vars Associative array of parameters for the layout view - * - * @return string The layout - */ -function elgg_view_layout($layout_name, $vars = array()) { - - if (is_string($vars)) { - elgg_deprecated_notice("The use of unlimited optional string arguments in elgg_view_layout() was deprecated in favor of an options array", 1.8); - $arg = 1; - $param_array = array(); - while ($arg < func_num_args()) { - $param_array['area' . $arg] = func_get_arg($arg); - $arg++; - } - } else { - $param_array = $vars; - } - - if (elgg_view_exists("layouts/{$layout_name}")) { - return elgg_view("layouts/{$layout_name}", $param_array); - } else { - return elgg_view("layouts/default", $param_array); - } -} - -/** * Returns a rendered title. * * This is a shortcut for {@elgg_view page_elements/title}. * * @param string $title The page title - * @param string $submenu Should a submenu be displayed? (default false, use not recommended) + * @param string $submenu Should a submenu be displayed? (default false, use not recommended and deprecated) * * @return string The HTML (etc) */ function elgg_view_title($title, $submenu = false) { + if ($submenu !== false) { + elgg_deprecated_notice('setting $submenu in elgg_view_title() is deprecated', 1.8); + } + $title = elgg_view('page_elements/title', array('title' => $title, 'submenu' => $submenu)); return $title; @@ -1063,7 +970,6 @@ function elgg_view_comments($entity, $add_comment = true) { } } - /** * Wrapper function to display search listings. * @@ -1107,141 +1013,110 @@ function set_template_handler($function_name) { } /** - * Extends a view with another view. - * - * The output of any view can be prepended or appended to any other view. - * - * The default action is to append a view. If the priority is less than 500, - * the output of the extended view will be appended to the original view. - * - * Priority can be specified and affects the order in which extensions - * are appended or prepended. + * Returns the name of views for in a directory. * - * @internal View extensions are stored in - * $CONFIG->views->extensions[$view][$priority] = $view_extension + * Use this to get all namespaced views under the first element. * - * @param string $view The view to extend. - * @param string $view_extension This view is added to $view - * @param int $priority The priority, from 0 to 1000, - * to add at (lowest numbers displayed first) - * @param string $viewtype Not used + * @param string $dir The main directory that holds the views. (mod/profile/views/) + * @param string $base The root name of the view to use, without the viewtype. (profile) * - * @return void + * @return array * @since 1.7.0 - * @link http://docs.elgg.org/Views/Ejxtend - * @example views/extend.php - */ -function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') { - global $CONFIG; - - if (!isset($CONFIG->views)) { - $CONFIG->views = new stdClass; - } - - if (!isset($CONFIG->views->extensions)) { - $CONFIG->views->extensions = array(); - } - - if (!isset($CONFIG->views->extensions[$view])) { - $CONFIG->views->extensions[$view][500] = "{$view}"; - } - - while (isset($CONFIG->views->extensions[$view][$priority])) { - $priority++; - } - - $CONFIG->views->extensions[$view][$priority] = "{$view_extension}"; - ksort($CONFIG->views->extensions[$view]); -} - -/** - * Unextends a view. - * - * @param string $view The view that was extended. - * @param string $view_extension This view that was added to $view - * - * @return bool - * @since 1.7.2 + * @todo Why isn't this used anywhere else but in elgg_view_tree()? + * Seems like a useful function for autodiscovery. */ -function elgg_unextend_view($view, $view_extension) { - global $CONFIG; - - if (!isset($CONFIG->views)) { - return FALSE; - } - - if (!isset($CONFIG->views->extensions)) { - return FALSE; - } - - if (!isset($CONFIG->views->extensions[$view])) { - return FALSE; - } - - $priority = array_search($view_extension, $CONFIG->views->extensions[$view]); - if ($priority === FALSE) { - return FALSE; +function elgg_get_views($dir, $base) { + $return = array(); + if (file_exists($dir) && is_dir($dir)) { + if ($handle = opendir($dir)) { + while ($view = readdir($handle)) { + if (!in_array($view, array('.', '..', '.svn', 'CVS'))) { + if (is_dir($dir . '/' . $view)) { + if ($val = elgg_get_views($dir . '/' . $view, $base . '/' . $view)) { + $return = array_merge($return, $val); + } + } else { + $view = str_replace('.php', '', $view); + $return[] = $base . '/' . $view; + } + } + } + } } - unset($CONFIG->views->extensions[$view][$priority]); - - return TRUE; + return $return; } /** - * Extend a view + * Get views in a dir * - * @deprecated 1.7. Use elgg_extend_view(). + * @deprecated 1.7. Use elgg_get_views(). * - * @param string $view The view to extend. - * @param string $view_name This view is added to $view - * @param int $priority The priority, from 0 to 1000, - * to add at (lowest numbers displayed first) - * @param string $viewtype Not used + * @param string $dir Dir + * @param string $base Base view * - * @return void + * @return array */ -function extend_view($view, $view_name, $priority = 501, $viewtype = '') { - elgg_deprecated_notice('extend_view() was deprecated by elgg_extend_view()!', 1.7); - elgg_extend_view($view, $view_name, $priority, $viewtype); +function get_views($dir, $base) { + elgg_deprecated_notice('get_views() was deprecated by elgg_get_views()!', 1.7); + elgg_get_views($dir, $base); } /** - * Set an alternative base location for a view. - * - * Views are expected to be in plugin_name/views/. This function can - * be used to change that location. - * - * @internal Core view locations are stored in $CONFIG->viewpath. + * Returns all views below a partial view. * - * @tip This is useful to optionally register views in a plugin. + * Settings $view_root = 'profile' will show all available views under + * the "profile" namespace. * - * @param string $view The name of the view - * @param string $location The base location path - * @param string $viewtype The view type + * @param string $view_root The root view + * @param string $viewtype Optionally specify a view type + * other than the current one. * - * @return void + * @return array A list of view names underneath that root view + * @todo This is used once in the deprecated get_activity_stream_data() function. */ -function set_view_location($view, $location, $viewtype = '') { +function elgg_view_tree($view_root, $viewtype = "") { global $CONFIG; + static $treecache; - if (empty($viewtype)) { - $viewtype = 'default'; + // Get viewtype + if (!$viewtype) { + $viewtype = elgg_get_viewtype(); } - if (!isset($CONFIG->views)) { - $CONFIG->views = new stdClass; + // Has the treecache been initialised? + if (!isset($treecache)) { + $treecache = array(); + } + // A little light internal caching + if (!empty($treecache[$view_root])) { + return $treecache[$view_root]; } - if (!isset($CONFIG->views->locations)) { - $CONFIG->views->locations = array($viewtype => array($view => $location)); + // Examine $CONFIG->views->locations + if (isset($CONFIG->views->locations[$viewtype])) { + foreach ($CONFIG->views->locations[$viewtype] as $view => $path) { + $pos = strpos($view, $view_root); + if ($pos === 0) { + $treecache[$view_root][] = $view; + } + } + } - } else if (!isset($CONFIG->views->locations[$viewtype])) { - $CONFIG->views->locations[$viewtype] = array($view => $location); + // Now examine core + $location = $CONFIG->viewpath; + $viewtype = elgg_get_viewtype(); + $root = $location . $viewtype . '/' . $view_root; - } else { - $CONFIG->views->locations[$viewtype][$view] = $location; + if (file_exists($root) && is_dir($root)) { + $val = elgg_get_views($root, $view_root); + if (!is_array($treecache[$view_root])) { + $treecache[$view_root] = array(); + } + $treecache[$view_root] = array_merge($treecache[$view_root], $val); } + + return $treecache[$view_root]; } /** @@ -1298,76 +1173,203 @@ function autoregister_views($view_base, $folder, $base_location_path, $viewtype) } /** - * Assembles and outputs a full page. + * Registers a view to simple cache. * - * A "page" in Elgg is determined by the current view type and - * can be HTML for a browser, RSS for a feed reader, or - * Javascript, PHP and a number of other formats. + * Simple cache is a caching mechanism that saves the output of + * views and its extensions into a file. If the view is called + * by the {@link simplecache/view.php} file, the Elgg framework will + * not be loaded and the contents of the view will returned + * from file. * - * @param string $title Title - * @param string $body Body - * @param string $page_shell Optional page shell to use. See page_shells view directory - * @param array $vars Optional vars array to pass to the page - * shell. Automatically adds title, body, and sysmessages + * @warning Simple cached views must take no parameters and return + * the same content no matter who is logged in. * - * @return string The contents of the page - * @since 1.8 + * @note CSS and the basic JS views are cached by the engine. + * + * @param string $viewname View name + * + * @return void + * @link http://docs.elgg.org/Views/Simplecache + * @see elgg_view_regenerate_simplecache() */ -function elgg_view_page($title, $body, $page_shell = 'default', $vars = array()) { +function elgg_view_register_simplecache($viewname) { + global $CONFIG; - if (count_messages()) { - // get messages - try for errors first - $sysmessages = system_messages(NULL, "errors"); - if (count($sysmessages["errors"]) == 0) { - // no errors so grab rest of messages - $sysmessages = system_messages(null, ""); - } else { - // we have errors - clear out remaining messages - system_messages(null, ""); + if (!isset($CONFIG->views)) { + $CONFIG->views = new stdClass; + } + + if (!isset($CONFIG->views->simplecache)) { + $CONFIG->views->simplecache = array(); + } + + $CONFIG->views->simplecache[] = $viewname; +} + +/** + * Get the URL for the cached file + * + * @param string $type The file type: css or js + * @param string $view The view name + * @return string + * @since 1.8.0 + */ +function elgg_view_get_simplecache_url($type, $view) { + global $CONFIG; + $lastcache = (int)$CONFIG->lastcache; + + if (elgg_view_is_simplecache_enabled()) { + $viewtype = elgg_get_viewtype(); + $url = elgg_get_site_url() . "cache/$type/$view/$viewtype/$view.$lastcache.$type"; + } else { + $url = elgg_get_site_url() . "pg/$type/$view.$lastcache.$type"; + } + return $url; +} + +/** + * Regenerates the simple cache. + * + * @warning This does not invalidate the cache, but actively resets it. + * + * @param string $viewtype Optional viewtype to regenerate + * + * @return void + * @see elgg_view_register_simplecache() + */ +function elgg_view_regenerate_simplecache($viewtype = NULL) { + global $CONFIG; + + if (!isset($CONFIG->views->simplecache) || !is_array($CONFIG->views->simplecache)) { + return; + } + + $lastcached = time(); + + // @todo elgg_view() checks if the page set is done (isset($CONFIG->pagesetupdone)) and + // triggers an event if it's not. Calling elgg_view() here breaks submenus + // (at least) because the page setup hook is called before any + // contexts can be correctly set (since this is called before page_handler()). + // To avoid this, lie about $CONFIG->pagehandlerdone to force + // the trigger correctly when the first view is actually being output. + $CONFIG->pagesetupdone = TRUE; + + if (!file_exists($CONFIG->dataroot . 'views_simplecache')) { + mkdir($CONFIG->dataroot . 'views_simplecache'); + } + + if (isset($viewtype)) { + $viewtypes = array($viewtype); + } else { + $viewtypes = $CONFIG->view_types; + } + + $original_viewtype = elgg_get_viewtype(); + + foreach ($viewtypes as $viewtype) { + elgg_set_viewtype($viewtype); + foreach ($CONFIG->views->simplecache as $view) { + $viewcontents = elgg_view($view); + $viewname = md5(elgg_get_viewtype() . $view); + if ($handle = fopen($CONFIG->dataroot . 'views_simplecache/' . $viewname, 'w')) { + fwrite($handle, $viewcontents); + fclose($handle); + } } + + datalist_set("simplecache_lastupdate_$viewtype", $lastcached); + datalist_set("simplecache_lastcached_$viewtype", $lastcached); } - $vars['title'] = $title; - $vars['body'] = $body; - $vars['sysmessages'] = $sysmessages; + elgg_set_viewtype($original_viewtype); - // Draw the page - $output = elgg_view("page_shells/$page_shell", $vars); + // needs to be set for links in html head + $CONFIG->lastcache = $lastcached; - $vars['page_shell'] = $page_shell; + unset($CONFIG->pagesetupdone); +} - // Allow plugins to mod output - return elgg_trigger_plugin_hook('output', 'page', $vars, $output); +/** + * Is simple cache enabled + * + * @return bool + * @since 1.8.0 + */ +function elgg_view_is_simplecache_enabled() { + global $CONFIG; + + if ($CONFIG->simplecache_enabled) { + return true; + } + + return false; } /** - * @deprecated 1.8 Use elgg_view_page() + * Enables the simple cache. + * + * @access private + * @see elgg_view_register_simplecache() + * @return void */ -function page_draw($title, $body, $sidebar = "") { - elgg_deprecated_notice("page_draw() was deprecated in favor of elgg_view_page() in 1.8.", 1.8); +function elgg_view_enable_simplecache() { + global $CONFIG; - $vars = array( - 'sidebar' => $sidebar - ); - echo elgg_view_page($title, $body, 'default', $vars); + datalist_set('simplecache_enabled', 1); + $CONFIG->simplecache_enabled = 1; + elgg_view_regenerate_simplecache(); } /** - * Checks if $view_type is valid on this installation. + * Disables the simple cache. * - * @param string $view_type View type + * @warning Simplecache is also purged when disabled. + * + * @access private + * @see elgg_view_register_simplecache() + * @return void + */ +function elgg_view_disable_simplecache() { + global $CONFIG; + if ($CONFIG->simplecache_enabled) { + datalist_set('simplecache_enabled', 0); + $CONFIG->simplecache_enabled = 0; + + // purge simple cache + if ($handle = opendir($CONFIG->dataroot . 'views_simplecache')) { + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != "..") { + unlink($CONFIG->dataroot . 'views_simplecache/' . $file); + } + } + closedir($handle); + } + } +} + +/** + * Invalidates all cached views in the simplecache * * @return bool - * @since 1.7.2 + * @since 1.7.4 */ -function elgg_is_valid_view_type($view_type) { +function elgg_invalidate_simplecache() { global $CONFIG; - if (!isset($CONFIG->view_types) || !is_array($CONFIG->view_types)) { - return FALSE; + $return = TRUE; + + if ($handle = opendir($CONFIG->dataroot . 'views_simplecache')) { + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != "..") { + $return = $return && unlink($CONFIG->dataroot . 'views_simplecache/' . $file); + } + } + closedir($handle); + } else { + $return = FALSE; } - return in_array($view_type, $CONFIG->view_types); + return $return; } /** |