diff options
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/lib/elgglib.php | 1083 | ||||
| -rw-r--r-- | engine/lib/views.php | 1053 | ||||
| -rw-r--r-- | engine/start.php | 2 | 
3 files changed, 1071 insertions, 1067 deletions
| diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php index e86b7a4c8..385660d01 100644 --- a/engine/lib/elgglib.php +++ b/engine/lib/elgglib.php @@ -19,8 +19,7 @@   *   * @param string $location URL to forward to browser to. Can be relative path.   * @return nothing|false - */ -function forward($location = "") { + */function forward($location = "") {  	global $CONFIG;  	if (!headers_sent()) { @@ -84,446 +83,6 @@ function current_page_url() {  }  /** - * Templating and visual functionality - */ - -$CURRENT_SYSTEM_VIEWTYPE = ""; - -/** - * Override the view mode detection for the elgg view system. - * - * This function will force any further views to be rendered using $viewtype. Remember to call elgg_set_viewtype() with - * no parameters to reset. - * - * @param string $viewtype The view type, e.g. 'rss', or 'default'. - * @return bool - */ -function elgg_set_viewtype($viewtype = "") { -	global $CURRENT_SYSTEM_VIEWTYPE; - -	$CURRENT_SYSTEM_VIEWTYPE = $viewtype; - -	return true; -} - -/** - * Return the current view type used by the elgg view system. - * - * By default, this function will return a value based on the default for your system or from the command line - * view parameter. However, you may force a given view type by calling elgg_set_viewtype() - * - * @return string The view. - */ -function elgg_get_viewtype() { -	global $CURRENT_SYSTEM_VIEWTYPE, $CONFIG; - -	$viewtype = NULL; - -	if ($CURRENT_SYSTEM_VIEWTYPE != "") { -		return $CURRENT_SYSTEM_VIEWTYPE; -	} - -	if ((empty($_SESSION['view'])) || ( (trim($CONFIG->view!="")) && ($_SESSION['view']!=$CONFIG->view) )) { -		$_SESSION['view'] = "default"; -		// If we have a config default view for this site then use that instead of 'default' -		if (/*(is_installed()) && */(!empty($CONFIG->view)) && (trim($CONFIG->view)!="")) { -			$_SESSION['view'] = $CONFIG->view; -		} -	} - -	if (empty($viewtype) && is_callable('get_input')) { -		$viewtype = get_input('view'); -	} - -	if (empty($viewtype)) { -		$viewtype = $_SESSION['view']; -	} - -	return $viewtype; -} - -/** - * Register a viewtype to fall back to a default view if view does not exist in - * that viewtype. - * - * This is useful for alternate html viewtypes (such as for mobile devices) - * - * @param string $viewtype The viewtype to register - */ -function elgg_register_viewtype_fallback($viewtype) { -	global $CONFIG; - -	if (!isset($CONFIG->viewtype)) { -		$CONFIG->viewtype = new stdClass; -	} - -	if (!isset($CONFIG->viewtype->fallback)) { -		$CONFIG->viewtype->fallback = array(); -	} - -	$CONFIG->viewtype->fallback[] = $viewtype; -} - -/** - * Checks if this viewtype falls back to default - * - * @param string $viewtype - * @return boolean - */ -function elgg_does_viewtype_fallback($viewtype) { -	global $CONFIG; - -	if (isset($CONFIG->viewtype) && isset($CONFIG->viewtype->fallback)) { -		return in_array($viewtype, $CONFIG->viewtype->fallback); -	} - -	return FALSE; -} - - -/** - * Return the location of a given view. - * - * @param string $view The view. - * @param string $viewtype The viewtype - */ -function elgg_get_view_location($view, $viewtype = '') { -	global $CONFIG; - -	if (empty($viewtype)) { -		$viewtype = elgg_get_viewtype(); -	} - -	if (!isset($CONFIG->views->locations[$viewtype][$view])) { -		if (!isset($CONFIG->viewpath)) { -			return dirname(dirname(dirname(__FILE__))) . "/views/"; -		} else { -			return $CONFIG->viewpath; -		} -	} else { -		return $CONFIG->views->locations[$viewtype][$view]; -	} - -	return false; -} - -/** - * Handles templating views - * - * @see set_template_handler - * - * @param string $view The name and location of the view to use - * @param array $vars Any variables that the view requires, passed as an array - * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) - * @param boolean $debug If set to true, the viewer will complain if it can't find a view - * @param string $viewtype If set, forces the viewtype for the elgg_view call to be this value (default: standard detection) - * @return string The HTML content - */ -function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $viewtype = '') { -	global $CONFIG; -	static $usercache; - -	$view = (string)$view; - -	// basic checking for bad paths -	if (strpos($view, '..') !== false) { -		return false; -	} - -	$view_orig = $view; - -	// Trigger the pagesetup event -	if (!isset($CONFIG->pagesetupdone)) { -		trigger_elgg_event('pagesetup','system'); -		$CONFIG->pagesetupdone = true; -	} - -	if (!is_array($usercache)) { -		$usercache = array(); -	} - -	if (!is_array($vars)) { -		elgg_log('Vars in views must be an array!', 'ERROR'); -		$vars = array(); -	} - -	if (empty($vars)) { -		$vars = array(); -	} - -	// Load session and configuration variables into $vars -	// $_SESSION will always be an array if it is set -	if (isset($_SESSION) /*&& is_array($_SESSION)*/ ) { -		//= array_merge($vars, $_SESSION); -		$vars += $_SESSION; -	} - -	$vars['config'] = array(); - -	if (!empty($CONFIG)) { -		$vars['config'] = $CONFIG; -	} - -	$vars['url'] = $CONFIG->url; - -	// Load page owner variables into $vars -	if (is_callable('page_owner')) { -		$vars['page_owner'] = page_owner(); -	} else { -		$vars['page_owner'] = -1; -	} - -	if (($vars['page_owner'] != -1) && (is_installed())) { -		if (!isset($usercache[$vars['page_owner']])) { -			$vars['page_owner_user'] = get_entity($vars['page_owner']); -			$usercache[$vars['page_owner']] = $vars['page_owner_user']; -		} else { -			$vars['page_owner_user'] = $usercache[$vars['page_owner']]; -		} -	} - -	if (!isset($vars['js'])) { -		$vars['js'] = ""; -	} - -	// If it's been requested, pass off to a template handler instead -	if ($bypass == false && isset($CONFIG->template_handler) && !empty($CONFIG->template_handler)) { -		$template_handler = $CONFIG->template_handler; -		if (is_callable($template_handler)) { -			return $template_handler($view, $vars); -		} -	} - -	// Get the current viewtype -	if (empty($viewtype)) { -		$viewtype = elgg_get_viewtype(); -	} - -	// Viewtypes can only be alphanumeric -	if (preg_match('[\W]', $viewtype)) { -		return ''; -	} - -	// Set up any extensions to the requested view -	if (isset($CONFIG->views->extensions[$view])) { -		$viewlist = $CONFIG->views->extensions[$view]; -	} else { -		$viewlist = array(500 => $view); -	} - -	// Start the output buffer, find the requested view file, and execute it -	ob_start(); - -	foreach($viewlist as $priority => $view) { -		$view_location = elgg_get_view_location($view, $viewtype); -		$view_file = "$view_location$viewtype/$view.php"; -		$default_view_file = "{$view_location}default/$view.php"; - -		// try to include view -		if (!file_exists($view_file) || !include($view_file)) { -			// requested view does not exist -			$error = "$viewtype/$view view does not exist."; - -			// attempt to load default view -			if ($viewtype != 'default' && elgg_does_viewtype_fallback($viewtype)) { -				if (file_exists($default_view_file) && include($default_view_file)) { -					// default view found -					$error .= " Using default/$view instead."; -				} else { -					// no view found at all -					$error = "Neither $viewtype/$view nor default/$view view exists."; -				} -			} - -			// log warning -			elgg_log($error, 'NOTICE'); -		} -	} - -	// Save the output buffer into the $content variable -	$content = ob_get_clean(); - -	// Plugin hook -	$content = trigger_plugin_hook('view', $view_orig, -		array('view' => $view_orig, 'vars' => $vars), $content); - -	// backward compatibility with less grandular hook will be gone in 2.0 -	$content_tmp = trigger_plugin_hook('display', 'view', array('view' => $view_orig, 'vars' => $vars), $content); - -	if ($content_tmp != $content) { -		$content = $content_tmp; -		elgg_deprecated_notice('The display:view plugin hook is deprecated by view:view_name or view:all', 1.8); -	} - -	// Return $content -	return $content; -} - -/** - * Returns whether the specified view exists - * - * @param string $view The view name - * @param string $viewtype If set, forces the viewtype - * @param bool $recurse If false, do not recursively check extensions - * @return true|false Depending on success - */ -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 be simply cached - * - * Views cached in this manner must take no parameters and be login agnostic - - * that is to say, they look the same no matter who is logged in (or logged out). - * - * CSS and the basic jS views are automatically cached like this. - * - * @param string $viewname View name - */ -function elgg_view_register_simplecache($viewname) { -	global $CONFIG; - -	if (!isset($CONFIG->views)) { -		$CONFIG->views = new stdClass; -	} - -	if (!isset($CONFIG->views->simplecache)) { -		$CONFIG->views->simplecache = array(); -	} - -	//if (elgg_view_exists($viewname)) -	$CONFIG->views->simplecache[] = $viewname; -} - -/** - * Regenerates the simple cache. - * - * @param string $viewtype Optional viewtype to regenerate - * @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); -	} - -	elgg_set_viewtype($original_viewtype); - -	unset($CONFIG->pagesetupdone); -} - -/** - * Enables the simple cache. - * - * @see elgg_view_register_simplecache - * - */ - -function elgg_view_enable_simplecache() { -	global $CONFIG; - -	datalist_set('simplecache_enabled',1); -	$CONFIG->simplecache_enabled = 1; -	elgg_view_regenerate_simplecache(); -} - -/** - * Disables the simple cache. - * - * @see elgg_view_register_simplecache - * - */ -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); -		} -	} -} - -/**   * This is a factory function which produces an ElggCache object suitable for caching file load paths.   *   * TODO: Can this be done in a cleaner way? @@ -606,366 +165,6 @@ function elgg_disable_filepath_cache() {  }  /** - * Internal function for retrieving views used by elgg_view_tree - * - * @param unknown_type $dir - * @param unknown_type $base - * @return unknown - */ -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; -					} -				} -			} -		} -	} -	return $return; -} - -/** - * @deprecated 1.7.  Use elgg_get_views(). - * @param $dir - * @param $base - */ -function get_views($dir, $base) { -	elgg_deprecated_notice('get_views() was deprecated by elgg_get_views()!', 1.7); -	elgg_get_views($dir, $base); -} - -/** - * When given a partial view root (eg 'js' or 'page_elements'), returns an array of views underneath it - * - * @param string $view_root The root view - * @param string $viewtype Optionally specify a view type other than the current one. - * @return array A list of view names underneath that root view - */ -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]; -	} - -	// 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; -			} -		} -	} - -	// 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); -	} - -	return $treecache[$view_root]; -} - -/** - * When given an entity, views it intelligently. - * - * Expects a view to exist called entity-type/subtype, or for the entity to have a parameter - * 'view' which lists a different view to display.  In both cases, elgg_view will be called with - * array('entity' => $entity, 'full' => $full) as its parameters, and therefore this is what - * the view should expect to receive. - * - * @param ElggEntity $entity The entity to display - * @param boolean $full Determines whether or not to display the full version of an object, or a smaller version for use in aggregators etc - * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) - * @param boolean $debug If set to true, the viewer will complain if it can't find a view - * @return string HTML to display or false - */ -function elgg_view_entity(ElggEntity $entity, $full = false, $bypass = true, $debug = false) { -	global $autofeed; -	$autofeed = true; - -	// No point continuing if entity is null -	if (!$entity) { -		return ''; -	} - -	if (!($entity instanceof ElggEntity)) { -		return false; -	} - -	// if this entity has a view defined, use it -	$view = $entity->view; -	if (is_string($view)) { -		return elgg_view($view, -						array('entity' => $entity, 'full' => $full), -						$bypass, -						$debug); -	} - -	$entity_type = $entity->getType(); - -	$subtype = $entity->getSubtype(); -	if (empty($subtype)) { -		$subtype = $entity_type; -	} - -	$contents = ''; -	if (elgg_view_exists("{$entity_type}/{$subtype}")) { -		$contents = elgg_view("{$entity_type}/{$subtype}", array( -				'entity' => $entity, -				'full' => $full -				), $bypass, $debug); -	} -	if (empty($contents)) { -		$contents = elgg_view("{$entity_type}/default",array( -				'entity' => $entity, -				'full' => $full -				), $bypass, $debug); -	} -	// Marcus Povey 20090616 : Speculative and low impact approach for fixing #964 -	if ($full)  { -		$annotations = elgg_view_entity_annotations($entity, $full); - -		if ($annotations) { -			$contents .= $annotations; -		} -	} -	return $contents; -} - -/** - * When given an annotation, views it intelligently. - * - * This function expects annotation views to be of the form annotation/name, where name - * is the type of annotation. - * - * @param ElggAnnotation $annotation The annotation to display - * @param boolean $full Determines whether or not to display the full version of an object, or a smaller version for use in aggregators etc - * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) - * @param boolean $debug If set to true, the viewer will complain if it can't find a view - * @return string HTML (etc) to display - */ -function elgg_view_annotation(ElggAnnotation $annotation, $bypass = true, $debug = false) { -	global $autofeed; -	$autofeed = true; - -	$view = $annotation->view; -	if (is_string($view)) { -		return elgg_view($view,array('annotation' => $annotation), $bypass, $debug); -	} - -	$name = $annotation->name; -	$intname = (int) $name; -	if ("{$intname}" == "{$name}") { -		$name = get_metastring($intname); -	} -	if (empty($name)) { -		return ""; -	} - -	if (elgg_view_exists("annotation/{$name}")) { -		return elgg_view("annotation/{$name}",array('annotation' => $annotation), $bypass, $debug); -	} else { -		return elgg_view("annotation/default",array('annotation' => $annotation), $bypass, $debug); -	} -} - - -/** - * Returns a view of a list of entities, plus navigation. It is intended that this function - * be called from other wrapper functions. - * - * @see list_entities - * @see list_user_objects - * @see list_user_friends_objects - * @see list_entities_from_metadata - * @see list_entities_from_metadata_multi - * @see list_entities_from_relationships - * @see list_site_members - * - * @param array $entities List of entities - * @param int $count The total number of entities across all pages - * @param int $offset The current indexing offset - * @param int $limit The number of entities to display per page - * @param true|false $fullview Whether or not to display the full view (default: true) - * @param true|false $viewtypetoggle Whether or not to allow users to toggle to gallery view - * @param bool $pagination Whether pagination is offered. - * @return string The list of entities - */ -function elgg_view_entity_list($entities, $count, $offset, $limit, $fullview = true, $viewtypetoggle = true, $pagination = true) { -	$count = (int) $count; -	$limit = (int) $limit; - -	// do not require views to explicitly pass in the offset -	if (!$offset = (int) $offset) { -		$offset = sanitise_int(get_input('offset', 0)); -	} - -	// do not require views to explicitly pass in the offset -	if (!$offset = (int) $offset) { -		$offset = sanitise_int(get_input('offset', 0)); -	} - -	$context = get_context(); - -	$html = elgg_view('entities/entity_list',array( -		'entities' => $entities, -		'count' => $count, -		'offset' => $offset, -		'limit' => $limit, -		'baseurl' => $_SERVER['REQUEST_URI'], -		'fullview' => $fullview, -		'context' => $context, -		'viewtypetoggle' => $viewtypetoggle, -		'viewtype' => get_input('search_viewtype','list'), -		'pagination' => $pagination -	)); - -	return $html; -} - -/** - * Returns a view of a list of annotations, plus navigation. It is intended that this function - * be called from other wrapper functions. - * - * @param array $annotations List of annotations - * @param int $count The total number of annotations across all pages - * @param int $offset The current indexing offset - * @param int $limit The number of annotations to display per page - * @return string The list of annotations - */ -function elgg_view_annotation_list($annotations, $count, $offset, $limit) { -	$count = (int) $count; -	$offset = (int) $offset; -	$limit = (int) $limit; - -	$html = ""; - -	$nav = elgg_view('navigation/pagination',array( -		'baseurl' => $_SERVER['REQUEST_URI'], -		'offset' => $offset, -		'count' => $count, -		'limit' => $limit, -		'word' => 'annoff', -		'nonefound' => false, -	)); - -	$html .= $nav; - -	if (is_array($annotations) && sizeof($annotations) > 0) { -		foreach($annotations as $annotation) { -			$html .= elgg_view_annotation($annotation, "", false); -		} -	} - -	if ($count) { -		$html .= $nav; -	} - -	return $html; -} - -/** - * Display a selective rendered list of annotations for a given entity. - * - * The list is produced as the result of the entity:annotate plugin hook - * and is designed to provide a more generic framework to allow plugins - * to extend the generic display of entities with their own annotation - * renderings. - * - * This is called automatically by the framework from elgg_view_entity() - * - * @param ElggEntity $entity - * @param bool $full - * @return string or false on failure - */ -function elgg_view_entity_annotations(ElggEntity $entity, $full = true) { - -	// No point continuing if entity is null -	if (!$entity) { -		return false; -	} - -	if (!($entity instanceof ElggEntity)) { -		return false; -	} - -	$entity_type = $entity->getType(); - -	$annotations = trigger_plugin_hook('entity:annotate', $entity_type, -		array( -			'entity' => $entity, -			'full' => $full, -		) -	); - -	return $annotations; -} - -/** - * Displays an internal layout for the use of a plugin canvas. - * Takes a variable number of parameters, which are made available - * in the views as $vars['area1'] .. $vars['areaN']. - * - * @param string $layout The name of the views in canvas/layouts/. - * @return string The layout - */ -function elgg_view_layout($layout) { -	$arg = 1; -	$param_array = array(); -	while ($arg < func_num_args()) { -		$param_array['area' . $arg] = func_get_arg($arg); -		$arg++; -	} -	if (elgg_view_exists("canvas/layouts/{$layout}")) { -		return elgg_view("canvas/layouts/{$layout}",$param_array); -	} else { -		return elgg_view("canvas/default",$param_array); -	} -} - -/** - * Returns a view for the page title - * - * @param string $title The page title - * @param string $submenu Should a submenu be displayed? (default false, use not recommended) - * @return string The HTML (etc) - */ -function elgg_view_title($title, $submenu = false) { -	$title = elgg_view('page_elements/title', array('title' => $title, 'submenu' => $submenu)); - -	return $title; -} - -/**   * Deprecated by elgg_add_submenu_item()   *   * @see elgg_add_submenu_item() @@ -1297,30 +496,6 @@ function elgg_count_likes($entity) {  }  /** - * Automatically views comments and a comment form relating to the given entity - * - * @param ElggEntity $entity The entity to comment on - * @return string|false The HTML (etc) for the comments, or false on failure - */ -function elgg_view_comments($entity){ - -	if (!($entity instanceof ElggEntity)) { -		return false; -	} - -	if ($comments = trigger_plugin_hook('comments',$entity->getType(),array('entity' => $entity),false)) { -		return $comments; -	} else { -		$comments = list_annotations($entity->getGUID(),'generic_comment'); - -		//display the comment form -		$comments .= elgg_view('comments/forms/edit',array('entity' => $entity)); - -		return $comments; -	} -} - -/**   * Count the number of comments attached to an entity   *   * @param ElggEntity $entity @@ -1335,221 +510,7 @@ function elgg_count_comments($entity) {  	}  } -/** - * Wrapper function to display search listings. - * - * @param string $icon The icon for the listing - * @param string $info Any information that needs to be displayed. - * @return string The HTML (etc) representing the listing - */ -function elgg_view_listing($icon, $info) { -	return elgg_view('entities/entity_listing',array('icon' => $icon, 'info' => $info)); -} -/** - * Sets an alternative function to handle templates, which will be passed to by elgg_view. - * This function must take the $view and $vars parameters from elgg_view: - * - * 		function my_template_function(string $view, array $vars = array()) - * - * @see elgg_view - * - * @param string $function_name The name of the function to pass to. - * @return true|false - */ -function set_template_handler($function_name) { -	global $CONFIG; -	if (!empty($function_name) && is_callable($function_name)) { -		$CONFIG->template_handler = $function_name; -		return true; -	} -	return false; -} - -/** - * Extends a view. - * - * The addititional views are displayed before or after the primary view. - * Priorities less than 500 are displayed before the primary view and - * greater than 500 after. The default priority is 501. - * - * @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 - */ -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 - */ -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; -	} - -	unset($CONFIG->views->extensions[$view][$priority]); - -	return TRUE; -} - -/** - * @deprecated 1.7.  Use elgg_extend_view(). - * @param $view - * @param $view_name - * @param $priority - * @param $viewtype - */ -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); -} - -/** - * Set an alternative base location for a view (as opposed to the default of $CONFIG->viewpath) - * - * @param string $view The name of the view - * @param string $location The base location path - */ -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; -	} -} - -/** - * Auto-registers views from a particular starting location - * - * @param string $view_base The base of the view name - * @param string $folder The folder to begin looking in - * @param string $base_location_path The base views directory to use with set_view_location - * @param string $viewtype The type of view we're looking at (default, rss, etc) - */ -function autoregister_views($view_base, $folder, $base_location_path, $viewtype) { -	if (!isset($i)) { -		$i = 0; -	} - -	if ($handle = opendir($folder)) { -		while ($view = readdir($handle)) { -			if (!in_array($view,array('.','..','.svn','CVS')) && !is_dir($folder . "/" . $view)) { -				// this includes png files because some icons are stored within view directories. -				// See commit [1705] -				if ((substr_count($view,".php") > 0) || (substr_count($view,".png") > 0)) { -					if (!empty($view_base)) { -						$view_base_new = $view_base . "/"; -					} else { -						$view_base_new = ""; -					} - -					set_view_location($view_base_new . str_replace('.php', '', $view), $base_location_path, $viewtype); -				} -			} else if (!in_array($view, array('.', '..', '.svn', 'CVS')) && is_dir($folder . "/" . $view)) { -				if (!empty($view_base)) { -					$view_base_new = $view_base . "/"; -				} else { -					$view_base_new = ""; -				} -				autoregister_views($view_base_new . $view, $folder . "/" . $view, $base_location_path, $viewtype); -			} -		} -		return TRUE; -	} - -	return FALSE; -} - -/** - * Returns a representation of a full 'page' (which might be an HTML page, RSS file, etc, depending on the current view) - * - * @param unknown_type $title - * @param unknown_type $body - * @return unknown - */ -function page_draw($title, $body, $sidebar = "") { - -	// 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, ""); -	} - -	// Draw the page -	$output = elgg_view('page_shells/default', array( -		'title' => $title, -		'body' => $body, -		'sidebar' => $sidebar, -		'sysmessages' => $sysmessages, -		) -	); - -	$split_output = str_split($output, 1024); - -	foreach($split_output as $chunk) { -		echo $chunk; -	} -}  /**   * Library loading and handling @@ -3218,19 +2179,6 @@ function elgg_init() {  	// Register an event triggered at system shutdown  	register_shutdown_function('__elgg_shutdown_hook'); - -	// discover the built-in view types -	// @todo cache this -	$view_path = $CONFIG->viewpath; -	$CONFIG->view_types = array(); - -	$views = scandir($view_path); - -	foreach ($views as $view) { -		if ('.' !== substr($view, 0, 1) && is_dir($view_path . $view)) { -			$CONFIG->view_types[] = $view; -		} -	}  }  function elgg_walled_garden_index() { @@ -3250,6 +2198,8 @@ function elgg_walled_garden_index() {   * @return unknown_type   */  function elgg_boot() { +	global $CONFIG; +  	// Actions  	register_action('comments/add');  	register_action('comments/delete'); @@ -3259,6 +2209,20 @@ function elgg_boot() {  	elgg_view_register_simplecache('css');  	elgg_view_register_simplecache('js/friendsPickerv1');  	elgg_view_register_simplecache('js/initialise_elgg'); + +	// discover the built-in view types +	// @todo cache this +	$view_path = $CONFIG->viewpath; +	$CONFIG->view_types = array(); + +	$views = scandir($view_path); + +	foreach ($views as $view) { +		if ('.' !== substr($view, 0, 1) && is_dir($view_path . $view)) { +			$CONFIG->view_types[] = $view; +		} +	} +  }  /** @@ -3432,19 +2396,6 @@ function elgg_walled_garden() {  }  /** - * Checks if $view_type is valid on this installation. - * - * @param string $view_type - * @return bool - * @since 1.7 - */ -function elgg_is_valid_view_type($view_type) { -	global $CONFIG; - -	return in_array($view_type, $CONFIG->view_types); -} - -/**   * Checks for $array[$key] and returns its value if it exists, else   * returns $default.   * diff --git a/engine/lib/views.php b/engine/lib/views.php new file mode 100644 index 000000000..b7dc2016c --- /dev/null +++ b/engine/lib/views.php @@ -0,0 +1,1053 @@ +<?php  +/** + * Provides interfaces for Elgg's views system + *  + * @package Elgg + */ + +$CURRENT_SYSTEM_VIEWTYPE = ""; + +/** + * Override the view mode detection for the elgg view system. + * + * This function will force any further views to be rendered using $viewtype. Remember to call elgg_set_viewtype() with + * no parameters to reset. + * + * @param string $viewtype The view type, e.g. 'rss', or 'default'. + * @return bool + */ +function elgg_set_viewtype($viewtype = "") { +	global $CURRENT_SYSTEM_VIEWTYPE; + +	$CURRENT_SYSTEM_VIEWTYPE = $viewtype; + +	return true; +} + +/** + * Return the current view type used by the elgg view system. + * + * By default, this function will return a value based on the default for your system or from the command line + * view parameter. However, you may force a given view type by calling elgg_set_viewtype() + * + * @return string The view. + */ +function elgg_get_viewtype() { +	global $CURRENT_SYSTEM_VIEWTYPE, $CONFIG; + +	$viewtype = NULL; + +	if ($CURRENT_SYSTEM_VIEWTYPE != "") { +		return $CURRENT_SYSTEM_VIEWTYPE; +	} + +	if ((empty($_SESSION['view'])) || ( (trim($CONFIG->view!="")) && ($_SESSION['view']!=$CONFIG->view) )) { +		$_SESSION['view'] = "default"; +		// If we have a config default view for this site then use that instead of 'default' +		if (/*(is_installed()) && */(!empty($CONFIG->view)) && (trim($CONFIG->view)!="")) { +			$_SESSION['view'] = $CONFIG->view; +		} +	} + +	if (empty($viewtype) && is_callable('get_input')) { +		$viewtype = get_input('view'); +	} + +	if (empty($viewtype)) { +		$viewtype = $_SESSION['view']; +	} + +	return $viewtype; +} + +/** + * Register a viewtype to fall back to a default view if view does not exist in + * that viewtype. + * + * This is useful for alternate html viewtypes (such as for mobile devices) + * + * @param string $viewtype The viewtype to register + */ +function elgg_register_viewtype_fallback($viewtype) { +	global $CONFIG; + +	if (!isset($CONFIG->viewtype)) { +		$CONFIG->viewtype = new stdClass; +	} + +	if (!isset($CONFIG->viewtype->fallback)) { +		$CONFIG->viewtype->fallback = array(); +	} + +	$CONFIG->viewtype->fallback[] = $viewtype; +} + +/** + * Checks if this viewtype falls back to default + * + * @param string $viewtype + * @return boolean + */ +function elgg_does_viewtype_fallback($viewtype) { +	global $CONFIG; + +	if (isset($CONFIG->viewtype) && isset($CONFIG->viewtype->fallback)) { +		return in_array($viewtype, $CONFIG->viewtype->fallback); +	} +	 +	return FALSE; +} + + +/** + * Return the location of a given view. + * + * @param string $view The view. + * @param string $viewtype The viewtype + */ +function elgg_get_view_location($view, $viewtype = '') { +	global $CONFIG; + +	if (empty($viewtype)) { +		$viewtype = elgg_get_viewtype(); +	} + +	if (!isset($CONFIG->views->locations[$viewtype][$view])) { +		if (!isset($CONFIG->viewpath)) { +			return dirname(dirname(dirname(__FILE__))) . "/views/"; +		} else { +			return $CONFIG->viewpath; +		} +	} else { +		return $CONFIG->views->locations[$viewtype][$view]; +	} + +	return false; +} + +/** + * Handles templating views + * + * @see set_template_handler + * + * @param string $view The name and location of the view to use + * @param array $vars Any variables that the view requires, passed as an array + * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) + * @param boolean $debug If set to true, the viewer will complain if it can't find a view + * @param string $viewtype If set, forces the viewtype for the elgg_view call to be this value (default: standard detection) + * @return string The HTML content + */ +function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $viewtype = '') { +	global $CONFIG; +	static $usercache; + +	$view = (string)$view; + +	// basic checking for bad paths +	if (strpos($view, '..') !== false) { +		return false; +	} + +	$view_orig = $view; + +	// Trigger the pagesetup event +	if (!isset($CONFIG->pagesetupdone)) { +		trigger_elgg_event('pagesetup','system'); +		$CONFIG->pagesetupdone = true; +	} + +	if (!is_array($usercache)) { +		$usercache = array(); +	} + +	if (!is_array($vars)) { +		elgg_log('Vars in views must be an array!', 'ERROR'); +		$vars = array(); +	} + +	if (empty($vars)) { +		$vars = array(); +	} + +	// Load session and configuration variables into $vars +	// $_SESSION will always be an array if it is set +	if (isset($_SESSION) /*&& is_array($_SESSION)*/ ) { +		//= array_merge($vars, $_SESSION); +		$vars += $_SESSION; +	} + +	$vars['config'] = array(); + +	if (!empty($CONFIG)) { +		$vars['config'] = $CONFIG; +	} + +	$vars['url'] = $CONFIG->url; + +	// Load page owner variables into $vars +	if (is_callable('page_owner')) { +		$vars['page_owner'] = page_owner(); +	} else { +		$vars['page_owner'] = -1; +	} + +	if (($vars['page_owner'] != -1) && (is_installed())) { +		if (!isset($usercache[$vars['page_owner']])) { +			$vars['page_owner_user'] = get_entity($vars['page_owner']); +			$usercache[$vars['page_owner']] = $vars['page_owner_user']; +		} else { +			$vars['page_owner_user'] = $usercache[$vars['page_owner']]; +		} +	} + +	if (!isset($vars['js'])) { +		$vars['js'] = ""; +	} + +	// If it's been requested, pass off to a template handler instead +	if ($bypass == false && isset($CONFIG->template_handler) && !empty($CONFIG->template_handler)) { +		$template_handler = $CONFIG->template_handler; +		if (is_callable($template_handler)) { +			return $template_handler($view, $vars); +		} +	} + +	// Get the current viewtype +	if (empty($viewtype)) { +		$viewtype = elgg_get_viewtype(); +	} + +	// Viewtypes can only be alphanumeric  +	if (preg_match('[\W]', $viewtype)) { +		return '';  +	}  + +	// Set up any extensions to the requested view +	if (isset($CONFIG->views->extensions[$view])) { +		$viewlist = $CONFIG->views->extensions[$view]; +	} else { +		$viewlist = array(500 => $view); +	} +	// Start the output buffer, find the requested view file, and execute it +	ob_start(); + +	foreach($viewlist as $priority => $view) { +		$view_location = elgg_get_view_location($view, $viewtype); +		$view_file = "$view_location$viewtype/$view.php"; +		 +		$default_location = elgg_get_view_location($view, 'default'); +		$default_view_file = "{$default_location}default/$view.php"; +		 +		// try to include view +		if (!file_exists($view_file) || !include($view_file)) { +			// requested view does not exist +			$error = "$viewtype/$view view does not exist."; + +			// attempt to load default view +			if ($viewtype != 'default' && elgg_does_viewtype_fallback($viewtype)) { +				if (file_exists($default_view_file) && include($default_view_file)) { +					// default view found +					$error .= " Using default/$view instead."; +				} else { +					// no view found at all +					$error = "Neither $viewtype/$view nor default/$view view exists."; +				} +			} + +			// log warning +			elgg_log($error, 'NOTICE'); +		} +	} + +	// Save the output buffer into the $content variable +	$content = ob_get_clean(); + +	// Plugin hook +	$content = trigger_plugin_hook('view', $view_orig, +		array('view' => $view_orig, 'vars' => $vars), $content); + +	// backward compatibility with less grandular hook will be gone in 2.0 +	$content_tmp = trigger_plugin_hook('display', 'view', array('view' => $view_orig, 'vars' => $vars), $content); + +	if ($content_tmp != $content) { +		$content = $content_tmp; +		elgg_deprecated_notice('The display:view plugin hook is deprecated by view:view_name or view:all', 1.8); +	} + +	// Return $content +	return $content; +} + +/** + * Returns whether the specified view exists + * + * @param string $view The view name + * @param string $viewtype If set, forces the viewtype + * @param bool $recurse If false, do not recursively check extensions + * @return true|false Depending on success + */ +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 be simply cached + * + * Views cached in this manner must take no parameters and be login agnostic - + * that is to say, they look the same no matter who is logged in (or logged out). + * + * CSS and the basic jS views are automatically cached like this. + * + * @param string $viewname View name + */ +function elgg_view_register_simplecache($viewname) { +	global $CONFIG; + +	if (!isset($CONFIG->views)) { +		$CONFIG->views = new stdClass; +	} + +	if (!isset($CONFIG->views->simplecache)) { +		$CONFIG->views->simplecache = array(); +	} + +	//if (elgg_view_exists($viewname)) +	$CONFIG->views->simplecache[] = $viewname; +} + +/** + * Regenerates the simple cache. + * + * @param string $viewtype Optional viewtype to regenerate + * @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); +	} + +	elgg_set_viewtype($original_viewtype); + +	unset($CONFIG->pagesetupdone); +} + +/** + * Enables the simple cache. + * + * @see elgg_view_register_simplecache + * + */ + +function elgg_view_enable_simplecache() { +	global $CONFIG; + +	datalist_set('simplecache_enabled',1); +	$CONFIG->simplecache_enabled = 1; +	elgg_view_regenerate_simplecache(); +} + +/** + * Disables the simple cache. + * + * @see elgg_view_register_simplecache + * + */ +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); +		} +	} +} + + +/** + * Internal function for retrieving views used by elgg_view_tree + * + * @param unknown_type $dir + * @param unknown_type $base + * @return unknown + */ +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; +					} +				} +			} +		} +	} +	return $return; +} + +/** + * @deprecated 1.7.  Use elgg_get_views(). + * @param $dir + * @param $base + */ +function get_views($dir, $base) { +	elgg_deprecated_notice('get_views() was deprecated by elgg_get_views()!', 1.7); +	elgg_get_views($dir, $base); +} + +/** + * When given a partial view root (eg 'js' or 'page_elements'), returns an array of views underneath it + * + * @param string $view_root The root view + * @param string $viewtype Optionally specify a view type other than the current one. + * @return array A list of view names underneath that root view + */ +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]; +	} + +	// 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; +			} +		} +	} + +	// 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); +	} + +	return $treecache[$view_root]; +} + +/** + * When given an entity, views it intelligently. + * + * Expects a view to exist called entity-type/subtype, or for the entity to have a parameter + * 'view' which lists a different view to display.  In both cases, elgg_view will be called with + * array('entity' => $entity, 'full' => $full) as its parameters, and therefore this is what + * the view should expect to receive. + * + * @param ElggEntity $entity The entity to display + * @param boolean $full Determines whether or not to display the full version of an object, or a smaller version for use in aggregators etc + * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) + * @param boolean $debug If set to true, the viewer will complain if it can't find a view + * @return string HTML to display or false + */ +function elgg_view_entity(ElggEntity $entity, $full = false, $bypass = true, $debug = false) { +	global $autofeed; +	$autofeed = true; + +	// No point continuing if entity is null +	if (!$entity) { +		return ''; +	} + +	if (!($entity instanceof ElggEntity)) { +		return false; +	} + +	// if this entity has a view defined, use it +	$view = $entity->view; +	if (is_string($view)) { +		return elgg_view($view, +						array('entity' => $entity, 'full' => $full), +						$bypass, +						$debug); +	} + +	$entity_type = $entity->getType(); + +	$subtype = $entity->getSubtype(); +	if (empty($subtype)) { +		$subtype = $entity_type; +	} + +	$contents = ''; +	if (elgg_view_exists("{$entity_type}/{$subtype}")) { +		$contents = elgg_view("{$entity_type}/{$subtype}", array( +				'entity' => $entity, +				'full' => $full +				), $bypass, $debug); +	} +	if (empty($contents)) { +		$contents = elgg_view("{$entity_type}/default",array( +				'entity' => $entity, +				'full' => $full +				), $bypass, $debug); +	} +	// Marcus Povey 20090616 : Speculative and low impact approach for fixing #964 +	if ($full)  { +		$annotations = elgg_view_entity_annotations($entity, $full); + +		if ($annotations) { +			$contents .= $annotations; +		} +	} +	return $contents; +} + +/** + * When given an annotation, views it intelligently. + * + * This function expects annotation views to be of the form annotation/name, where name + * is the type of annotation. + * + * @param ElggAnnotation $annotation The annotation to display + * @param boolean $full Determines whether or not to display the full version of an object, or a smaller version for use in aggregators etc + * @param boolean $bypass If set to true, elgg_view will bypass any specified alternative template handler; by default, it will hand off to this if requested (see set_template_handler) + * @param boolean $debug If set to true, the viewer will complain if it can't find a view + * @return string HTML (etc) to display + */ +function elgg_view_annotation(ElggAnnotation $annotation, $bypass = true, $debug = false) { +	global $autofeed; +	$autofeed = true; + +	$view = $annotation->view; +	if (is_string($view)) { +		return elgg_view($view,array('annotation' => $annotation), $bypass, $debug); +	} + +	$name = $annotation->name; +	$intname = (int) $name; +	if ("{$intname}" == "{$name}") { +		$name = get_metastring($intname); +	} +	if (empty($name)) { +		return ""; +	} + +	if (elgg_view_exists("annotation/{$name}")) { +		return elgg_view("annotation/{$name}",array('annotation' => $annotation), $bypass, $debug); +	} else { +		return elgg_view("annotation/default",array('annotation' => $annotation), $bypass, $debug); +	} +} + + +/** + * Returns a view of a list of entities, plus navigation. It is intended that this function + * be called from other wrapper functions. + * + * @see list_entities + * @see list_user_objects + * @see list_user_friends_objects + * @see list_entities_from_metadata + * @see list_entities_from_metadata_multi + * @see list_entities_from_relationships + * @see list_site_members + * + * @param array $entities List of entities + * @param int $count The total number of entities across all pages + * @param int $offset The current indexing offset + * @param int $limit The number of entities to display per page + * @param true|false $fullview Whether or not to display the full view (default: true) + * @param true|false $viewtypetoggle Whether or not to allow users to toggle to gallery view + * @param bool $pagination Whether pagination is offered. + * @return string The list of entities + */ +function elgg_view_entity_list($entities, $count, $offset, $limit, $fullview = true, $viewtypetoggle = true, $pagination = true) { +	$count = (int) $count; +	$limit = (int) $limit; +	 +	// do not require views to explicitly pass in the offset +	if (!$offset = (int) $offset) { +		$offset = sanitise_int(get_input('offset', 0)); +	} + +	$context = get_context(); + +	$html = elgg_view('entities/entity_list',array( +		'entities' => $entities, +		'count' => $count, +		'offset' => $offset, +		'limit' => $limit, +		'baseurl' => $_SERVER['REQUEST_URI'], +		'fullview' => $fullview, +		'context' => $context, +		'viewtypetoggle' => $viewtypetoggle, +		'viewtype' => get_input('search_viewtype','list'), +		'pagination' => $pagination +	)); + +	return $html; +} + +/** + * Returns a view of a list of annotations, plus navigation. It is intended that this function + * be called from other wrapper functions. + * + * @param array $annotations List of annotations + * @param int $count The total number of annotations across all pages + * @param int $offset The current indexing offset + * @param int $limit The number of annotations to display per page + * @return string The list of annotations + */ +function elgg_view_annotation_list($annotations, $count, $offset, $limit) { +	$count = (int) $count; +	$offset = (int) $offset; +	$limit = (int) $limit; + +	$html = ""; + +	$nav = elgg_view('navigation/pagination',array( +		'baseurl' => $_SERVER['REQUEST_URI'], +		'offset' => $offset, +		'count' => $count, +		'limit' => $limit, +		'word' => 'annoff', +		'nonefound' => false, +	)); + +	$html .= $nav; + +	if (is_array($annotations) && sizeof($annotations) > 0) { +		foreach($annotations as $annotation) { +			$html .= elgg_view_annotation($annotation, "", false); +		} +	} + +	if ($count) { +		$html .= $nav; +	} + +	return $html; +} + +/** + * Display a selective rendered list of annotations for a given entity. + * + * The list is produced as the result of the entity:annotate plugin hook + * and is designed to provide a more generic framework to allow plugins + * to extend the generic display of entities with their own annotation + * renderings. + * + * This is called automatically by the framework from elgg_view_entity() + * + * @param ElggEntity $entity + * @param bool $full + * @return string or false on failure + */ +function elgg_view_entity_annotations(ElggEntity $entity, $full = true) { + +	// No point continuing if entity is null +	if (!$entity) { +		return false; +	} + +	if (!($entity instanceof ElggEntity)) { +		return false; +	} + +	$entity_type = $entity->getType(); + +	$annotations = trigger_plugin_hook('entity:annotate', $entity_type, +		array( +			'entity' => $entity, +			'full' => $full, +		) +	); + +	return $annotations; +} + +/** + * Displays an internal layout for the use of a plugin canvas. + * Takes a variable number of parameters, which are made available + * in the views as $vars['area1'] .. $vars['areaN']. + * + * @param string $layout The name of the views in canvas/layouts/. + * @return string The layout + */ +function elgg_view_layout($layout) { +	$arg = 1; +	$param_array = array(); +	while ($arg < func_num_args()) { +		$param_array['area' . $arg] = func_get_arg($arg); +		$arg++; +	} + +	if (elgg_view_exists("canvas/layouts/{$layout}")) { +		return elgg_view("canvas/layouts/{$layout}",$param_array); +	} else { +		return elgg_view("canvas/default",$param_array); +	} +} + +/** + * Returns a view for the page title + * + * @param string $title The page title + * @param string $submenu Should a submenu be displayed? (default false, use not recommended) + * @return string The HTML (etc) + */ +function elgg_view_title($title, $submenu = false) { +	$title = elgg_view('page_elements/title', array('title' => $title, 'submenu' => $submenu)); + +	return $title; +} + + +/** + * Automatically views comments and a comment form relating to the given entity + * + * @param ElggEntity $entity The entity to comment on + * @return string|false The HTML (etc) for the comments, or false on failure + */ +function elgg_view_comments($entity){ + +	if (!($entity instanceof ElggEntity)) { +		return false; +	} + +	if ($comments = trigger_plugin_hook('comments',$entity->getType(),array('entity' => $entity),false)) { +		return $comments; +	} else { +		$comments = list_annotations($entity->getGUID(),'generic_comment'); + +		//display the comment form +		$comments .= elgg_view('comments/forms/edit',array('entity' => $entity)); + +		return $comments; +	} +} + + +/** + * Wrapper function to display search listings. + * + * @param string $icon The icon for the listing + * @param string $info Any information that needs to be displayed. + * @return string The HTML (etc) representing the listing + */ +function elgg_view_listing($icon, $info) { +	return elgg_view('entities/entity_listing',array('icon' => $icon, 'info' => $info)); +} + +/** + * Sets an alternative function to handle templates, which will be passed to by elgg_view. + * This function must take the $view and $vars parameters from elgg_view: + * + * 		function my_template_function(string $view, array $vars = array()) + * + * @see elgg_view + * + * @param string $function_name The name of the function to pass to. + * @return true|false + */ +function set_template_handler($function_name) { +	global $CONFIG; +	if (!empty($function_name) && is_callable($function_name)) { +		$CONFIG->template_handler = $function_name; +		return true; +	} +	return false; +} + +/** + * Extends a view. + * + * The addititional views are displayed before or after the primary view.  + * Priorities less than 500 are displayed before the primary view and  + * greater than 500 after. The default priority is 501.  + * + * @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 + */ +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 + */ +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; +	} + +	unset($CONFIG->views->extensions[$view][$priority]); +	 +	return TRUE; +} + +/** + * @deprecated 1.7.  Use elgg_extend_view(). + * @param $view + * @param $view_name + * @param $priority + * @param $viewtype + */ +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); +} + +/** + * Set an alternative base location for a view (as opposed to the default of $CONFIG->viewpath) + * + * @param string $view The name of the view + * @param string $location The base location path + */ +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; +	} +} + +/** + * Auto-registers views from a particular starting location + * + * @param string $view_base The base of the view name + * @param string $folder The folder to begin looking in + * @param string $base_location_path The base views directory to use with set_view_location + * @param string $viewtype The type of view we're looking at (default, rss, etc) + */ +function autoregister_views($view_base, $folder, $base_location_path, $viewtype) { +	if (!isset($i)) { +		$i = 0; +	} + +	if ($handle = opendir($folder)) { +		while ($view = readdir($handle)) { +			if (!in_array($view,array('.','..','.svn','CVS')) && !is_dir($folder . "/" . $view)) { +				// this includes png files because some icons are stored within view directories. +				// See commit [1705] +				if ((substr_count($view,".php") > 0) || (substr_count($view,".png") > 0)) { +					if (!empty($view_base)) { +						$view_base_new = $view_base . "/"; +					} else { +						$view_base_new = ""; +					} + +					set_view_location($view_base_new . str_replace('.php', '', $view), $base_location_path, $viewtype); +				} +			} else if (!in_array($view, array('.', '..', '.svn', 'CVS')) && is_dir($folder . "/" . $view)) { +				if (!empty($view_base)) { +					$view_base_new = $view_base . "/"; +				} else { +					$view_base_new = ""; +				} +				autoregister_views($view_base_new . $view, $folder . "/" . $view, $base_location_path, $viewtype); +			} +		} +		return TRUE; +	} + +	return FALSE; +} + +/** + * Returns a representation of a full 'page' (which might be an HTML page, RSS file, etc, depending on the current view) + * + * @param unknown_type $title + * @param unknown_type $body + * @return unknown + */ +function page_draw($title, $body, $sidebar = "") { + +	// 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, ""); +	} + +	// Draw the page +	$output = elgg_view('page_shells/default', array( +		'title' => $title, +		'body' => $body, +		'sidebar' => $sidebar, +		'sysmessages' => $sysmessages, +		) +	); +	$split_output = str_split($output, 1024); + +	foreach($split_output as $chunk) { +		echo $chunk; +	} +} + +/** + * Checks if $view_type is valid on this installation. + * + * @param string $view_type + * @return bool + */ +function elgg_is_valid_view_type($view_type) { +	global $CONFIG; + +	return in_array($view_type, $CONFIG->view_types); +}
\ No newline at end of file diff --git a/engine/start.php b/engine/start.php index f5d3ce5e4..569fd3f83 100644 --- a/engine/start.php +++ b/engine/start.php @@ -27,7 +27,7 @@ $lib_dir = dirname(__FILE__) . '/lib/';  // bootstrapping with required files in a required order  $required_files = array( -	'exceptions.php', 'elgglib.php', 'access.php', 'system_log.php', 'export.php', +	'exceptions.php', 'elgglib.php', 'views.php', 'access.php', 'system_log.php', 'export.php',  	'sessions.php', 'languages.php', 'input.php', 'install.php', 'cache.php', 'output.php'  ); | 
