PageRenderTime 27ms CodeModel.GetById 3ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/engine/lib/views.php

https://github.com/fragilbert/Elgg
PHP | 1461 lines | 566 code | 156 blank | 739 comment | 114 complexity | 540b2c0e6324e2c97cb536dcc64771a0 MD5 | raw file
   1<?php
   2/**
   3 * Elgg's view system.
   4 *
   5 * The view system is the primary templating engine in Elgg and renders
   6 * all output.  Views are short, parameterised PHP scripts for displaying
   7 * output that can be regsitered, overridden, or extended.  The view type
   8 * determines the output format and location of the files that renders the view.
   9 *
  10 * Elgg uses a two step process to render full output: first
  11 * content-specific elements are rendered, then the resulting
  12 * content is inserted into a layout and displayed.  This makes it
  13 * easy to maintain a consistent look on all pages.
  14 *
  15 * A view corresponds to a single file on the filesystem and the views
  16 * name is its directory structure.  A file in
  17 * <code>mod/plugins/views/default/myplugin/example.php</code>
  18 * is called by saying (with the default viewtype):
  19 * <code>echo elgg_view('myplugin/example');</code>
  20 *
  21 * View names that are registered later override those that are
  22 * registered earlier.  For plugins this corresponds directly
  23 * to their load order: views in plugins lower in the list override
  24 * those higher in the list.
  25 *
  26 * Plugin views belong in the views/ directory under an appropriate
  27 * viewtype.  Views are automatically registered.
  28 *
  29 * Views can be embedded-you can call a view from within a view.
  30 * Views can also be prepended or extended by any other view.
  31 *
  32 * Any view can extend any other view if registered with
  33 * {@link elgg_extend_view()}.
  34 *
  35 * Viewtypes are set by passing $_REQUEST['view'].  The viewtype
  36 * 'default' is a standard HTML view.  Types can be defined on the fly
  37 * and you can get the current viewtype with {@link elgg_get_viewtype()}.
  38 *
  39 * @internal Plugin views are autoregistered before their init functions
  40 * are called, so the init order doesn't affect views.
  41 *
  42 * @internal The file that determines the output of the view is the last
  43 * registered by {@link elgg_set_view_location()}.
  44 *
  45 * @package Elgg.Core
  46 * @subpackage Views
  47 * @link http://docs.elgg.org/Views
  48 */
  49
  50/**
  51 * The viewtype override.
  52 *
  53 * @global string $CURRENT_SYSTEM_VIEWTYPE
  54 * @see elgg_set_viewtype()
  55 */
  56global $CURRENT_SYSTEM_VIEWTYPE;
  57$CURRENT_SYSTEM_VIEWTYPE = "";
  58
  59/**
  60 * Manually set the viewtype.
  61 *
  62 * View types are detected automatically.  This function allows
  63 * you to force subsequent views to use a different viewtype.
  64 *
  65 * @tip Call elgg_set_viewtype() with no parameter to reset.
  66 *
  67 * @param string $viewtype The view type, e.g. 'rss', or 'default'.
  68 *
  69 * @return bool
  70 * @link http://docs.elgg.org/Views/Viewtype
  71 * @example views/viewtype.php
  72 */
  73function elgg_set_viewtype($viewtype = "") {
  74	global $CURRENT_SYSTEM_VIEWTYPE;
  75
  76	$CURRENT_SYSTEM_VIEWTYPE = $viewtype;
  77
  78	return true;
  79}
  80
  81/**
  82 * Return the current view type.
  83 *
  84 * Viewtypes are automatically detected and can be set with $_REQUEST['view']
  85 * or {@link elgg_set_viewtype()}.
  86 *
  87 * @internal Viewtype is determined in this order:
  88 *  - $CURRENT_SYSTEM_VIEWTYPE Any overrides by {@link elgg_set_viewtype()}
  89 *  - $CONFIG->view  The default view as saved in the DB.
  90 *
  91 * @return string The view.
  92 * @see elgg_set_viewtype()
  93 * @link http://docs.elgg.org/Views
  94 */
  95function elgg_get_viewtype() {
  96	global $CURRENT_SYSTEM_VIEWTYPE, $CONFIG;
  97
  98	if ($CURRENT_SYSTEM_VIEWTYPE != "") {
  99		return $CURRENT_SYSTEM_VIEWTYPE;
 100	}
 101
 102	$viewtype = get_input('view', '', false);
 103	if (_elgg_is_valid_viewtype($viewtype)) {
 104		return $viewtype;
 105	}
 106
 107	if (isset($CONFIG->view) && _elgg_is_valid_viewtype($CONFIG->view)) {
 108		return $CONFIG->view;
 109	}
 110
 111	return 'default';
 112}
 113
 114/**
 115 * Register a viewtype.
 116 *
 117 * @param string $viewtype The view type to register
 118 * @return bool
 119 */
 120function elgg_register_viewtype($viewtype) {
 121	global $CONFIG;
 122
 123	if (!isset($CONFIG->view_types) || !is_array($CONFIG->view_types)) {
 124		$CONFIG->view_types = array();
 125	}
 126
 127	if (!in_array($viewtype, $CONFIG->view_types)) {
 128		$CONFIG->view_types[] = $viewtype;
 129	}
 130
 131	return true;
 132}
 133
 134/**
 135 * Checks if $viewtype is registered.
 136 *
 137 * @param string $viewtype The viewtype name
 138 *
 139 * @return bool
 140 * @since 1.9.0
 141 */
 142function elgg_is_registered_viewtype($viewtype) {
 143	global $CONFIG;
 144
 145	if (!isset($CONFIG->view_types) || !is_array($CONFIG->view_types)) {
 146		return FALSE;
 147	}
 148
 149	return in_array($viewtype, $CONFIG->view_types);
 150}
 151
 152
 153/**
 154 * Checks if $viewtype is a string suitable for use as a viewtype name
 155 *
 156 * @param string $viewtype Potential viewtype name. Alphanumeric chars plus _ allowed.
 157 *
 158 * @return bool
 159 * @access private
 160 * @since 1.9
 161 */
 162function _elgg_is_valid_viewtype($viewtype) {
 163	if (!is_string($viewtype) || $viewtype === '') {
 164		return false;
 165	}
 166
 167	if (preg_match('/\W/', $viewtype)) {
 168		return false;
 169	}
 170
 171	return true;
 172}
 173
 174/**
 175 * Register a viewtype to fall back to a default view if a view isn't
 176 * found for that viewtype.
 177 *
 178 * @tip This is useful for alternate html viewtypes (such as for mobile devices).
 179 *
 180 * @param string $viewtype The viewtype to register
 181 *
 182 * @return void
 183 * @since 1.7.2
 184 * @example views/viewtype_fallback.php Fallback from mobile to default.
 185 */
 186function elgg_register_viewtype_fallback($viewtype) {
 187	_elgg_services()->views->registerViewtypeFallback($viewtype);
 188}
 189
 190/**
 191 * Checks if a viewtype falls back to default.
 192 *
 193 * @param string $viewtype Viewtype
 194 *
 195 * @return boolean
 196 * @since 1.7.2
 197 */
 198function elgg_does_viewtype_fallback($viewtype) {
 199	return _elgg_services()->views->doesViewtypeFallback($viewtype);
 200}
 201
 202/**
 203 * Register a view to be available for ajax calls
 204 *
 205 * @param string $view The view name
 206 * @return void
 207 * @since 1.8.3
 208 */
 209function elgg_register_ajax_view($view) {
 210	elgg_register_external_view($view, false);
 211}
 212
 213/**
 214 * Unregister a view for ajax calls
 215 * 
 216 * @param string $view The view name
 217 * @return void
 218 * @since 1.8.3
 219 */
 220function elgg_unregister_ajax_view($view) {
 221	elgg_unregister_external_view($view);
 222}
 223
 224/**
 225 * Registers a view as being available externally (i.e. via URL).
 226 *
 227 * @param string  $view      The name of the view.
 228 * @param boolean $cacheable Whether this view can be cached.
 229 * @since 1.9.0
 230 */
 231function elgg_register_external_view($view, $cacheable = false) {
 232	global $CONFIG;
 233
 234	if (!isset($CONFIG->allowed_ajax_views)) {
 235		$CONFIG->allowed_ajax_views = array();
 236	}
 237
 238	$CONFIG->allowed_ajax_views[$view] = true;
 239
 240	if ($cacheable) {
 241		_elgg_services()->views->registerCacheableView($view);
 242	}
 243}
 244
 245/**
 246 * Check whether a view is registered as cacheable.
 247 * 
 248 * @param string $view The name of the view.
 249 * @return boolean
 250 * @access private
 251 * @since 1.9.0
 252 */
 253function _elgg_is_view_cacheable($view) {
 254	return _elgg_services()->views->isCacheableView($view);
 255}
 256
 257/**
 258 * Unregister a view for accessibility via URLs.
 259 * 
 260 * @param string $view The view name
 261 * @return void
 262 * @since 1.9.0
 263 */
 264function elgg_unregister_external_view($view) {
 265	global $CONFIG;
 266
 267	if (isset($CONFIG->allowed_ajax_views[$view])) {
 268		unset($CONFIG->allowed_ajax_views[$view]);
 269	}
 270}
 271
 272/**
 273 * Returns the file location for a view.
 274 *
 275 * @warning This doesn't check if the file exists, but only
 276 * constructs (or extracts) the path and returns it.
 277 *
 278 * @param string $view     The view.
 279 * @param string $viewtype The viewtype
 280 *
 281 * @return string
 282 */
 283function elgg_get_view_location($view, $viewtype = '') {
 284	return _elgg_services()->views->getViewLocation($view, $viewtype);
 285}
 286
 287/**
 288 * Set an alternative base location for a view.
 289 *
 290 * Views are expected to be in plugin_name/views/.  This function can
 291 * be used to change that location.
 292 *
 293 * @internal Core view locations are stored in $CONFIG->viewpath.
 294 *
 295 * @tip This is useful to optionally register views in a plugin.
 296 *
 297 * @param string $view     The name of the view
 298 * @param string $location The base location path
 299 * @param string $viewtype The view type
 300 *
 301 * @return void
 302 */
 303function elgg_set_view_location($view, $location, $viewtype = '') {
 304	_elgg_services()->views->setViewLocation($view, $location, $viewtype);
 305}
 306
 307/**
 308 * Returns whether the specified view exists
 309 *
 310 * @note If $recurse is true, also checks if a view exists only as an extension.
 311 *
 312 * @param string $view     The view name
 313 * @param string $viewtype If set, forces the viewtype
 314 * @param bool   $recurse  If false, do not check extensions
 315 *
 316 * @return bool
 317 */
 318function elgg_view_exists($view, $viewtype = '', $recurse = true) {
 319	return _elgg_services()->views->viewExists($view, $viewtype, $recurse);
 320}
 321
 322/**
 323 * Return a parsed view.
 324 *
 325 * Views are rendered by a template handler and returned as strings.
 326 *
 327 * Views are called with a special $vars variable set,
 328 * which includes any variables passed as the second parameter.
 329 * For backward compatbility, the following variables are also set but we
 330 * recommend that you do not use them:
 331 *  - $vars['config'] The $CONFIG global. (Use {@link elgg_get_config()} instead).
 332 *  - $vars['url'] The site URL. (use {@link elgg_get_site_url()} instead).
 333 *  - $vars['user'] The logged in user. (use {@link elgg_get_logged_in_user_entity()} instead).
 334 *
 335 * Custom template handlers can be set with {@link set_template_handler()}.
 336 *
 337 * The output of views can be intercepted by registering for the
 338 * view, $view_name plugin hook.
 339 *
 340 * @warning Any variables in $_SESSION will override passed vars
 341 * upon name collision.  See {@trac #2124}.
 342 *
 343 * @param string  $view     The name and location of the view to use
 344 * @param array   $vars     Variables to pass to the view.
 345 * @param boolean $bypass   If set to true, elgg_view will bypass any specified
 346 *                          alternative template handler; by default, it will
 347 *                          hand off to this if requested (see set_template_handler)
 348 * @param boolean $ignored  This argument is ignored and will be removed eventually
 349 * @param string  $viewtype If set, forces the viewtype for the elgg_view call to be
 350 *                          this value (default: standard detection)
 351 *
 352 * @return string The parsed view
 353 * @see set_template_handler()
 354 * @example views/elgg_view.php
 355 * @link http://docs.elgg.org/View
 356 */
 357function elgg_view($view, $vars = array(), $bypass = false, $ignored = false, $viewtype = '') {
 358	return _elgg_services()->views->renderView($view, $vars, $bypass, $viewtype);
 359}
 360
 361/**
 362 * Extends a view with another view.
 363 *
 364 * The output of any view can be prepended or appended to any other view.
 365 *
 366 * The default action is to append a view.  If the priority is less than 500,
 367 * the output of the extended view will be appended to the original view.
 368 *
 369 * Priority can be specified and affects the order in which extensions
 370 * are appended or prepended.
 371 *
 372 * @internal View extensions are stored in
 373 * $CONFIG->views->extensions[$view][$priority] = $view_extension
 374 *
 375 * @param string $view           The view to extend.
 376 * @param string $view_extension This view is added to $view
 377 * @param int    $priority       The priority, from 0 to 1000,
 378 *                               to add at (lowest numbers displayed first)
 379 *
 380 * @return void
 381 * @since 1.7.0
 382 * @link http://docs.elgg.org/Views/Extend
 383 * @example views/extend.php
 384 */
 385function elgg_extend_view($view, $view_extension, $priority = 501, $viewtype = '') {
 386	_elgg_services()->views->extendView($view, $view_extension, $priority, $viewtype);
 387}
 388
 389/**
 390 * Unextends a view.
 391 *
 392 * @param string $view           The view that was extended.
 393 * @param string $view_extension This view that was added to $view
 394 *
 395 * @return bool
 396 * @since 1.7.2
 397 */
 398function elgg_unextend_view($view, $view_extension) {
 399	return _elgg_services()->views->unextendView($view, $view_extension);
 400}
 401
 402/**
 403 * Assembles and outputs a full page.
 404 *
 405 * A "page" in Elgg is determined by the current view type and
 406 * can be HTML for a browser, RSS for a feed reader, or
 407 * Javascript, PHP and a number of other formats.
 408 *
 409 * @param string $title      Title
 410 * @param string $body       Body
 411 * @param string $page_shell Optional page shell to use. See page/shells view directory
 412 * @param array  $vars       Optional vars array to pass to the page
 413 *                           shell. Automatically adds title, body, and sysmessages
 414 *
 415 * @return string The contents of the page
 416 * @since  1.8
 417 */
 418function elgg_view_page($title, $body, $page_shell = 'default', $vars = array()) {
 419
 420	$messages = null;
 421	if (count_messages()) {
 422		// get messages - try for errors first
 423		$messages = system_messages(NULL, "error");
 424		if (count($messages["error"]) == 0) {
 425			// no errors so grab rest of messages
 426			$messages = system_messages(null, "");
 427		} else {
 428			// we have errors - clear out remaining messages
 429			system_messages(null, "");
 430		}
 431	}
 432
 433	$vars['title'] = $title;
 434	$vars['body'] = $body;
 435	$vars['sysmessages'] = $messages;
 436
 437	$vars = elgg_trigger_plugin_hook('output:before', 'page', null, $vars);
 438	
 439	// check for deprecated view
 440	if ($page_shell == 'default' && elgg_view_exists('pageshells/pageshell')) {
 441		elgg_deprecated_notice("pageshells/pageshell is deprecated by page/$page_shell", 1.8);
 442		$output = elgg_view('pageshells/pageshell', $vars);
 443	} else {
 444		$output = elgg_view("page/$page_shell", $vars);
 445	}
 446
 447	$vars['page_shell'] = $page_shell;
 448
 449	// Allow plugins to mod output
 450	return elgg_trigger_plugin_hook('output', 'page', $vars, $output);
 451}
 452
 453/**
 454 * Displays a layout with optional parameters.
 455 *
 456 * Layouts provide consistent organization of pages and other blocks of content.
 457 * There are a few default layouts in core:
 458 *  - admin                   A special layout for the admin area.
 459 *  - one_column              A single content column.
 460 *  - one_sidebar             A content column with sidebar.
 461 *  - two_sidebar             A content column with two sidebars.
 462 *  - widgets                 A widget canvas.
 463 *
 464 * The layout views take the form page/layouts/$layout_name
 465 * See the individual layouts for what options are supported. The three most
 466 * common layouts have these parameters:
 467 * one_column
 468 *     content => string
 469 * one_sidebar
 470 *     content => string
 471 *     sidebar => string (optional)
 472 * content
 473 *     content => string
 474 *     sidebar => string (optional)
 475 *     buttons => string (override the default add button)
 476 *     title   => string (override the default title)
 477 *     filter_context => string (selected content filter)
 478 *     See the content layout view for more parameters
 479 *
 480 * @param string $layout_name The name of the view in page/layouts/.
 481 * @param array  $vars        Associative array of parameters for the layout view
 482 *
 483 * @return string The layout
 484 */
 485function elgg_view_layout($layout_name, $vars = array()) {
 486
 487	if (is_string($vars) || $vars === null) {
 488		elgg_deprecated_notice("The use of unlimited optional string arguments in elgg_view_layout() was deprecated in favor of an options array", 1.8);
 489		$arg = 1;
 490		$param_array = array();
 491		while ($arg < func_num_args()) {
 492			$param_array['area' . $arg] = func_get_arg($arg);
 493			$arg++;
 494		}
 495	} else {
 496		$param_array = $vars;
 497	}
 498
 499	$params = elgg_trigger_plugin_hook('output:before', 'layout', null, $param_array);
 500
 501	// check deprecated location
 502	if (elgg_view_exists("canvas/layouts/$layout_name")) {
 503		elgg_deprecated_notice("canvas/layouts/$layout_name is deprecated by page/layouts/$layout_name", 1.8);
 504		$output = elgg_view("canvas/layouts/$layout_name", $params);
 505	} elseif (elgg_view_exists("page/layouts/$layout_name")) {
 506		$output = elgg_view("page/layouts/$layout_name", $params);
 507	} else {
 508		$output = elgg_view("page/layouts/default", $params);
 509	}
 510
 511	return elgg_trigger_plugin_hook('output:after', 'layout', $params, $output);
 512}
 513
 514/**
 515 * Render a menu
 516 *
 517 * @see elgg_register_menu_item() for documentation on adding menu items and
 518 * navigation.php for information on the different menus available.
 519 *
 520 * This function triggers a 'register', 'menu:<menu name>' plugin hook that enables
 521 * plugins to add menu items just before a menu is rendered. This is used by
 522 * dynamic menus (menus that change based on some input such as the user hover
 523 * menu). Using elgg_register_menu_item() in response to the hook can cause
 524 * incorrect links to show up. See the blog plugin's blog_owner_block_menu()
 525 * for an example of using this plugin hook.
 526 *
 527 * An additional hook is the 'prepare', 'menu:<menu name>' which enables plugins
 528 * to modify the structure of the menu (sort it, remove items, set variables on
 529 * the menu items).
 530 *
 531 * elgg_view_menu() uses views in navigation/menu
 532 *
 533 * @param string $menu_name The name of the menu
 534 * @param array  $vars      An associative array of display options for the menu.
 535 *                          Options include:
 536 *                              sort_by => string or php callback
 537 *                                  string options: 'name', 'priority', 'title' (default),
 538 *                                  'register' (registration order) or a
 539 *                                  php callback (a compare function for usort)
 540 *                              handler: string the page handler to build action URLs
 541 *                              entity: ElggEntity to use to build action URLs
 542 *                              class: string the class for the entire menu.
 543 *                              show_section_headers: bool show headers before menu sections.
 544 *
 545 * @return string
 546 * @since 1.8.0
 547 */
 548function elgg_view_menu($menu_name, array $vars = array()) {
 549	global $CONFIG;
 550
 551	$vars['name'] = $menu_name;
 552
 553	$sort_by = elgg_extract('sort_by', $vars, 'text');
 554
 555	if (isset($CONFIG->menus[$menu_name])) {
 556		$menu = $CONFIG->menus[$menu_name];
 557	} else {
 558		$menu = array();
 559	}
 560
 561	// Give plugins a chance to add menu items just before creation.
 562	// This supports dynamic menus (example: user_hover).
 563	$menu = elgg_trigger_plugin_hook('register', "menu:$menu_name", $vars, $menu);
 564
 565	$builder = new ElggMenuBuilder($menu);
 566	$vars['menu'] = $builder->getMenu($sort_by);
 567	$vars['selected_item'] = $builder->getSelected();
 568
 569	// Let plugins modify the menu
 570	$vars['menu'] = elgg_trigger_plugin_hook('prepare', "menu:$menu_name", $vars, $vars['menu']);
 571
 572	if (elgg_view_exists("navigation/menu/$menu_name")) {
 573		return elgg_view("navigation/menu/$menu_name", $vars);
 574	} else {
 575		return elgg_view("navigation/menu/default", $vars);
 576	}
 577}
 578
 579/**
 580 * Returns a string of a rendered entity.
 581 *
 582 * Entity views are either determined by setting the view property on the entity
 583 * or by having a view named after the entity $type/$subtype.  Entities that have
 584 * neither a view property nor a defined $type/$subtype view will fall back to
 585 * using the $type/default view.
 586 *
 587 * The entity view is called with the following in $vars:
 588 *  - ElggEntity 'entity' The entity being viewed
 589 *
 590 * Other common view $vars paramters:
 591 *  - bool 'full_view' Whether to show a full or condensed view.
 592 *
 593 * @tip This function can automatically appends annotations to entities if in full
 594 * view and a handler is registered for the entity:annotate.  See {@trac 964} and
 595 * {@link elgg_view_entity_annotations()}.
 596 *
 597 * @param ElggEntity $entity The entity to display
 598 * @param array      $vars   Array of variables to pass to the entity view.
 599 *                           In Elgg 1.7 and earlier it was the boolean $full_view
 600 * @param boolean    $bypass If true, will not pass to a custom template handler.
 601 *                           {@see set_template_handler()}
 602 * @param boolean    $debug  Complain if views are missing
 603 *
 604 * @return string HTML to display or false
 605 * @link http://docs.elgg.org/Views/Entity
 606 * @link http://docs.elgg.org/Entities
 607 * @todo The annotation hook might be better as a generic plugin hook to append content.
 608 */
 609function elgg_view_entity(ElggEntity $entity, $vars = array(), $bypass = false, $debug = false) {
 610
 611	// No point continuing if entity is null
 612	if (!$entity || !($entity instanceof ElggEntity)) {
 613		return false;
 614	}
 615
 616	global $autofeed;
 617	$autofeed = true;
 618
 619	$defaults = array(
 620		'full_view' => false,
 621	);
 622
 623	if (is_array($vars)) {
 624		$vars = array_merge($defaults, $vars);
 625	} else {
 626		elgg_deprecated_notice("Update your use of elgg_view_entity()", 1.8);
 627		$vars = array(
 628			'full_view' => $vars,
 629		);
 630	}
 631
 632	$vars['entity'] = $entity;
 633
 634
 635	// if this entity has a view defined, use it
 636	$view = $entity->view;
 637	if (is_string($view)) {
 638		return elgg_view($view, $vars, $bypass, $debug);
 639	}
 640
 641	$entity_type = $entity->getType();
 642
 643	$subtype = $entity->getSubtype();
 644	if (empty($subtype)) {
 645		$subtype = 'default';
 646	}
 647
 648	$contents = '';
 649	if (elgg_view_exists("$entity_type/$subtype")) {
 650		$contents = elgg_view("$entity_type/$subtype", $vars, $bypass, $debug);
 651	} else {
 652		$contents = elgg_view("$entity_type/default", $vars, $bypass, $debug);
 653	}
 654
 655	// Marcus Povey 20090616 : Speculative and low impact approach for fixing #964
 656	if ($vars['full_view']) {
 657		$annotations = elgg_view_entity_annotations($entity, $vars['full_view']);
 658
 659		if ($annotations) {
 660			$contents .= $annotations;
 661		}
 662	}
 663	return $contents;
 664}
 665
 666/**
 667 * View the icon of an entity
 668 *
 669 * Entity views are determined by having a view named after the entity $type/$subtype.
 670 * Entities that do not have a defined icon/$type/$subtype view will fall back to using
 671 * the icon/$type/default view.
 672 *
 673 * @param ElggEntity $entity The entity to display
 674 * @param string     $size   The size: tiny, small, medium, large
 675 * @param array      $vars   An array of variables to pass to the view. Some possible
 676 *                           variables are img_class and link_class. See the
 677 *                           specific icon view for more parameters.
 678 *
 679 * @return string HTML to display or false
 680 */
 681function elgg_view_entity_icon(ElggEntity $entity, $size = 'medium', $vars = array()) {
 682
 683	// No point continuing if entity is null
 684	if (!$entity || !($entity instanceof ElggEntity)) {
 685		return false;
 686	}
 687
 688	$vars['entity'] = $entity;
 689	$vars['size'] = $size;
 690
 691	$entity_type = $entity->getType();
 692
 693	$subtype = $entity->getSubtype();
 694	if (empty($subtype)) {
 695		$subtype = 'default';
 696	}
 697
 698	$contents = '';
 699	if (elgg_view_exists("icon/$entity_type/$subtype")) {
 700		$contents = elgg_view("icon/$entity_type/$subtype", $vars);
 701	}
 702	if (empty($contents)) {
 703		$contents = elgg_view("icon/$entity_type/default", $vars);
 704	}
 705	if (empty($contents)) {
 706		$contents = elgg_view("icon/default", $vars);
 707	}
 708
 709	return $contents;
 710}
 711
 712/**
 713 * Returns a string of a rendered annotation.
 714 *
 715 * Annotation views are expected to be in annotation/$annotation_name.
 716 * If a view is not found for $annotation_name, the default annotation/default
 717 * will be used.
 718 *
 719 * @warning annotation/default is not currently defined in core.
 720 *
 721 * The annotation view is called with the following in $vars:
 722 *  - ElggEntity 'annotation' The annotation being viewed.
 723 *
 724 * @param ElggAnnotation $annotation The annotation to display
 725 * @param array          $vars       Variable array for view.
 726 * @param bool           $bypass     If true, will not pass to a custom
 727 *                                   template handler. {@see set_template_handler()}
 728 * @param bool           $debug      Complain if views are missing
 729 *
 730 * @return string/false Rendered annotation
 731 */
 732function elgg_view_annotation(ElggAnnotation $annotation, array $vars = array(), $bypass = false, $debug = false) {
 733	global $autofeed;
 734	$autofeed = true;
 735
 736	$defaults = array(
 737		'full_view' => true,
 738	);
 739
 740	$vars = array_merge($defaults, $vars);
 741	$vars['annotation'] = $annotation;
 742
 743	// @todo setting the view on an annotation is not advertised anywhere
 744	// do we want to keep this?
 745	$view = $annotation->view;
 746	if (is_string($view)) {
 747		return elgg_view($view, $vars, $bypass, $debug);
 748	}
 749
 750	$name = $annotation->name;
 751	if (empty($name)) {
 752		return false;
 753	}
 754
 755	if (elgg_view_exists("annotation/$name")) {
 756		return elgg_view("annotation/$name", $vars, $bypass, $debug);
 757	} else {
 758		return elgg_view("annotation/default", $vars, $bypass, $debug);
 759	}
 760}
 761
 762/**
 763 * Returns a rendered list of entities with pagination. This function should be
 764 * called by wrapper functions.
 765 *
 766 * @see elgg_list_entities()
 767 * @see list_user_friends_objects()
 768 * @see elgg_list_entities_from_metadata()
 769 * @see elgg_list_entities_from_relationships()
 770 * @see elgg_list_entities_from_annotations()
 771 *
 772 * @param array $entities Array of entities
 773 * @param array $vars     Display variables
 774 *		'count'            The total number of entities across all pages
 775 *		'offset'           The current indexing offset
 776 *		'limit'            The number of entities to display per page
 777 *		'full_view'        Display the full view of the entities?
 778 *		'list_class'       CSS class applied to the list
 779 *		'item_class'       CSS class applied to the list items
 780 *		'pagination'       Display pagination?
 781 *		'list_type'        List type: 'list' (default), 'gallery'
 782 *		'list_type_toggle' Display the list type toggle?
 783 *
 784 * @return string The rendered list of entities
 785 * @access private
 786 */
 787function elgg_view_entity_list($entities, $vars = array(), $offset = 0, $limit = 10, $full_view = true,
 788$list_type_toggle = true, $pagination = true) {
 789
 790	if (!is_int($offset)) {
 791		$offset = (int)get_input('offset', 0);
 792	}
 793
 794	// list type can be passed as request parameter
 795	$list_type = get_input('list_type', 'list');
 796	if (get_input('listtype')) {
 797		elgg_deprecated_notice("'listtype' has been deprecated by 'list_type' for lists", 1.8);
 798		$list_type = get_input('listtype');
 799	}
 800
 801	if (is_array($vars)) {
 802		// new function
 803		$defaults = array(
 804			'items' => $entities,
 805			'list_class' => 'elgg-list-entity',
 806			'full_view' => true,
 807			'pagination' => true,
 808			'list_type' => $list_type,
 809			'list_type_toggle' => false,
 810			'offset' => $offset,
 811		);
 812
 813		$vars = array_merge($defaults, $vars);
 814
 815	} else {
 816		// old function parameters
 817		elgg_deprecated_notice("Please update your use of elgg_view_entity_list()", 1.8);
 818
 819		$vars = array(
 820			'items' => $entities,
 821			'count' => (int) $vars, // the old count parameter
 822			'offset' => $offset,
 823			'limit' => (int) $limit,
 824			'full_view' => $full_view,
 825			'pagination' => $pagination,
 826			'list_type' => $list_type,
 827			'list_type_toggle' => $list_type_toggle,
 828			'list_class' => 'elgg-list-entity',
 829		);
 830	}
 831
 832	if ($vars['list_type'] != 'list') {
 833		return elgg_view('page/components/gallery', $vars);
 834	} else {
 835		return elgg_view('page/components/list', $vars);
 836	}
 837}
 838
 839/**
 840 * Returns a rendered list of annotations, plus pagination. This function
 841 * should be called by wrapper functions.
 842 *
 843 * @param array $annotations Array of annotations
 844 * @param array $vars        Display variables
 845 *		'count'      The total number of annotations across all pages
 846 *		'offset'     The current indexing offset
 847 *		'limit'      The number of annotations to display per page
 848 *		'full_view'  Display the full view of the annotation?
 849 *		'list_class' CSS Class applied to the list
 850 *		'offset_key' The url parameter key used for offset
 851 *
 852 * @return string The list of annotations
 853 * @access private
 854 */
 855function elgg_view_annotation_list($annotations, array $vars = array()) {
 856	$defaults = array(
 857		'items' => $annotations,
 858		'list_class' => 'elgg-list-annotation elgg-annotation-list', // @todo remove elgg-annotation-list in Elgg 1.9
 859		'full_view' => true,
 860		'offset_key' => 'annoff',
 861	);
 862
 863	$vars = array_merge($defaults, $vars);
 864
 865	return elgg_view('page/components/list', $vars);
 866}
 867
 868/**
 869 * Display a plugin-specified rendered list of annotations for an entity.
 870 *
 871 * This displays the output of functions registered to the entity:annotation,
 872 * $entity_type plugin hook.
 873 *
 874 * This is called automatically by the framework from {@link elgg_view_entity()}
 875 *
 876 * @param ElggEntity $entity    Entity
 877 * @param bool       $full_view Display full view?
 878 *
 879 * @return mixed string or false on failure
 880 * @todo Change the hook name.
 881 */
 882function elgg_view_entity_annotations(ElggEntity $entity, $full_view = true) {
 883	if (!($entity instanceof ElggEntity)) {
 884		return false;
 885	}
 886
 887	$entity_type = $entity->getType();
 888
 889	$annotations = elgg_trigger_plugin_hook('entity:annotate', $entity_type,
 890		array(
 891			'entity' => $entity,
 892			'full_view' => $full_view,
 893		)
 894	);
 895
 896	return $annotations;
 897}
 898
 899/**
 900 * Renders a title.
 901 *
 902 * This is a shortcut for {@elgg_view page/elements/title}.
 903 *
 904 * @param string $title The page title
 905 * @param array $vars   View variables (was submenu be displayed? (deprecated))
 906 *
 907 * @return string The HTML (etc)
 908 */
 909function elgg_view_title($title, $vars = array()) {
 910	if (!is_array($vars)) {
 911		elgg_deprecated_notice('setting $submenu in elgg_view_title() is deprecated', 1.8);
 912		$vars = array('submenu' => $vars);
 913	}
 914
 915	$vars['title'] = $title;
 916
 917	return elgg_view('page/elements/title', $vars);
 918}
 919
 920/**
 921 * Displays a UNIX timestamp in a friendly way
 922 *
 923 * @see elgg_get_friendly_time()
 924 *
 925 * @param int $time A UNIX epoch timestamp
 926 *
 927 * @return string The friendly time HTML
 928 * @since 1.7.2
 929 */
 930function elgg_view_friendly_time($time) {
 931	return elgg_view('output/friendlytime', array('time' => $time));
 932}
 933
 934
 935/**
 936 * Returns rendered comments and a comment form for an entity.
 937 *
 938 * @tip Plugins can override the output by registering a handler
 939 * for the comments, $entity_type hook.  The handler is responsible
 940 * for formatting the comments and the add comment form.
 941 *
 942 * @param ElggEntity $entity      The entity to view comments of
 943 * @param bool       $add_comment Include a form to add comments?
 944 * @param array      $vars        Variables to pass to comment view
 945 *
 946 * @return string|false Rendered comments or false on failure
 947 * @link http://docs.elgg.org/Entities/Comments
 948 * @link http://docs.elgg.org/Annotations/Comments
 949 */
 950function elgg_view_comments($entity, $add_comment = true, array $vars = array()) {
 951	if (!($entity instanceof ElggEntity)) {
 952		return false;
 953	}
 954
 955	$vars['entity'] = $entity;
 956	$vars['show_add_form'] = $add_comment;
 957	$vars['class'] = elgg_extract('class', $vars, "{$entity->getSubtype()}-comments");
 958
 959	$output = elgg_trigger_plugin_hook('comments', $entity->getType(), $vars, false);
 960	if ($output) {
 961		return $output;
 962	} else {
 963		return elgg_view('page/elements/comments', $vars);
 964	}
 965}
 966
 967/**
 968 * Wrapper function for the image block display pattern.
 969 *
 970 * Fixed width media on the side (image, icon, flash, etc.).
 971 * Descriptive content filling the rest of the column.
 972 *
 973 * This is a shortcut for {@elgg_view page/components/image_block}.
 974 *
 975 * @param string $image The icon and other information
 976 * @param string $body  Description content
 977 * @param array $vars   Additional parameters for the view
 978 *
 979 * @return string
 980 * @since 1.8.0
 981 */
 982function elgg_view_image_block($image, $body, $vars = array()) {
 983	$vars['image'] = $image;
 984	$vars['body'] = $body;
 985	return elgg_view('page/components/image_block', $vars);
 986}
 987
 988/**
 989 * Wrapper function for the module display pattern.
 990 *
 991 * Box with header, body, footer
 992 *
 993 * This is a shortcut for {@elgg_view page/components/module}.
 994 *
 995 * @param string $type  The type of module (main, info, popup, aside, etc.)
 996 * @param string $title A title to put in the header
 997 * @param string $body  Content of the module
 998 * @param array  $vars  Additional parameters for the module
 999 *
1000 * @return string
1001 * @since 1.8.0
1002 */
1003function elgg_view_module($type, $title, $body, array $vars = array()) {
1004	$vars['type'] = $type;
1005	$vars['class'] = elgg_extract('class', $vars, '') . " elgg-module-$type";
1006	$vars['title'] = $title;
1007	$vars['body'] = $body;
1008	return elgg_view('page/components/module', $vars);
1009}
1010
1011/**
1012 * Renders a human-readable representation of a river item
1013 *
1014 * @param ElggRiverItem $item A river item object
1015 * @param array         $vars An array of variables for the view
1016 *
1017 * @return string returns empty string if could not be rendered
1018 */
1019function elgg_view_river_item($item, array $vars = array()) {
1020	if (!($item instanceof ElggRiverItem)) {
1021		return '';
1022	}
1023	// checking default viewtype since some viewtypes do not have unique views per item (rss)
1024	$view = $item->getView();
1025	if (!$view || !elgg_view_exists($view, 'default')) {
1026		return '';
1027	}
1028
1029	$subject = $item->getSubjectEntity();
1030	$object = $item->getObjectEntity();
1031	if (!$subject || !$object) {
1032		// subject is disabled or subject/object deleted
1033		return '';
1034	}
1035	// Don't hide objects in closed groups that a user can see.
1036	// see http://trac.elgg.org/ticket/4789
1037//	else {
1038//		// hide based on object's container
1039//		$visibility = ElggGroupItemVisibility::factory($object->container_guid);
1040//		if ($visibility->shouldHideItems) {
1041//			return '';
1042//		}
1043//	}
1044
1045	$vars['item'] = $item;
1046
1047	return elgg_view('river/item', $vars);
1048}
1049
1050/**
1051 * Convenience function for generating a form from a view in a standard location.
1052 *
1053 * This function assumes that the body of the form is located at "forms/$action" and
1054 * sets the action by default to "action/$action".  Automatically wraps the forms/$action
1055 * view with a <form> tag and inserts the anti-csrf security tokens.
1056 *
1057 * @tip This automatically appends elgg-form-action-name to the form's class. It replaces any
1058 * slashes with dashes (blog/save becomes elgg-form-blog-save)
1059 *
1060 * @example
1061 * <code>echo elgg_view_form('login');</code>
1062 *
1063 * This would assume a "login" form body to be at "forms/login" and would set the action
1064 * of the form to "http://yoursite.com/action/login".
1065 *
1066 * If elgg_view('forms/login') is:
1067 * <input type="text" name="username" />
1068 * <input type="password" name="password" />
1069 *
1070 * Then elgg_view_form('login') generates:
1071 * <form action="http://yoursite.com/action/login" method="post">
1072 *     ...security tokens...
1073 *     <input type="text" name="username" />
1074 *     <input type="password" name="password" />
1075 * </form>
1076 *
1077 * @param string $action    The name of the action. An action name does not include
1078 *                          the leading "action/". For example, "login" is an action name.
1079 * @param array  $form_vars $vars environment passed to the "input/form" view
1080 * @param array  $body_vars $vars environment passed to the "forms/$action" view
1081 *
1082 * @return string The complete form
1083 */
1084function elgg_view_form($action, $form_vars = array(), $body_vars = array()) {
1085	global $CONFIG;
1086
1087	$defaults = array(
1088		'action' => $CONFIG->wwwroot . "action/$action",
1089		'body' => elgg_view("forms/$action", $body_vars)
1090	);
1091
1092	$form_class = 'elgg-form-' . preg_replace('/[^a-z0-9]/i', '-', $action);
1093
1094	// append elgg-form class to any class options set
1095	if (isset($form_vars['class'])) {
1096		$form_vars['class'] = $form_vars['class'] . " $form_class";
1097	} else {
1098		$form_vars['class'] = $form_class;
1099	}
1100
1101	return elgg_view('input/form', array_merge($defaults, $form_vars));
1102}
1103
1104/**
1105 * View an item in a list
1106 *
1107 * @param ElggEntity|ElggAnnotation $item
1108 * @param array  $vars Additional parameters for the rendering
1109 *
1110 * @return string
1111 * @since 1.8.0
1112 * @access private
1113 */
1114function elgg_view_list_item($item, array $vars = array()) {
1115	global $CONFIG;
1116
1117	$type = $item->getType();
1118	if (in_array($type, $CONFIG->entity_types)) {
1119		return elgg_view_entity($item, $vars);
1120	} else if ($type == 'annotation') {
1121		return elgg_view_annotation($item, $vars);
1122	} else if ($type == 'river') {
1123		return elgg_view_river_item($item, $vars);
1124	}
1125
1126	return '';
1127}
1128
1129/**
1130 * View one of the elgg sprite icons
1131 * 
1132 * Shorthand for <span class="elgg-icon elgg-icon-$name"></span>
1133 * 
1134 * @param string $name  The specific icon to display
1135 * @param string $class Additional class: float, float-alt, or custom class
1136 * 
1137 * @return string The html for displaying an icon
1138 */
1139function elgg_view_icon($name, $class = '') {
1140	// @todo deprecate boolean in Elgg 1.9
1141	if ($class === true) {
1142		$class = 'float';
1143	}
1144	return "<span class=\"elgg-icon elgg-icon-$name $class\"></span>";
1145}
1146
1147/**
1148 * Displays a user's access collections, using the core/friends/collections view
1149 *
1150 * @param int $owner_guid The GUID of the owning user
1151 *
1152 * @return string A formatted rendition of the collections
1153 * @todo Move to the friends/collection.php page.
1154 * @access private
1155 */
1156function elgg_view_access_collections($owner_guid) {
1157	if ($collections = get_user_access_collections($owner_guid)) {
1158		foreach ($collections as $key => $collection) {
1159			$collections[$key]->members = get_members_of_access_collection($collection->id, true);
1160			$collections[$key]->entities = get_user_friends($owner_guid, "", 9999);
1161		}
1162	}
1163
1164	return elgg_view('core/friends/collections', array('collections' => $collections));
1165}
1166
1167/**
1168 * Registers a function to handle templates.
1169 *
1170 * Alternative template handlers can be registered to handle
1171 * all output functions.  By default, {@link elgg_view()} will
1172 * simply include the view file.  If an alternate template handler
1173 * is registered, the view name and passed $vars will be passed to the
1174 * registered function, which is then responsible for generating and returning
1175 * output.
1176 *
1177 * Template handlers need to accept two arguments: string $view_name and array
1178 * $vars.
1179 *
1180 * @warning This is experimental.
1181 *
1182 * @param string $function_name The name of the function to pass to.
1183 *
1184 * @return bool
1185 * @see elgg_view()
1186 * @link http://docs.elgg.org/Views/TemplateHandlers
1187 */
1188function set_template_handler($function_name) {
1189	global $CONFIG;
1190
1191	if (is_callable($function_name)) {
1192		$CONFIG->template_handler = $function_name;
1193		return true;
1194	}
1195	return false;
1196}
1197
1198/**
1199 * Returns the name of views for in a directory.
1200 *
1201 * Use this to get all namespaced views under the first element.
1202 *
1203 * @param string $dir  The main directory that holds the views. (mod/profile/views/)
1204 * @param string $base The root name of the view to use, without the viewtype. (profile)
1205 *
1206 * @return array
1207 * @since 1.7.0
1208 * @todo Why isn't this used anywhere else but in elgg_view_tree()?
1209 * Seems like a useful function for autodiscovery.
1210 * @access private
1211 */
1212function elgg_get_views($dir, $base) {
1213	$return = array();
1214	if (file_exists($dir) && is_dir($dir)) {
1215		if ($handle = opendir($dir)) {
1216			while ($view = readdir($handle)) {
1217				if (!in_array($view, array('.', '..', '.svn', 'CVS'))) {
1218					if (is_dir($dir . '/' . $view)) {
1219						if ($val = elgg_get_views($dir . '/' . $view, $base . '/' . $view)) {
1220							$return = array_merge($return, $val);
1221						}
1222					} else {
1223						$view = str_replace('.php', '', $view);
1224						$return[] = $base . '/' . $view;
1225					}
1226				}
1227			}
1228		}
1229	}
1230
1231	return $return;
1232}
1233
1234/**
1235 * Returns all views below a partial view.
1236 *
1237 * Settings $view_root = 'profile' will show all available views under
1238 * the "profile" namespace.
1239 *
1240 * @param string $view_root The root view
1241 * @param string $viewtype  Optionally specify a view type
1242 *                          other than the current one.
1243 *
1244 * @return array A list of view names underneath that root view
1245 * @todo This is used once in the deprecated get_activity_stream_data() function.
1246 * @access private
1247 */
1248function elgg_view_tree($view_root, $viewtype = "") {
1249	global $CONFIG;
1250	static $treecache = array();
1251
1252	// Get viewtype
1253	if (!$viewtype) {
1254		$viewtype = elgg_get_viewtype();
1255	}
1256
1257	// A little light internal caching
1258	if (!empty($treecache[$view_root])) {
1259		return $treecache[$view_root];
1260	}
1261
1262	// Examine $CONFIG->views->locations
1263	if (isset($CONFIG->views->locations[$viewtype])) {
1264		foreach ($CONFIG->views->locations[$viewtype] as $view => $path) {
1265			$pos = strpos($view, $view_root);
1266			if ($pos === 0) {
1267				$treecache[$view_root][] = $view;
1268			}
1269		}
1270	}
1271
1272	// Now examine core
1273	$location = $CONFIG->viewpath;
1274	$viewtype = elgg_get_viewtype();
1275	$root = $location . $viewtype . '/' . $view_root;
1276
1277	if (file_exists($root) && is_dir($root)) {
1278		$val = elgg_get_views($root, $view_root);
1279		if (!is_array($treecache[$view_root])) {
1280			$treecache[$view_root] = array();
1281		}
1282		$treecache[$view_root] = array_merge($treecache[$view_root], $val);
1283	}
1284
1285	return $treecache[$view_root];
1286}
1287
1288/**
1289 * Auto-registers views from a location.
1290 *
1291 * @note Views in plugin/views/ are automatically registered for active plugins.
1292 * Plugin authors would only need to call this if optionally including
1293 * an entire views structure.
1294 *
1295 * @param string $view_base          Optional The base of the view name without the view type.
1296 * @param string $folder             Required The folder to begin looking in
1297 * @param string $base_location_path The base views directory to use with elgg_set_view_location()
1298 * @param string $viewtype           The type of view we're looking at (default, rss, etc)
1299 *
1300 * @return bool returns false if folder can't be read
1301 * @since 1.7.0
1302 * @see elgg_set_view_location()
1303 * @access private
1304 */
1305function autoregister_views($view_base, $folder, $base_location_path, $viewtype) {
1306	return _elgg_services()->views->autoregisterViews($view_base, $folder, $base_location_path, $viewtype);
1307}
1308
1309/**
1310 * Minifies simplecache CSS and JS views by handling the "simplecache:generate" hook
1311 *
1312 * @param string $hook    The name of the hook
1313 * @param string $type    View type (css, js, or unknown)
1314 * @param string $content Content of the view
1315 * @param array  $params  Array of parameters
1316 *
1317 * @return string|null View content minified (if css/js type)
1318 * @access private
1319 */
1320function _elgg_views_minify($hook, $type, $content, $params) {
1321	static $autoload_registered;
1322	if (!$autoload_registered) {
1323		$path = elgg_get_root_path() . 'vendors/minify/lib';
1324		elgg_get_class_loader()->addFallback($path);
1325		$autoload_registered = true;
1326	}
1327
1328	if ($type == 'js') {
1329		if (elgg_get_config('simplecache_minify_js')) {
1330			return JSMin::minify($content);
1331		}
1332	} elseif ($type == 'css') {
1333		if (elgg_get_config('simplecache_minify_css')) {
1334			$cssmin = new CSSMin();
1335			return $cssmin->run($content);
1336		}
1337	}
1338}
1339
1340/**
1341 * Add the rss link to the extras when if needed
1342 *
1343 * @return void
1344 * @access private
1345 */
1346function elgg_views_add_rss_link() {
1347	global $autofeed;
1348	if (isset($autofeed) && $autofeed == true) {
1349		$url = full_url();
1350		if (substr_count($url, '?')) {
1351			$url .= "&view=rss";
1352		} else {
1353			$url .= "?view=rss";
1354		}
1355
1356		$url = elgg_format_url($url);
1357		elgg_register_menu_item('extras', array(
1358			'name' => 'rss',
1359			'text' => elgg_view_icon('rss'),
1360			'href' => $url,
1361			'title' => elgg_echo('feed:rss'),
1362		));
1363	}
1364}
1365
1366/**
1367 * Registers deprecated views to avoid making some pages from older plugins
1368 * completely empty.
1369 *
1370 * @access private
1371 */
1372function elgg_views_handle_deprecated_views() {
1373	$location = elgg_get_view_location('page_elements/contentwrapper');
1374	if ($location === "/var/www/views/") {
1375		elgg_extend_view('page_elements/contentwrapper', 'page/elements/wrapper');
1376	}
1377}
1378
1379/**
1380 * Initialize viewtypes on system boot event
1381 * This ensures simplecache is cleared during upgrades. See #2252
1382 *
1383 * @return void
1384 * @access private
1385 * @elgg_event_handler boot system
1386 */
1387function elgg_views_boot() {
1388	global $CONFIG;
1389
1390	elgg_register_simplecache_view('css/ie');
1391	elgg_register_simplecache_view('css/ie7');
1392	elgg_register_simplecache_view('css/ie8');
1393
1394	elgg_register_simplecache_view('js/text.js');
1395
1396	elgg_register_js('require', '/vendors/requirejs/require-2.1.4.min.js', 'head'); 
1397	elgg_register_js('jquery', '/vendors/jquery/jquery-1.7.2.min.js', 'head');
1398	elgg_register_js('jquery-ui', '/vendors/jquery/jquery-ui-1.8.21.min.js', 'head');
1399	elgg_register_js('jquery.form', array(
1400		'src' => '/vendors/jquery/jquery.form.js',
1401		'location' => 'head',
1402		'deps' => array('jquery'),
1403		'exports' => 'jQuery.fn.ajaxForm',
1404	));
1405
1406	elgg_register_simplecache_view('js/elgg');
1407	$elgg_js_url = elgg_get_simplecache_url('js', 'elgg');
1408	elgg_register_js('elgg', $elgg_js_url, 'head');
1409
1410	elgg_load_js('require');
1411	elgg_load_js('jquery');
1412	elgg_load_js('jquery-ui');
1413	elgg_load_js('elgg');
1414
1415	elgg_register_simplecache_view('js/lightbox');
1416	$lightbox_js_url = elgg_get_simplecache_url('js', 'lightbox');
1417	elgg_register_js('lightbox', $lightbox_js_url);
1418
1419	elgg_register_simplecache_view('css/lightbox');
1420	$lightbox_css_url = elgg_get_simplecache_url('css', 'lightbox');
1421	elgg_register_css('lightbox', $lightbox_css_url);
1422
1423	elgg_register_simplecache_view('css/elgg');
1424	$elgg_css_url = elgg_get_simplecache_url('css', 'elgg');
1425	elgg_register_css('elgg', $elgg_css_url);
1426
1427	elgg_load_css('elgg');
1428
1429	elgg_register_ajax_view('js/languages');
1430
1431	elgg_register_plugin_hook_handler('simplecache:generate', 'css', '_elgg_views_minify');
1432	elgg_register_plugin_hook_handler('simplecache:generate', 'js', '_elgg_views_minify');
1433
1434	elgg_register_plugin_hook_handler('output:before', 'layout', 'elgg_views_add_rss_link');
1435
1436	// discover the core viewtypes
1437	// @todo the cache is loaded in load_plugins() but we need to know viewtypes earlier
1438	$view_path = $CONFIG->viewpath;
1439	$viewtype_dirs = scandir($view_path);
1440	foreach ($viewtype_dirs as $viewtype) {
1441		if (_elgg_is_valid_viewtype($viewtype) && is_dir($view_path . $viewtype)) {
1442			elgg_register_viewtype($viewtype);
1443		}
1444	}
1445
1446	// set default icon sizes - can be overridden in settings.php or with plugin
1447	if (!$CONFIG->icon_sizes) {
1448		$icon_sizes = array(
1449			'topbar' => array('w' => 16, 'h' => 16, 'square' => TRUE, 'upscale' => TRUE),
1450			'tiny' => array('w' => 25, 'h' => 25, 'square' => TRUE, 'upscale' => TRUE),
1451			'small' => array('w' => 40, 'h' => 40, 'square' => TRUE, 'upscale' => TRUE),
1452			'medium' => array('w' => 100, 'h' => 100, 'square' => TRUE, 'upscale' => TRUE),
1453			'large' => array('w' => 200, 'h' => 200, 'square' => FALSE, 'upscale' => FALSE),
1454			'master' => array('w' => 550, 'h' => 550, 'square' => FALSE, 'upscale' => FALSE),
1455		);
1456		elgg_set_config('icon_sizes', $icon_sizes);
1457	}
1458}
1459
1460elgg_register_event_handler('boot', 'system', 'elgg_views_boot');
1461elgg_register_event_handler('init', 'system', 'elgg_views_handle_deprecated_views');