]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
moved the view functions around so that they are grouped together by function
authorcash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sun, 5 Dec 2010 19:14:11 +0000 (19:14 +0000)
committercash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Sun, 5 Dec 2010 19:14:11 +0000 (19:14 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@7536 36083f99-b078-4883-b0ff-0f9b5a30f544

engine/lib/views.php

index 2612c2363ad285bc63134169514bce9774192685..e4592d4b762e00c6b895ee19b31c3909cbd18c4b 100644 (file)
@@ -112,6 +112,24 @@ function elgg_get_viewtype() {
        return 'default';
 }
 
+/**
+ * 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.
@@ -188,6 +206,91 @@ function elgg_get_view_location($view, $viewtype = '') {
        return false;
 }
 
+/**
+ * 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.
  *
@@ -341,357 +444,203 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
 }
 
 /**
- * Returns whether the specified view exists
+ * Extends a view with another view.
  *
- * @note If $recurse is strue, also checks if a view exists only as an extension.
+ * The output of any view can be prepended or appended to any other view.
  *
- * @param string $view     The view name
- * @param string $viewtype If set, forces the viewtype
- * @param bool   $recurse  If false, do not check extensions
+ * 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.
  *
- * @return bool
+ * Priority can be specified and affects the order in which extensions
+ * are appended or prepended.
+ *
+ * @internal View extensions are stored in
+ * $CONFIG->views->extensions[$view][$priority] = $view_extension
+ *
+ * @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
+ * @since 1.7.0
+ * @link http://docs.elgg.org/Views/Ejxtend
+ * @example views/extend.php
  */
-function elgg_view_exists($view, $viewtype = '', $recurse = true) {
+function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') {
        global $CONFIG;
 
-       // Detect view type
-       if (empty($viewtype)) {
-               $viewtype = elgg_get_viewtype();
+       if (!isset($CONFIG->views)) {
+               $CONFIG->views = new stdClass;
        }
 
-       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 (!isset($CONFIG->views->extensions)) {
+               $CONFIG->views->extensions = array();
        }
 
-       if (file_exists($location . "{$viewtype}/{$view}.php")) {
-               return true;
+       if (!isset($CONFIG->views->extensions[$view])) {
+               $CONFIG->views->extensions[$view][500] = "{$view}";
        }
 
-       // 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;
-                       }
-               }
+       while (isset($CONFIG->views->extensions[$view][$priority])) {
+               $priority++;
        }
 
-       return false;
+       $CONFIG->views->extensions[$view][$priority] = "{$view_extension}";
+       ksort($CONFIG->views->extensions[$view]);
 }
 
 /**
- * Registers a view to simple cache.
- *
- * 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.
- *
- * @warning Simple cached views must take no parameters and return
- * the same content no matter who is logged in.
- *
- * @note CSS and the basic JS views are cached by the engine.
+ * Unextends a view.
  *
- * @param string $viewname View name
+ * @param string $view           The view that was extended.
+ * @param string $view_extension This view that was added to $view
  *
- * @return void
- * @link http://docs.elgg.org/Views/Simplecache
- * @see elgg_view_regenerate_simplecache()
+ * @return bool
+ * @since 1.7.2
  */
-function elgg_view_register_simplecache($viewname) {
+function elgg_unextend_view($view, $view_extension) {
        global $CONFIG;
 
        if (!isset($CONFIG->views)) {
-               $CONFIG->views = new stdClass;
+               return FALSE;
        }
 
-       if (!isset($CONFIG->views->simplecache)) {
-               $CONFIG->views->simplecache = array();
+       if (!isset($CONFIG->views->extensions)) {
+               return FALSE;
        }
 
-       $CONFIG->views->simplecache[] = $viewname;
+       if (!isset($CONFIG->views->extensions[$view])) {
+               return FALSE;
+       }
+
+       $priority = array_search($view_extension, $CONFIG->views->extensions[$view]);
+       if ($priority === FALSE) {
+               return FALSE;
+       }
+
+       unset($CONFIG->views->extensions[$view][$priority]);
+
+       return TRUE;
 }
 
 /**
- * Get the URL for the cached file
+ * Extend a view
  *
- * @param string $type The file type: css or js
- * @param string $view The view name
- * @return string
- * @since 1.8.0
+ * @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
+ *
+ * @return void
  */
-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;
+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);
 }
 
 /**
- * Regenerates the simple cache.
+ * Assembles and outputs a full page.
  *
- * @warning This does not invalidate the cache, but actively resets it.
+ * 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.
  *
- * @param string $viewtype Optional viewtype to regenerate
+ * @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 void
- * @see elgg_view_register_simplecache()
+ * @return string The contents of the page
+ * @since  1.8
  */
-function elgg_view_regenerate_simplecache($viewtype = NULL) {
-       global $CONFIG;
+function elgg_view_page($title, $body, $page_shell = 'default', $vars = array()) {
 
-       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);
-       }
-
-       elgg_set_viewtype($original_viewtype);
-
-       // needs to be set for links in html head
-       $CONFIG->lastcache = $lastcached;
-
-       unset($CONFIG->pagesetupdone);
-}
-
-/**
- * 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;
-}
-
-/**
- * Enables the simple cache.
- *
- * @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();
-}
-
-/**
- * Disables the simple cache.
- *
- * @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);
+       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.
@@ -953,62 +901,21 @@ function elgg_view_entity_annotations(ElggEntity $entity, $full = true) {
        return $annotations;
 }
 
-/**
- * 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;
 }
 
 /**