code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminHandler Class
 * Backbone of the admin area, handles requests and functionality.
 */
class AdminHandler extends ActionHandler
{
	/** An instance of the active public theme, which allows plugin hooks to execute */
	protected $active_theme = null;

	/**
	 * Verifies user credentials before creating the theme and displaying the request.
	 */
	public function __construct()
	{
		$user = User::identify();
		if ( !$user->loggedin ) {
			Session::add_to_set( 'login', $_SERVER['REQUEST_URI'], 'original' );
			if ( URL::get_matched_rule()->action == 'admin_ajax' && isset( $_SERVER['HTTP_REFERER'] ) ) {
				 $ar = new AjaxResponse(408, _t('Your session has ended, please log in and try again.') );
				 $ar->out();
			}
			else {
				$post_raw = $_POST->get_array_copy_raw();
				if ( !empty( $post_raw ) ) {
					Session::add_to_set( 'last_form_data', $post_raw, 'post' );
					Session::error( _t( 'We saved the last form you posted. Log back in to continue its submission.' ), 'expired_form_submission' );
				}
				$get_raw = $_GET->get_array_copy_raw();
				if ( !empty( $get_raw ) ) {
					Session::add_to_set( 'last_form_data', $get_raw, 'get' );
					Session::error( _t( 'We saved the last form you posted. Log back in to continue its submission.' ), 'expired_form_submission' );
				}
				Utils::redirect( URL::get( 'auth', array( 'page' => 'login' ) ) );
			}
			exit;
		}

		$last_form_data = Session::get_set( 'last_form_data' ); // This was saved in the "if ( !$user )" above, UserHandler transferred it properly.
		/* At this point, Controller has not created handler_vars, so we have to modify $_POST/$_GET. */
		if ( isset( $last_form_data['post'] ) ) {
			$_POST = $_POST->merge( $last_form_data['post'] );
			$_SERVER['REQUEST_METHOD'] = 'POST'; // This will trigger the proper act_admin switches.
			Session::remove_error( 'expired_form_submission' );
		}
		if ( isset( $last_form_data['get'] ) ) {
			$_GET = $_GET->merge( $last_form_data['get'] );
			Session::remove_error( 'expired_form_submission' );
			// No need to change REQUEST_METHOD since GET is the default.
		}
		$user->remember();

		// Create an instance of the active public theme so that its plugin functions are implemented
		$this->active_theme = Themes::create();

		// setup the stacks for javascript in the admin - it's a method so a plugin can call it externally
		self::setup_stacks();

		// on every page load check the plugins currently loaded against the list we last checked for updates and trigger a cron if we need to
		Update::check_plugins();
	}

	/**
	 * Create the admin theme instance
	 *
	 * @param string $page The admin page requested
	 * @param string $type The content type included in the request
	 */
	public function setup_admin_theme( $page, $type = '' )
	{
		if ( !isset( $this->theme ) ) {
			$theme_dir = Plugins::filter( 'admin_theme_dir', Site::get_dir( 'admin_theme', true ) );
			$this->theme = Themes::create( '_admin', 'RawPHPEngine', $theme_dir );

			// Add some default stylesheets
			Stack::add( 'admin_stylesheet', array( Site::get_url( 'admin_theme' ) . '/css/admin.css', 'screen' ), 'admin' );
			Stack::add( 'admin_stylesheet', array( Site::get_url( 'admin_theme' ) . '/css/jqueryui.css', 'screen' ), 'jqueryui' );

			// Add some default template variables
			$this->set_admin_template_vars( $this->theme );
			$this->theme->admin_type = $type;
			$this->theme->admin_page = $page;
			$this->theme->admin_page_url = ( $page == 'dashboard' ) ? URL::get( 'admin', 'page=' ) : URL::get( 'admin', 'page=' . $page );
			$this->theme->page = $page;
			$this->theme->admin_title = MultiByte::ucwords( $page ) . ( $type != '' ? ' ' . MultiByte::ucwords( $type ) : '' );
			$this->theme->admin_title =
				isset( $this->theme->mainmenu[$this->theme->admin_page]['text'] )
					? $this->theme->mainmenu[$this->theme->admin_page]['text']
					: MultiByte::ucwords( $page ) . ( $type != '' ? ' ' . MultiByte::ucwords( $type ) : '' );
		}
	}

	/**
	 * Dispatches the request to the defined method. (ie: post_{page})
	 */
	public function act_admin()
	{
		$page = ( isset( $this->handler_vars['page'] ) && !empty( $this->handler_vars['page'] ) ) ? $this->handler_vars['page'] : 'dashboard';
		$page = filter_var( $page, FILTER_SANITIZE_STRING );
		if ( isset( $this->handler_vars['content_type'] ) ) {
			$type = Plugins::filter( 'post_type_display', Post::type_name( $this->handler_vars['content_type'] ), 'singular' );
		}
		elseif ( $page == 'publish' && isset( $this->handler_vars['id'] ) ) {
			$type = Post::type_name( Post::get( array( 'status' => Post::status( 'any' ), 'id' => intval( $this->handler_vars['id'] ) ) )->content_type );
			$type = Plugins::filter( 'post_type_display', $type, 'singular' );
		}
		else {
			$type = '';
		}

		$this->setup_admin_theme( $page, $type );

		// Access check to see if the user is allowed the requested page
		Utils::check_request_method( array( 'GET', 'HEAD', 'POST' ) );
		if ( !$this->access_allowed( $page, $type ) ) {
			Session::error( _t( 'Access to that page has been denied by the administrator.' ) );
			$this->get_blank();
		}

		switch ( $_SERVER['REQUEST_METHOD'] ) {
			case 'POST':
				// Let plugins try to handle the page
				Plugins::act( 'admin_theme_post_' . $page, $this, $this->theme );
				// Handle POSTs to the admin pages
				$fn = 'post_' . $page;
				if ( method_exists( $this, $fn ) ) {
					$this->$fn();
				}
				else {
					$classname = get_class( $this );
					_e( '%1$s->%2$s() does not exist.', array( $classname, $fn ) );
					exit;
				}
				break;
			case 'GET':
			case 'HEAD':
				// Let plugins try to handle the page
				Plugins::act( 'admin_theme_get_' . $page, $this, $this->theme );
				// Handle GETs of the admin pages
				$fn = 'get_' . $page;
				if ( method_exists( $this, $fn ) ) {
					$this->$fn();
					exit;
				}
				// If a get_ function doesn't exist, just load the template and display it
				if ( $this->theme->template_exists( $page ) ) {
					$this->display( $page );
				}
				else {
					// The requested console page doesn't exist
					header( 'HTTP/1.1 404 Not Found', true, 404 );
					$this->get_blank( _t( 'The page you were looking for was not found.' ) );
				}
				break;
		}
	}

	/**
	 * Handle incoming requests to /admin_ajax for admin ajax requests
	 */
	public function act_admin_ajax()
	{
		header( 'Content-Type: text/javascript;charset=utf-8' );
		$context = $this->handler_vars['context'];
		if ( method_exists( $this, 'ajax_' . $context ) ) {

			$type = ( isset( $this->handler_vars['content_type'] ) && !empty( $this->handler_vars['content_type'] ) ) ? $this->handler_vars['content_type'] : '';
			// Access check to see if the user is allowed the requested page
			if ( $this->access_allowed( 'ajax_' . $context, $type ) ) {
				call_user_func( array( $this, 'ajax_' . $context ), $this->handler_vars );
			}
		}
		else {
			header( 'HTTP/1.1 403 Forbidden', true, 403 );
			die();
		}
	}

	/**
	* Handles get requests for the system information page.
	*/
	public function get_sysinfo()
	{
		$sysinfo = array();
		$siteinfo = array();

		// Assemble Site Info
		$siteinfo[ _t( 'Habari Version' ) ] = Version::get_habariversion();
		if ( Version::is_devel() ) {
			$siteinfo[ _t( 'Habari Version' ) ] .= " " . Version::get_git_short_hash();
		}

		$siteinfo[ _t( 'Habari API Version' ) ] = Version::get_apiversion();
		$siteinfo[ _t( 'Habari DB Version' ) ] = Version::get_dbversion();
		$siteinfo[ _t( 'Active Theme' ) ] = Options::get( 'theme_name' );
		$siteinfo[ _t( 'System Locale' ) ] =  HabariLocale::get();
		$this->theme->siteinfo = $siteinfo;

		// Assemble System Info
		$sysinfo[ _t( 'PHP Version' ) ] = phpversion();
		$sysinfo[ _t( 'Server Software' ) ] = $_SERVER['SERVER_SOFTWARE'];
		$sysinfo[ _t( 'Database' ) ] = DB::get_driver_name() . ' - ' . DB::get_driver_version();
		$sysinfo[ _t( 'PHP Extensions' ) ] = implode( ', ', get_loaded_extensions() );
		$sysinfo[ _t( 'PHP Configuration Settings' ) ] = implode( "<br>", Utils::get_ini_settings() );
		if ( defined( 'PCRE_VERSION' ) ) {
			$sysinfo[ _t( 'PCRE Version' ) ] = PCRE_VERSION;
		}
		else {
			// probably PHP < 5.2.4
			ob_start();
			phpinfo( 8 );
			$phpinfo = ob_get_contents();
			ob_end_clean();
			preg_match( '/PCRE Library Version.*class="v">(.*)$/mi', $phpinfo, $matches );
			$sysinfo[ _t( 'PCRE Version' ) ] = $matches[ 1 ];
		}
		$sysinfo[ _t( 'Browser' ) ] = $_SERVER[ 'HTTP_USER_AGENT' ];
		$this->theme->sysinfo = $sysinfo;

		// Assemble Class Info
		$classinfo = Utils::glob( HABARI_PATH . "/user/classes/*.php" );
		if ( count( $classinfo ) ) {
			$classinfo = array_map( 'realpath', $classinfo );
		}
		$this->theme->classinfo = $classinfo;

		// Assemble Plugin Info
		$raw_plugins = Plugins::get_active();
		$plugins = array( 'system'=>array(), 'user'=>array(), '3rdparty'=>array(), 'other'=>array() );
		foreach ( $raw_plugins as $plugin ) {
			$file = $plugin->get_file();
			// Catch plugins that are symlinked from other locations as ReflectionClass->getFileName() only returns the ultimate file path, not the symlink path, and we really want the symlink path
			$all_plugins = Plugins::list_all();
			$filename = basename( $file );
			if ( array_key_exists( $filename, $all_plugins ) && $all_plugins[$filename] != $file ) {
				$file = $all_plugins[$filename];
			}
			if ( preg_match( '%[\\\\/](system|3rdparty|user)[\\\\/]plugins[\\\\/]%i', $file, $matches ) ) {
				// A plugin's info is XML, cast the element to a string. See #1026.
				$plugins[strtolower( $matches[1] )][(string)$plugin->info->name] = $file;
			}
			else {
				// A plugin's info is XML, cast the element to a string.
				$plugins['other'][(string)$plugin->info->name] = $file;
			}
		}
		$this->theme->plugins = $plugins;
		$this->theme->admin_page = _t( 'System Information' );

		$this->display( 'sysinfo' );
	}

	/**
	 * Display a blank admin page with appropriate navigation.
	 * This function terminates execution before returning.
	 * Useful for displaying errors when permission is denied for viewing.
	 *
	 * @param string $content Optional default content to display
	 */
	public function get_blank( $content = '' )
	{
		$this->theme->content = Plugins::filter( 'admin_blank_content', $content );

		$this->display( 'blank' );
		exit();
	}

	/**
	 * Assembles the main menu for the admin area.
	 * @param Theme $theme The theme to add the menu to
	 */
	protected function get_main_menu( $theme )
	{
		$page = ( isset( $this->handler_vars['page'] ) && !empty( $this->handler_vars['page'] ) ) ? $this->handler_vars['page'] : 'dashboard';

		// These need to be replaced with submenus, but access to them is provided temporarily
		$createmenu = array();
		$managemenu = array();
		$createperms = array();
		$manageperms = array();

		$i = 1;
		foreach ( Post::list_active_post_types() as $type => $typeint ) {
			if ( $typeint == 0 ) {
				continue;
			}

			if ( $i == 10 ) {
				$hotkey = 0;
			}
			elseif ( $i > 10 ) {
				$hotkey = false;
			}
			else {
				$hotkey = $i;
			}

			$plural = Plugins::filter( 'post_type_display', $type, 'plural' );
			$singular = Plugins::filter( 'post_type_display', $type, 'singular' );

			$createperm = array( 'post_' . $type => ACL::get_bitmask( 'create' ), 'post_any' => ACL::get_bitmask( 'create' ) );
			$createmenu['create_' . $typeint] = array( 'url' => URL::get( 'admin', 'page=publish&content_type=' . $type ), 'title' => _t( 'Create a new %s', array( $singular ) ), 'text' => $singular, 'access' => $createperm );
			$createperms = array_merge( $createperms, $createperm );

			$manageperm = array( 'post_' . $type => array( ACL::get_bitmask( 'edit' ), ACL::get_bitmask( 'delete' ) ), 'own_posts'=>array( ACL::get_bitmask( 'edit' ), ACL::get_bitmask( 'delete' ) ), 'post_any'=>array( ACL::get_bitmask( 'edit' ), ACL::get_bitmask( 'delete' ) ) );
			$managemenu['manage_' . $typeint] = array( 'url' => URL::get( 'admin', 'page=posts&type=' . $typeint ), 'title' => _t( 'Manage %s', array( $plural ) ), 'text' => $plural, 'access'=> $manageperm );
			$manageperms = array_merge( $manageperms, $manageperm );

			$createmenu['create_' . $typeint]['hotkey'] = $hotkey;
			$managemenu['manage_' . $typeint]['hotkey'] = $hotkey;

			if ( $page == 'publish' && isset( $this->handler_vars['content_type'] ) && $this->handler_vars['content_type'] == $type ) {
				$createmenu['create_' . $typeint]['selected'] = true;
			}
			if ( $page == 'posts' && isset( $this->handler_vars['type'] ) && $this->handler_vars['type'] == $typeint ) {
				$managemenu['manage_' . $typeint]['selected'] = true;
			}
			$i++;
		}

		$createperms = array_merge( $createperms, array( 'own_posts'=>array( ACL::get_bitmask( 'create' ) ) ) );
		$manageperms = array_merge( $manageperms, array( 'own_posts'=>array( ACL::get_bitmask( 'edit' ), ACL::get_bitmask( 'delete' ) ) ) );

		$adminmenu = array(
			'create' => array( 'url' => '', 'title' => _t( 'Create content' ), 'text' => _t( 'New' ), 'hotkey' => 'N', 'submenu' => $createmenu ),
			'manage' => array( 'url' => '', 'title' => _t( 'Manage content' ), 'text' => _t( 'Manage' ), 'hotkey' => 'M', 'submenu' => $managemenu ),
			'comments' => array( 'url' => URL::get( 'admin', 'page=comments' ), 'title' => _t( 'Manage comments' ), 'text' => _t( 'Comments' ), 'hotkey' => 'C', 'access' => array( 'manage_all_comments' => true, 'manage_own_post_comments' => true ) ),
			'tags' => array( 'url' => URL::get( 'admin', 'page=tags' ), 'title' => _t( 'Manage tags' ), 'text' => _t( 'Tags' ), 'hotkey' => 'A', 'access'=>array( 'manage_tags'=>true ), 'class' => 'over-spacer' ),
			'dashboard' => array( 'url' => URL::get( 'admin', 'page=' ), 'title' => _t( 'View your user dashboard' ), 'text' => _t( 'Dashboard' ), 'hotkey' => 'D', 'class' => 'under-spacer' ),
			'options' => array( 'url' => URL::get( 'admin', 'page=options' ), 'title' => _t( 'View and configure site options' ), 'text' => _t( 'Options' ), 'hotkey' => 'O', 'access'=>array( 'manage_options'=>true ) ),
			'themes' => array( 'url' => URL::get( 'admin', 'page=themes' ), 'title' => _t( 'Preview and activate themes' ), 'text' => _t( 'Themes' ), 'hotkey' => 'T', 'access'=>array( 'manage_theme'=>true ) ),
			'plugins' => array( 'url' => URL::get( 'admin', 'page=plugins' ), 'title' => _t( 'Activate, deactivate, and configure plugins' ), 'text' => _t( 'Plugins' ), 'hotkey' => 'P', 'access'=>array( 'manage_plugins'=>true, 'manage_plugins_config' => true ) ),
			'import' => array( 'url' => URL::get( 'admin', 'page=import' ), 'title' => _t( 'Import content from another site' ), 'text' => _t( 'Import' ), 'hotkey' => 'I', 'access'=>array( 'manage_import'=>true ) ),
			'users' => array( 'url' => URL::get( 'admin', 'page=users' ), 'title' => _t( 'View and manage users' ), 'text' => _t( 'Users' ), 'hotkey' => 'U', 'access'=>array( 'manage_users'=>true ) ),
			'profile' => array( 'url' => URL::get( 'admin', 'page=user' ), 'title' => _t( 'Manage your user profile' ), 'text' => _t( 'My Profile' ), 'hotkey' => 'Y', 'access'=>array( 'manage_self'=>true, 'manage_users'=>true ) ),
			'groups' => array( 'url' => URL::get( 'admin', 'page=groups' ), 'title' => _t( 'View and manage groups' ), 'text' => _t( 'Groups' ), 'hotkey' => 'G', 'access'=>array( 'manage_groups'=>true ) ),
			'logs' => array( 'url' => URL::get( 'admin', 'page=logs' ), 'title' => _t( 'View system log messages' ), 'text' => _t( 'Logs' ), 'hotkey' => 'L', 'access'=>array( 'manage_logs'=>true ), 'class' => 'over-spacer' ) ,
			'logout' => array( 'url' => URL::get( 'auth', 'page=logout' ), 'title' => _t( 'Log out of the administration interface' ), 'text' => _t( 'Logout' ), 'hotkey' => 'X', 'class' => 'under-spacer' ),
		);

		$mainmenus = array_merge( $adminmenu );

		foreach ( $mainmenus as $menu_id => $menu ) {
			// Change this to set the correct menu as the active menu
			if ( !isset( $mainmenus[$menu_id]['selected'] ) ) {
				$mainmenus[$menu_id]['selected'] = false;
			}
		}

		$mainmenus = Plugins::filter( 'adminhandler_post_loadplugins_main_menu', $mainmenus );

		foreach ( $mainmenus as $key => $attrs ) {
			if ( $page == $key && !isset($mainmenus[$key]['submenu'])) {
				$mainmenus[$key]['selected'] = true;
			}
		}

		$mainmenus = $this->filter_menus_by_permission( $mainmenus );

		// Strip out import if no importers are available
		if ( !Plugins::filter( 'import_names', array() ) )
			unset( $mainmenus['import'] );

		// Make submenu links default to the first available item
		foreach ( array_keys( $mainmenus ) as $action ) {
			if ( !$mainmenus[$action]['url'] && !empty( $mainmenus[$action]['submenu'] ) ) {
				$default = current( $mainmenus[$action]['submenu'] );
				$mainmenus[$action]['url'] = $default['url'];
			}
		}

		$theme->assign( 'mainmenu', $mainmenus );
	}

	/**
	 * Remove menus for which the user does not have qualifying permissions.
	 *
	 * @param array $menuarray The master array of admin menu items
	 * @return array The modified array of admin menu items
	 */
	protected function filter_menus_by_permission( $menuarray )
	{
		$user = User::identify();
		foreach ( $menuarray as $key => $attrs ) {
			if ( isset( $attrs['access'] ) ) {
				$attrs['access'] = Utils::single_array( $attrs['access'] );
				$pass = false;
				foreach ( $attrs['access'] as $token => $masks ) {
					$masks = Utils::single_array( $masks );
					foreach ( $masks as $mask ) {
						if ( is_bool( $mask ) ) {
							if ( $user->can( $token ) ) {
							$pass = true;
							break;
							}
						}
						else {
							if ( $user->cannot( $token ) ) {
								break 2;
							}
							else {
								if ( $user->can( $token, $mask ) ) {
									$pass = true;
									break 2;

								}
							}
						}
					}
				}
				if ( !$pass ) {
					unset( $menuarray[$key] );
				}
			}
			if ( isset( $attrs['submenu'] ) && count( $attrs['submenu'] ) > 0 ) {
				$menuarray[$key]['submenu'] = $this->filter_menus_by_permission( $attrs['submenu'] );
				if ( count( $menuarray[$key]['submenu'] ) == 0 ) {
					unset( $menuarray[$key]['submenu'] );
					unset( $menuarray[$key] );
				}
			}
			if ( isset( $menuarray[$key] ) && count( $menuarray[$key] ) == 0 ) {
				unset( $menuarray[$key] );
			}
		}
		return $menuarray;
	}

	/**
	 * Checks if the currently logged in user has access to a page and post type.
	 */
	private function access_allowed( $page, $type )
	{
		$user = User::identify();
		$require_any = array();
		$result = false;

		switch ( $page ) {
			case 'comment':
			case 'comments':
			case 'ajax_comments':
			case 'ajax_in_edit':
			case 'ajax_update_comment':
				$require_any = array( 'manage_all_comments' => true, 'manage_own_post_comments' => true );
				break;

			case 'tags':
			case 'ajax_tags':
			case 'ajax_get_tags':
				$require_any = array( 'manage_tags' => true );
				break;
			case 'options':
				$require_any = array( 'manage_options' => true );
				break;
			case 'themes':
				$require_any = array( 'manage_themes' => true, 'manage_theme_config' => true );
				break;
			case 'activate_theme':
				$require_any = array( 'manage_themes' => true );
				break;
			case 'preview_theme':
				$require_any = array( 'manage_themes' => true );
				break;
			case 'plugins':
				$require_any = array( 'manage_plugins' => true, 'manage_plugins_config' => true );
				break;
			case 'plugin_toggle':
				$require_any = array( 'manage_plugins' => true );
				break;
			case 'import':
				$require_any = array( 'manage_import' => true );
				break;
			case 'users':
			case 'ajax_update_users':
			case 'ajax_users':
				$require_any = array( 'manage_users' => true );
				break;
			case 'user':
				$require_any = array( 'manage_users' => true, 'manage_self' => true );
				break;
			case 'groups':
			case 'group':
			case 'ajax_update_groups':
			case 'ajax_groups':
				$require_any = array( 'manage_groups' => true );
				break;
			case 'logs':
			case 'ajax_delete_logs':
			case 'ajax_logs':
				$require_any = array( 'manage_logs' => true );
				break;
			case 'publish':
			case 'ajax_media':
			case 'ajax_media_panel':
			case 'ajax_media_upload':
				$type = Post::type_name( $type );
				$require_any = array(
					'post_any' => array( ACL::get_bitmask( 'create' ), ACL::get_bitmask( 'edit' ) ),
					'post_' . $type => array( ACL::get_bitmask( 'create' ), ACL::get_bitmask( 'edit' ) ),
					'own_posts' => array( ACL::get_bitmask( 'create' ), ACL::get_bitmask( 'edit' ) ),
				);
				break;
			case 'delete_post':
				$type = Post::type_name( $type );
				$require_any = array(
					'post_any' => ACL::get_bitmask( 'delete' ),
					'post_' . $type => ACL::get_bitmask( 'delete' ),
					'own_posts' => ACL::get_bitmask( 'delete' ),
				);
				break;
			case 'posts':
			case 'ajax_posts':
			case 'ajax_update_posts':
				$require_any = array(
					'post_any' => array( ACL::get_bitmask( 'delete' ), ACL::get_bitmask( 'edit' ) ),
					'own_posts' => array( ACL::get_bitmask( 'delete' ), ACL::get_bitmask( 'edit' ) ),
				);
				foreach ( Post::list_active_post_types() as $type => $type_id ) {
					$require_any['post_' . $type] = array( ACL::get_bitmask( 'delete' ), ACL::get_bitmask( 'edit' ) );
				}
				break;
			case 'sysinfo':
				$require_any = array( 'super_user' => true );
				break;
			case 'dashboard':
			case 'ajax_dashboard':
				$result = true;
				break;
			case 'ajax_add_block':
				$result = true;
				break;
			case 'ajax_delete_block':
				$result = true;
				break;
			case 'configure_block':
				$result = true;
				break;
			case 'ajax_save_areas':
				$result = true;
				break;
			case 'locale':
				$result = true;
				break;
			default:
				break;
		}

		$require_any = Plugins::filter( 'admin_access_tokens', $require_any, $page, $type );

		foreach ( $require_any as $token => $access ) {
			$access = Utils::single_array( $access );
			foreach ( $access as $mask ) {
				if ( is_bool( $mask ) && $user->can( $token ) ) {
					$result = true;
					break;
				}
				elseif ( $user->can( $token, $mask ) ) {
					$result = true;
					break 2;
				}
			}
		}

		$result = Plugins::filter( 'admin_access', $result, $page, $type );

		return $result;
	}

	/**
	 * Assigns the main menu to $mainmenu into the theme.
	 */
	protected function set_admin_template_vars( $theme )
	{
		$this->get_main_menu( $theme );
	}

	/**
	 * Helper function to assign all handler_vars into the theme and displays a theme template.
	 * @param template_name Name of template to display (note: not the filename)
	 */
	protected function display( $template_name )
	{
		$this->theme->display( $template_name );
	}

	/**
	 * Setup the default admin javascript stack here so that it can be called
	 * from plugins, etc. This is not an ideal solution, but works for now.
	 *
	 */
	public static function setup_stacks()
	{
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/jquery.js", 'jquery' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/jquery-ui.min.js", 'jquery.ui', 'jquery' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/jquery.color.js", 'jquery.color', 'jquery' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/jquery.ui.nestedSortable.js", 'jquery-nested-sortable', 'jquery.ui' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/humanmsg/humanmsg.js", 'humanmsg', 'jquery' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/jquery.hotkeys.js", 'jquery.hotkeys', 'jquery' );
		Stack::add( 'admin_header_javascript', URL::get( 'admin', 'page=locale'), 'locale' );
		Stack::add( 'admin_header_javascript', Site::get_url( 'admin_theme' ) . "/js/media.js", 'media', array('jquery', 'locale') );
		Stack::add( 'admin_header_javascript', Site::get_url( 'admin_theme' ) . "/js/admin.js", 'admin', array('jquery', 'locale') );

		Stack::add( 'admin_header_javascript', Site::get_url( 'vendor' ) . "/crc32.js", 'crc32' );
	}

	public function create_theme()
	{
		$theme_dir = Plugins::filter( 'admin_theme_dir', Site::get_dir( 'admin_theme', true ) );
		$this->theme = Themes::create( 'admin', 'RawPHPEngine', $theme_dir );
	}

}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminImportHandler Class
 * Handles import-related actions in the admin
 *
 */
class AdminImportHandler extends AdminHandler
{
	/**
	 * Handles GET requests for the import page.
	 */
	public function get_import()
	{
		// First check for troublesome plugins
		$bad_features = array(
		    'ping',
		    'pingback',
		    'spamcheck',
		);
		$troublemakers = array();
		$plugins = Plugins::list_active();
		foreach( $plugins as $plugin ) {
			$info = Plugins::load_info( $plugin );
			$provides = array();
			if( isset($info->provides ) ) {
				foreach( $info->provides->feature as $feature ) {
					$provides[] = $feature;
				}
			}
			$has_bad = array_intersect( $bad_features, $provides );
			if( count( $has_bad ) ) {
				$troublemakers[] = $info->name;
			}
		}
		if( count( $troublemakers ) ) {
			$troublemakers = implode( ', ', $troublemakers );
			$msg = _t( 'Plugins that conflict with importing are active. To prevent undesirable consequences, please de-activate the following plugins until the import is finished: ' ) . '<br>';
			$msg .= $troublemakers;
			$this->theme->conflicting_plugins = $msg;
			Session::error( $msg );
		}

		// Now get on with creating the page
		$importer = isset( $_POST['importer'] ) ? $_POST['importer'] : '';
		$stage = isset( $_POST['stage'] ) ? $_POST['stage'] : '1';
		$step = isset( $_POST['step'] ) ? $_POST['step'] : '1';

		$this->theme->enctype = Plugins::filter( 'import_form_enctype', 'application/x-www-form-urlencoded', $importer, $stage, $step );

		// filter to get registered importers
		$importers = Plugins::filter( 'import_names', array() );

		// fitler to get the output of the current importer, if one is running
		if ( $importer != '' ) {
			$output = Plugins::filter( 'import_stage', '', $importer, $stage, $step );
		}
		else {
			$output = '';
		}

		$this->theme->importer = $importer;
		$this->theme->stage = $stage;
		$this->theme->step = $step;
		$this->theme->importers = $importers;
		$this->theme->output = $output;

		$this->display( 'import' );

	}

	/**
	 * Handles the submission of the import form, importing data from a WordPress database.
	 * This function should probably be broken into an importer class, since it is WordPress-specific.
	 */
	public function post_import()
	{
		if ( !isset( $_POST['importer'] ) ) {
			Utils::redirect( URL::get( 'admin', 'page=import' ) );
		}

		$this->get_import();
	}

}

repo_name: DaSourcerer/habari


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminLocaleHandler Class
 * Returns locale data as javascript for the admin
 *
 */
class AdminLocaleHandler extends AdminHandler
{
	public function get_locale() {

		header('Expires: ' . gmdate('D, d M Y H:i:s ', time() + 432000) . 'GMT');
		header('content-type: text/javascript');

		$domain = HabariLocale::get_messages();
		$domain_json = json_encode($domain);

		echo <<< tee
function _t() {
	var domain = {$domain_json};
	var s = arguments[0];

	if(domain[s] != undefined) {
		s = domain[s][1][0];
	}

	for(var i = 1; i <= arguments.length; i++) {
		r = new RegExp('%' + (i) + '\\\\\$s', 'g');
		if(!s.match(r)) {
			r = new RegExp('%s');
		}
		s = s.replace(r, arguments[i]);
	}
	return s;
}

tee;

	}
}


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminLogsHandler Class
 * Handles log-related actions in the admin
 *
 */
class AdminLogsHandler extends AdminHandler
{
	/**
	 * Handle GET requests for /admin/logs to display the logs.
	 */
	public function get_logs()
	{
		$this->post_logs();
	}

	/**
	 * Handle POST requests for /admin/logs to display the logs.
	 */
	public function post_logs()
	{
		$this->fetch_logs();
		$this->display( 'logs' );
	}

	private function fetch_logs()
	{
		// load all the values for our filter drop-downs
		$dates = $this->fetch_log_dates();
		$users = $this->fetch_log_users();
		$ips = $this->fetch_log_ips();
		extract( $this->fetch_log_modules_types() ); // $modules and $types
		$severities = LogEntry::list_severities();

		// parse out the arguments we'll fetch logs for

		// the initial arguments
		$arguments = array(
			'limit' => Controller::get_var( 'limit', 20 ),
			'offset' => Controller::get_var( 'offset', 0 ),
		);

		// filter for the search field
		$search = Controller::get_var( 'search', '' );

		if ( $search != '' ) {
			$arguments['criteria'] = $search;
		}

		// filter by date
		$date = Controller::get_var( 'date', 'any' );

		if ( $date != 'any' ) {
			$d = HabariDateTime::date_create( $date );	// ! means fill any non-specified pieces with default Unix Epoch ones
			$arguments['year'] = $d->format( 'Y' );
			$arguments['month'] = $d->format( 'm' );
		}

		// filter by user
		$user = Controller::get_var( 'user', 'any' );

		if ( $user != 'any' ) {
			$arguments['user_id'] = $user;
		}

		// filter by ip
		$ip = Controller::get_var( 'address', 'any' );

		if ( $ip != 'any' ) {
			$arguments['ip'] = $ip;
		}

		// filter modules and types
		// @todo get events of a specific type in a specific module, instead of either of the two
		// the interface doesn't currently make any link between module and type, so we won't worry about it for now

		$module = Controller::get_var( 'module', 'any' );
		$type = Controller::get_var( 'type', 'any' );

		if ( $module != 'any' ) {
			// we get a slugified key back, get the actual module name
			$arguments['module'] = $modules[ $module ];
		}

		if ( $type != 'any' ) {
			// we get a slugified key back, get the actual type name
			$arguments['type'] = $types[ $type ];
		}

		// filter by severity
		$severity = Controller::get_var( 'severity', 0 );
		if ( $severity != 0) {
			$arguments['severity'] = $severity;
		}

		// get the logs!
		$logs = EventLog::get( $arguments );

		// last, but not least, generate the list of years used for the timeline
		$months = EventLog::get( array_merge( $arguments, array( 'month_cts' => true ) ) );

		$years = array();
		foreach ( $months as $m ) {

			$years[ $m->year ][] = $m;

		}

		// assign all our theme values in one spot

		// first the filter options
		$this->theme->dates = $dates;
		$this->theme->users = $users;
		$this->theme->addresses = $ips;
		$this->theme->modules = $modules;
		$this->theme->types = $types;
		$this->theme->severities = $severities;

		// next the filter criteria we used
		$this->theme->search_args = $search;
		$this->theme->date = $date;
		$this->theme->user = $user;
		$this->theme->address = $ip;
		$this->theme->module = $module;
		$this->theme->type = $type;
		$this->theme->severity = $severity;

		$this->theme->logs = $logs;

		$this->theme->years = $years;

		$this->theme->wsse = Utils::WSSE(); // prepare a WSSE token for any ajax calls

	}

	private function fetch_log_dates()
	{
		$db_dates = DB::get_column( 'SELECT timestamp FROM {log} ORDER BY timestamp DESC' );
		$dates = array(
			'any' => 'Any'
		);

		foreach ( $db_dates as $db_date ) {
			$date = HabariDateTime::date_create( $db_date )->format( 'Y-m' );
			$dates[ $date ] = $date;
		}
		return $dates;
	}

	private function fetch_log_users()
	{
		$db_users = DB::get_results( 'SELECT DISTINCT username, user_id FROM {users} JOIN {log} ON {users}.id = {log}.user_id ORDER BY username ASC' );
		$users = array(
			'any' => 'Any'
		);
		foreach ( $db_users as $db_user ) {
			$users[ $db_user->user_id ] = $db_user->username;
		}
		return $users;
	}

	private function fetch_log_ips()
	{
		$db_ips = DB::get_column( 'SELECT DISTINCT(ip) FROM {log}' );
		$ips = array(
			'any' => 'Any'
		);

		foreach ( $db_ips as $db_ip ) {
			$ips[ $db_ip ] = $db_ip;
		}
		return $ips;
	}

	private function fetch_log_modules_types()
	{
		$module_list = LogEntry::list_logentry_types();
		$modules = $types = array(
			'any' => 'Any',
		);

		foreach ( $module_list as $module_name => $type_array ) {
			// Utils::slugify() gives us a safe key to use - this is what will be handed to the filter after a POST as well
			$modules[ Utils::slugify( $module_name ) ] = $module_name;
			foreach ( $type_array as $type_name => $type_value ) {
				$types[ Utils::slugify( $type_name ) ] = $type_name;
			}
		}
		return array( 'modules' => $modules, 'types' => $types );
	}

	/**
	 * Handles AJAX requests from the logs page.
	 */
	public function ajax_logs()
	{
		Utils::check_request_method( array( 'GET', 'HEAD' ) );

		$this->create_theme();

		$this->fetch_logs();
		$items = $this->theme->fetch( 'logs_items' );
		$timeline = $this->theme->fetch( 'timeline_items' );

		$item_ids = array();

		foreach ( $this->theme->logs as $log ) {
			$item_ids['p' . $log->id] = 1;
		}

		$ar = new AjaxResponse();
		$ar->data = array(
			'items' => $items,
			'item_ids' => $item_ids,
			'timeline' => $timeline,
		);
		$ar->out();
	}

	/**
	 * Handles AJAX from /logs.
	 * Used to delete logs.
	 */
	public function ajax_delete_logs( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$count = 0;

		$wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
		if ( $handler_vars['digest'] != $wsse['digest'] ) {
			Session::error( _t( 'WSSE authentication failed.' ) );
			echo Session::messages_get( true, array( 'Format', 'json_messages' ) );
			return;
		}
		foreach ( $_POST as $id => $delete ) {
			// skip POST elements which are not log ids
			if ( preg_match( '/^p\d+$/', $id ) && $delete ) {
				$id = (int) substr( $id, 1 );
				$ids[] = array( 'id' => $id );
			}
		}

		if ( ( ! isset( $ids ) || empty( $ids ) ) && $handler_vars['action'] != 'purge' ) {
			Session::notice( _t( 'No logs selected.' ) );
			echo Session::messages_get( true, array( 'Format', 'json_messages' ) );
			return;
		}

		switch ( $handler_vars['action'] ) {
			case 'delete':
				$to_delete = EventLog::get( array( 'date' => 'any', 'where' => $ids, 'nolimit' => 1 ) );
				foreach ( $to_delete as $log ) {
					$log->delete();
					$count++;
				}
				Session::notice( _t( 'Deleted %d logs.', array( $count ) ) );
				break;
			case 'purge':
				$result = EventLog::purge();
				Session::notice( _t( 'Logs purged.' ) );
				break;
		}

		echo Session::messages_get( true, array( 'Format', 'json_messages' ) );
	}

}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminOptionsHandler Class
 * Handles options-related actions in the admin
 *
 */
class AdminOptionsHandler extends AdminHandler
{
	/**
	 * Handles get requests from the options admin page
	 */
	public function get_options()
	{
		$this->post_options();
	}

	/**
	 * Handles POST requests from the options admin page
	 */
	public function post_options()
	{
		$option_items = array();
		$timezones = DateTimeZone::listIdentifiers();
		$timezones = array_merge( array( ''=>'' ), array_combine( array_values( $timezones ), array_values( $timezones ) ) );

		$option_items[_t( 'Name & Tagline' )] = array(
			'title' => array(
				'label' => _t( 'Site Name' ),
				'type' => 'text',
				'helptext' => '',
				),
			'tagline' => array(
				'label' => _t( 'Site Tagline' ),
				'type' => 'text',
				'helptext' => '',
				),
			'about'   => array(
				'label'    => _t( 'About' ),
				'type'     => 'textarea',
				'helptext' => '',
				),
			);

		$option_items[_t( 'Publishing' )] = array(
			'pagination' => array(
				'label' => _t( 'Items per Page' ),
				'type' => 'text',
				'helptext' => '',
				),
			'atom_entries' => array(
				'label' => _t( 'Entries to show in Atom feed' ),
				'type' => 'text',
				'helptext' => '',
				),
			'comments_require_id' => array(
				'label' => _t( 'Require Comment Author Info' ),
				'type' => 'checkbox',
				'helptext' => '',
				),
			'spam_percentage' => array(
				'label' => _t( 'Comment SPAM Threshold' ),
				'type' => 'text',
				'helptext' => _t('The likelihood a comment is considered SPAM, in percent.'),
				),
			);

		$option_items[_t( 'Time & Date' )] = array(
			/*'presets' => array(
				'label' => _t('Presets'),
				'type' => 'select',
				'selectarray' => array(
					'europe' => _t('Europe')
					),
				'helptext' => '',
				),*/
			'timezone' => array(
				'label' => _t( 'Time Zone' ),
				'type' => 'select',
				'selectarray' => $timezones,
				'helptext' => _t( 'Current Date Time: %s', array( HabariDateTime::date_create()->format() ) ),
				),
			'dateformat' => array(
				'label' => _t( 'Date Format' ),
				'type' => 'text',
				'helptext' => _t( 'Current Date: %s', array( HabariDateTime::date_create()->date ) ),
				),
			'timeformat' => array(
				'label' => _t( 'Time Format' ),
				'type' => 'text',
				'helptext' => _t( 'Current Time: %s', array( HabariDateTime::date_create()->time ) ),
				)
			);

		$option_items[_t( 'Language' )] = array(
			'locale' => array(
				'label' => _t( 'Locale' ),
				'type' => 'select',
				'selectarray' => array_merge( array( '' => 'default' ), array_combine( HabariLocale::list_all(), HabariLocale::list_all() ) ),
				'helptext' => Config::exists('locale') ? _t('International language code : This value is set in your config.php file, and cannot be changed here.') : _t( 'International language code' ),
				'disabled' => Config::exists('locale'),
				'value' => Config::get('locale', Options::get( 'locale', 'en-us' )),
			),
			'system_locale' => array(
				'label' => _t( 'System Locale' ),
				'type' => 'text',
				'helptext' => _t( 'The appropriate locale code for your server' ),
			),
		);

		$option_items[_t( 'Troubleshooting' )] = array(
			'log_min_severity' => array(
				'label' => _t( 'Minimum Severity' ),
				'type' => 'select',
				'selectarray' => LogEntry::list_severities(),
				'helptext' => _t( 'Only log entries with a this or higher severity.' ),
			),
			'log_backtraces' => array(
				'label' => _t( 'Log Backtraces' ),
				'type' => 'checkbox',
				'helptext' => _t( 'Logs error backtraces to the log table\'s data column. Can drastically increase log size!' ),
			),
		);

			/*$option_items[_t('Presentation')] = array(
			'encoding' => array(
				'label' => _t('Encoding'),
				'type' => 'select',
				'selectarray' => array(
					'UTF-8' => 'UTF-8'
					),
				'helptext' => '',
				),
			);*/

		$option_items = Plugins::filter( 'admin_option_items', $option_items );

		$form = new FormUI( 'Admin Options' );
		$tab_index = 3;
		foreach ( $option_items as $name => $option_fields ) {
			$fieldset = $form->append( 'wrapper', Utils::slugify( _u( $name ) ), $name );
			$fieldset->class = 'container settings';
			$fieldset->append( 'static', $name, '<h2>' . htmlentities( $name, ENT_COMPAT, 'UTF-8' ) . '</h2>' );
			foreach ( $option_fields as $option_name => $option ) {
				$field = $fieldset->append( $option['type'], $option_name, $option_name, $option['label'] );
				$field->template = 'optionscontrol_' . $option['type'];
				$field->class = 'item clear';
				if(isset($option['value'])) {
					$field->value = $option['value'];
				}
				if(isset($option['disabled'])) {
					$field->disabled = $option['disabled'];
				}
				if ( $option['type'] == 'select' && isset( $option['selectarray'] ) ) {
					$field->options = $option['selectarray'];
				}
				$field->tabindex = $tab_index;
				$tab_index++;
				if ( isset( $option['helptext'] ) ) {
					$field->helptext = $option['helptext'];
				}
				else {
					$field->helptext = '';
				}
			}
		}

		/* @todo: filter for additional options from plugins
		 * We could either use existing config forms and simply extract
		 * the form controls, or we could create something different
		 */

		$submit = $form->append( 'submit', 'apply', _t( 'Apply' ), 'admincontrol_submit' );
		$submit->tabindex = $tab_index;
		$form->on_success( array( $this, 'form_options_success' ) );

		$this->theme->form = $form->get();
		$this->theme->option_names = array_keys( $option_items );
		$this->theme->display( 'options' );
		}

	/**
	 * Display a message when the site options are saved, and save those options
	 *
	 * @param FormUI $form The successfully submitted form
	 */
	public function form_options_success( $form )
	{
		Session::notice( _t( 'Successfully updated options' ) );
		$form->save();
		Utils::redirect();
	}

}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminPluginsHandler Class
 * Handles plugin-related actions in the admin
 *
 */
class AdminPluginsHandler extends AdminHandler
{
	/**
	 * Display the plugin administration page
	 */
	public function get_plugins()
	{
		$all_plugins = Plugins::list_all();
		$active_plugins = Plugins::get_active();

		$sort_active_plugins = array();
		$sort_inactive_plugins = array();
		$providing = array();
		$available = array();

		foreach ( $all_plugins as $file ) {
			$plugin = array();
			$plugin_id = Plugins::id_from_file( $file );
			$plugin['plugin_id'] = $plugin_id;
			$plugin['file'] = $file;

			$error = '';

			if ( Utils::php_check_file_syntax( $file, $error ) ) {
				$plugin['debug'] = false;
				$plugin['info'] = Plugins::load_info( $file );
				if ( array_key_exists( $plugin_id, $active_plugins ) ) {
					$plugin['verb'] = _t( 'Deactivate' );
					$pluginobj = $active_plugins[$plugin_id];
					$plugin['active'] = true;
					$plugin_actions = array();
					$plugin_actions1 = Plugins::filter_id( 'plugin_config', $plugin_id, $plugin_actions, $plugin_id );
					$plugin_actions = Plugins::filter( 'plugin_config_any', $plugin_actions1, $plugin_id );
					$plugin['actions'] = array();
					foreach ( $plugin_actions as $plugin_action => $plugin_action_caption ) {
						if ( is_numeric( $plugin_action ) ) {
							$plugin_action = $plugin_action_caption;
						}
						$action = array(
							'caption' => $plugin_action_caption,
							'action' => $plugin_action,
						);
						$urlparams = array( 'page' => 'plugins', 'configure'=>$plugin_id);
						$action['url'] = URL::get( 'admin', $urlparams );

						if ( $action['caption'] == _t( '?' ) ) {
							if ( isset( $_GET['configaction'] ) ) {
								$urlparams['configaction'] = $_GET['configaction'];
							}
							if ( $_GET['help'] != $plugin_action ) {
								$urlparams['help'] = $plugin_action;
							}
							$action['url'] = URL::get( 'admin', $urlparams );
							$plugin['help'] = $action;
						}
						else {
							if ( isset( $_GET['help'] ) ) {
								$urlparams['help'] = $_GET['help'];
							}
							$urlparams['configaction'] = $plugin_action;
							$action['url'] = URL::get( 'admin', $urlparams );
							$plugin['actions'][$plugin_action] = $action;
						}
					}
					$plugin['actions']['deactivate'] = array(
						'url' =>  URL::get( 'admin', 'page=plugin_toggle&plugin_id=' . $plugin['plugin_id'] . '&action=deactivate' ),
						'caption' => _t( 'Deactivate' ),
						'action' => 'Deactivate',
					);

					if ( isset( $plugin['info']->provides ) ) {
						foreach ( $plugin['info']->provides->feature as $feature ) {
							$providing[(string) $feature] = $feature;
						}
					}
				}
				else {
					// instantiate this plugin
					// in order to get its info()
					$plugin['active'] = false;
					$plugin['verb'] = _t( 'Activate' );
					$plugin['actions'] = array(
						'activate' => array(
							'url' =>  URL::get( 'admin', 'page=plugin_toggle&plugin_id=' . $plugin['plugin_id'] . '&action=activate' ),
							'caption' => _t( 'Activate' ),
							'action' => 'activate',
						),
					);
					if ( isset( $plugin['info']->help ) ) {
						if ( isset( $_GET['configaction'] ) ) {
							$urlparams['configaction'] = $_GET['configaction'];
						}
						if ( $_GET['help'] != '_help' ) {
							$urlparams['help'] = '_help';
						}
						$action['caption'] = _t( '?' );
						$action['action'] = '_help';
						$urlparams = array( 'page' => 'plugins', 'configure' => $plugin_id );
						$action['url'] = URL::get( 'admin', $urlparams );
						$plugin['help'] = $action;
					}
					if ( isset( $plugin['info']->provides ) ) {
						foreach ( $plugin['info']->provides->feature as $feature ) {
							$available[(string) $feature][$plugin_id] = $plugin['info']->name;
						}
					}
				}
			}
			else {
				$plugin['debug'] = true;
				$plugin['error'] = $error;
				$plugin['active'] = false;
			}
			if ( isset( $this->handler_vars['configure'] ) && ( $this->handler_vars['configure'] == $plugin['plugin_id'] ) ) {
				if ( isset( $plugin['help'] ) && Controller::get_var( 'configaction' ) == $plugin['help']['action'] ) {
					$this->theme->config_plugin_caption = _t( 'Help' );
				}
				else {
					if ( isset( $plugin['actions'][Controller::get_var( 'configaction' )] ) ) {
						$this->theme->config_plugin_caption = $plugin['actions'][Controller::get_var( 'configaction' )]['caption'];
					}
					else {
						$this->theme->config_plugin_caption = Controller::get_var( 'configaction' );
					}
				}
				unset( $plugin['actions'][Controller::get_var( 'configaction' )] );
				$this->theme->config_plugin = $plugin;
			}
			else if ( $plugin['active'] ) {
				$sort_active_plugins[$plugin_id] = $plugin;
			}
			else {
				$sort_inactive_plugins[$plugin_id] = $plugin;
			}
		}

		// Get the features that the current theme provides
		$themeinfo = Themes::get_active_data();
		if ( isset( $themeinfo['info']->provides ) ) {
			foreach ( $themeinfo['info']->provides->feature as $feature ) {
				$providing[(string) $feature] = $feature;
			}
		}

		foreach ( $sort_inactive_plugins as $plugin_id => $plugin ) {
			if ( isset( $plugin['info']->requires ) ) {
				foreach ( $plugin['info']->requires->feature as $feature ) {
					if ( !isset( $providing[(string) $feature] ) ) {
						if( isset( $available[(string) $feature] ) ) {
							$sort_inactive_plugins[$plugin_id]['available'][(string) $feature] = $available[(string) $feature];
							if(count($sort_inactive_plugins[$plugin_id]['available'][(string) $feature]) > 1) {
								unset( $sort_inactive_plugins[$plugin_id]['actions']['activate'] );
							}
						}
						else {
							if ( !isset( $sort_inactive_plugins[$plugin_id]['missing'] ) ) {
								$sort_inactive_plugins[$plugin_id]['missing'] = array();
							}
							$sort_inactive_plugins[$plugin_id]['missing'][(string) $feature] = isset( $feature['url'] ) ? $feature['url'] : '';
							unset( $sort_inactive_plugins[$plugin_id]['actions']['activate'] );
						}
					}
				}
			}
		}

		//$this->theme->plugins = array_merge($sort_active_plugins, $sort_inactive_plugins);
		$this->theme->assign( 'configaction', Controller::get_var( 'configaction' ) );
		$this->theme->assign( 'helpaction', Controller::get_var( 'help' ) );
		$this->theme->assign( 'configure', Controller::get_var( 'configure' ) );
		uasort($sort_active_plugins, array( $this, 'compare_names' ) );
		uasort($sort_inactive_plugins, array( $this, 'compare_names' ) );
		$this->theme->active_plugins = $sort_active_plugins;
		$this->theme->inactive_plugins = $sort_inactive_plugins;

		$this->theme->plugin_loader = Plugins::filter( 'plugin_loader', '', $this->theme );

		$this->display( 'plugins' );
	}

	/**
	 * A POST handler for the admin plugins page that simply passes those options through.
	 */
	public function post_plugins()
	{
		return $this->get_plugins();
	}

	/**
	 * Handles plugin activation or deactivation.
	 */
	public function get_plugin_toggle()
	{
		$extract = $this->handler_vars->filter_keys( 'plugin_id', 'action' );
		foreach ( $extract as $key => $value ) {
			$$key = $value;
		}

		$plugins = Plugins::list_all();
		foreach ( $plugins as $file ) {
			if ( Plugins::id_from_file( $file ) == $plugin_id ) {
				switch ( strtolower( $action ) ) {
					case 'activate':
						if ( Plugins::activate_plugin( $file ) ) {
							$plugins = Plugins::get_active();
							Session::notice(
								_t( "Activated plugin '%s'", array( $plugins[Plugins::id_from_file( $file )]->info->name ) ),
								$plugins[Plugins::id_from_file( $file )]->plugin_id
							);
						}
						break;
					case 'deactivate':
						if ( Plugins::deactivate_plugin( $file ) ) {
							$plugins = Plugins::get_active();
							Session::notice(
								_t( "Deactivated plugin '%s'", array( $plugins[Plugins::id_from_file( $file )]->info->name ) ),
								$plugins[Plugins::id_from_file( $file )]->plugin_id
							);
						}
						break;
					default:
						Plugins::act(
							'adminhandler_get_plugin_toggle_action',
							$action,
							$file,
							$plugin_id,
							$plugins
						);
						break;
				}
			}
		}
		Utils::redirect( URL::get( 'admin', 'page=plugins' ) );
	}

	/*
	 * Compare function for uasort()
	 * @param array $a The first element to compare
	 * @param array $b The second element to compare
	 * @return integer. 0 if the strings are equal, <0 if the first parameter is less than the second,
	 * and >0 if the first parameter is greater than the second
	 */
	protected function compare_names( $a, $b )
	{
		$aname = isset($a['info']) ? $a['info']->name : '';
		$bname = isset($b['info']) ? $b['info']->name : '';
		return strcmp( MultiByte::strtolower( $aname), MultiByte::strtolower( $bname ) );
	}

}


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminPostsHandler Class
 * Handles posts-related actions in the admin
 *
 */
class AdminPostsHandler extends AdminHandler
{
	/**
	 * Handles GET requests of the publish page.
	 */
	public function get_publish( $template = 'publish' )
	{
		$extract = $this->handler_vars->filter_keys( 'id', 'content_type' );
		foreach ( $extract as $key => $value ) {
			$$key = $value;
		}

		// 0 is what's assigned to new posts
		if ( isset( $id ) && ( $id != 0 ) ) {
			$post = Post::get( array( 'id' => $id, 'status' => Post::status( 'any' ) ) );
			if ( !$post ) {
				Session::error( _t( "You don't have permission to edit that post" ) );
				$this->get_blank();
			}
			if ( ! ACL::access_check( $post->get_access(), 'edit' ) ) {
				Session::error( _t( "You don't have permission to edit that post" ) );
				$this->get_blank();
			}
			$this->theme->post = $post;
		}
		else {
			$post = new Post();
			$this->theme->post = $post;
			$post->content_type = Post::type( ( isset( $content_type ) ) ? $content_type : 'entry' );

			// check the user can create new posts of the set type.
			$user = User::identify();
			$type = 'post_' . Post::type_name( $post->content_type );
			if ( ACL::user_cannot( $user, $type ) || ( ! ACL::user_can( $user, 'post_any', 'create' ) && ! ACL::user_can( $user, $type, 'create' ) ) ) {
				Session::error( _t( 'Access to create posts of type %s is denied', array( Post::type_name( $post->content_type ) ) ) );
				$this->get_blank();
			}
		}

		$this->theme->admin_page = _t( 'Publish %s', array( Plugins::filter( 'post_type_display', Post::type_name( $post->content_type ), 'singular' ) ) );
		$this->theme->admin_title = _t( 'Publish %s', array( Plugins::filter( 'post_type_display', Post::type_name( $post->content_type ), 'singular' ) ) );

		$statuses = Post::list_post_statuses( false );
		$this->theme->statuses = $statuses;

		$form = $post->get_form( 'admin' );

		$this->theme->form = $form;

		$this->theme->wsse = Utils::WSSE();
		$this->display( $template );
	}

	/**
	 * Handles POST requests from the publish page.
	 */
	public function post_publish()
	{
		$this->get_publish();
	}

	/**
	 * Deletes a post from the database.
	 */
	public function post_delete_post()
	{
		$extract = $this->handler_vars->filter_keys( 'id', 'nonce', 'timestamp', 'digest' );
		foreach ( $extract as $key => $value ) {
			$$key = $value;
		}

		$okay = true;
		if ( empty( $id ) || empty( $nonce ) || empty( $timestamp ) || empty( $digest ) ) {
			$okay = false;
		}
		$wsse = Utils::WSSE( $nonce, $timestamp );
		if ( $digest != $wsse['digest'] ) {
			$okay = false;
		}

		$post = Post::get( array( 'id' => $id, 'status' => Post::status( 'any' ) ) );
		if ( ! ACL::access_check( $post->get_access(), 'delete' ) ) {
			$okay = false;
		}

		if ( !$okay ) {
			Utils::redirect( URL::get( 'admin', 'page=posts&type='. Post::status( 'any' ) ) );
		}

		$post->delete();
		Session::notice( _t( 'Deleted the %1$s titled "%2$s".', array( Post::type_name( $post->content_type ), Utils::htmlspecialchars( $post->title ) ) ) );
		Utils::redirect( URL::get( 'admin', 'page=posts&type=' . Post::status( 'any' ) ) );
	}

	/**
	 * Assign values needed to display the posts page to the theme based on handlervars and parameters
	 *
	 */
	private function fetch_posts( $params = array() )
	{
		// Make certain handler_vars local with defaults, and add them to the theme output
		$locals = array(
			'do_update' => false,
			'post_ids' => null,
			'nonce' => '',
			'timestamp' => '',
			'password_digest' => '',
			'change' => '',
			'user_id' => 0,
			'type' => Post::type( 'any' ),
			'status' => Post::status( 'any' ),
			'limit' => 20,
			'offset' => 0,
			'search' => '',
		);
		foreach ( $locals as $varname => $default ) {
			$$varname = isset( $this->handler_vars[$varname] ) ? $this->handler_vars[$varname] : ( isset( $params[$varname] ) ? $params[$varname] : $default );
			$this->theme->{$varname} = $$varname;
		}

		// numbers submitted by HTTP forms are seen as strings
		// but we want the integer value for use in Posts::get,
		// so cast these two values to (int)
		if ( isset( $this->handler_vars['type'] ) ) {
			$type = (int) $this->handler_vars['type'];
		}
		if ( isset( $this->handler_vars['status'] ) ) {
			$status = (int) $this->handler_vars['status'];
		}

		// if we're updating posts, let's do so:
		if ( $do_update && isset( $post_ids ) ) {
			$okay = true;
			if ( empty( $nonce ) || empty( $timestamp ) ||  empty( $password_digest ) ) {
				$okay = false;
			}
			$wsse = Utils::WSSE( $nonce, $timestamp );
			if ( $password_digest != $wsse['digest'] ) {
				$okay = false;
			}
			if ( $okay ) {
				foreach ( $post_ids as $id ) {
					$ids[] = array( 'id' => $id );
				}
				$to_update = Posts::get( array( 'where' => $ids, 'nolimit' => 1 ) );
				foreach ( $to_update as $post ) {
					switch ( $change ) {
						case 'delete':
							if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
								$post->delete();
							}
							break;
						case 'publish':
							if ( ACL::access_check( $post->get_access(), 'edit' ) ) {
								$post->publish();
							}
							break;
						case 'unpublish':
							if ( ACL::access_check( $post->get_access(), 'edit' ) ) {
								$post->status = Post::status( 'draft' );
								$post->update();
							}
							break;
					}
				}
				unset( $this->handler_vars['change'] );
			}
		}

		// we load the WSSE tokens
		// for use in the delete button
		$this->theme->wsse = Utils::WSSE();

		$arguments = array(
			'content_type' => $type,
			'status' => $status,
			'limit' => $limit,
			'offset' => $offset,
			'user_id' => $user_id,
		);

		if ( '' != $search ) {
			$arguments = array_merge( $arguments, Posts::search_to_get( $search ) );
		}
		$this->theme->posts = Posts::get( $arguments );

		// setup keyword in search field if a status or type was passed in POST
		$this->theme->search_args = '';
		if ( $status != Post::status( 'any' ) ) {
			$this->theme->search_args = 'status:' . Post::status_name( $status ) . ' ';
		}
		if ( $type != Post::type( 'any' ) ) {
			$this->theme->search_args .= 'type:' . Post::type_name( $type ) . ' ';
		}
		if ( $user_id != 0 ) {
			$this->theme->search_args .= 'author:' . User::get_by_id( $user_id )->username .' ';
		}
		if ( $search != '' ) {
			$this->theme->search_args .= $search;
		}

		$monthcts = Posts::get( array_merge( $arguments, array( 'month_cts' => true, 'nolimit' => true ) ) );
		$years = array();
		foreach ( $monthcts as $month ) {
			if ( isset( $years[$month->year] ) ) {
				$years[$month->year][] = $month;
			}
			else {
				$years[$month->year] = array( $month );
			}
		}

		$this->theme->years = $years;

	}

	/**
	 * Handles GET requests to /admin/posts.
	 *
	 */
	public function get_posts()
	{
		$this->post_posts();
	}

	/**
	 * Handles POST values from /manage/posts.
	 * Used to control what content to show / manage.
	 */
	public function post_posts()
	{
		$this->fetch_posts();
		// Get special search statuses
		$statuses = array_keys( Post::list_post_statuses() );
		array_shift( $statuses );
		$labels = array_map(
			function($a) {return MultiByte::ucfirst(Plugins::filter("post_status_display", $a));},
			$statuses
		);
		$terms = array_map(
			function($a) {return "status:{$a}";},
			$statuses
		);
		$statuses = array_combine( $terms, $labels );

		// Get special search types
		$types = array_keys( Post::list_active_post_types() );
		array_shift( $types );
		$labels = array_map(
			function($a) {return Plugins::filter("post_type_display", $a, "singular");},
			$types
		);
		$terms = array_map(
			function($a) {return "type:{$a}";},
			$types
		);
		$types = array_combine( $terms, $labels );

		$special_searches = array_merge( $statuses, $types );
		// Add a filter to get the only the user's posts
		$special_searches["author:" . User::identify()->username] = _t( 'My Posts' );

		$this->theme->admin_page = _t( 'Manage Posts' );
		$this->theme->admin_title = _t( 'Manage Posts' );
		$this->theme->special_searches = Plugins::filter( 'special_searches', $special_searches );
		$this->display( 'posts' );
	}

	/**
	 * Handles AJAX requests from media silos.
	 */
	public function ajax_media( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$path = $handler_vars['path'];
		$rpath = $path;
		$silo = Media::get_silo( $rpath, true );  // get_silo sets $rpath by reference to the path inside the silo
		$assets = Media::dir( $path );
		$output = array(
			'ok' => 1,
			'dirs' => array(),
			'files' => array(),
			'path' => $path,
		);
		foreach ( $assets as $asset ) {
			if ( $asset->is_dir ) {
				$output['dirs'][$asset->basename] = $asset->get_props();
			}
			else {
				$output['files'][$asset->basename] = $asset->get_props();
			}
		}
		$rootpath = MultiByte::strpos( $path, '/' ) !== false ? MultiByte::substr( $path, 0, MultiByte::strpos( $path, '/' ) ) : $path;
		$controls = array( 'root' => '' . _t( 'Root' ) . '' );
		$controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, '' );
		$controls_out = '';
		foreach ( $controls as $k => $v ) {
			if ( is_numeric( $k ) ) {
				$controls_out .= "
{$v}
";
			}
			else {
				$controls_out .= "
{$v}
";
			}
		}
		$output['controls'] = $controls_out;

		$ar = new AjaxResponse();
		$ar->data = $output;
		$ar->out();
	}

	/**
	 * Handles AJAX requests from media panels.
	 */
	public function ajax_media_panel( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$path = $handler_vars['path'];
		$panelname = $handler_vars['panel'];
		$rpath = $path;
		$silo = Media::get_silo( $rpath, true );  // get_silo sets $rpath by reference to the path inside the silo

		$panel = '';
		$panel = Plugins::filter( 'media_panels', $panel, $silo, $rpath, $panelname );

		$controls = array();
		$controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, $panelname );
		$controls_out = '';
		foreach ( $controls as $k => $v ) {
			if ( is_numeric( $k ) ) {
				$controls_out .= "
{$v}
";
			}
			else {
				$controls_out .= "
{$v}
";
			}
		}
		$output = array(
			'controls' => $controls_out,
			'panel' => $panel,
		);

		$ar = new AjaxResponse();
		$ar->data = $output;
		$ar->out();
	}

	/**
	 * Handles AJAX upload requests from media panels.
	 */
	public function ajax_media_upload( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$path = $handler_vars['path'];
		$panelname = $handler_vars['panel'];
		$rpath = $path;
		$silo = Media::get_silo( $rpath, true );  // get_silo sets $rpath by reference to the path inside the silo

		$panel = '';
		$panel = Plugins::filter( 'media_panels', $panel, $silo, $rpath, $panelname );

		$controls = array();
		$controls = Plugins::filter( 'media_controls', $controls, $silo, $rpath, $panelname );
		$controls_out = '';
		foreach ( $controls as $k => $v ) {
			if ( is_numeric( $k ) ) {
				$controls_out .= "
{$v}
";
			}
			else {
				$controls_out .= "
{$v}
";
			}
		}
		$output = array(
			'controls' => $controls_out,
			'panel' => $panel,
		);

		$ar = new AjaxResponse();
		$ar->data = $output;
		$ar->out( true ); // See discussion at https://github.com/habari/habari/issues/204
	}

	/**
	 * Handles AJAX requests from the manage posts page.
	 */
	public function ajax_posts()
	{
		Utils::check_request_method( array( 'GET', 'HEAD' ) );

		$this->create_theme();

		$params = $_GET;

		$this->fetch_posts( $params );
		$items = $this->theme->fetch( 'posts_items' );
		$timeline = $this->theme->fetch( 'timeline_items' );

		$item_ids = array();

		foreach ( $this->theme->posts as $post ) {
			if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
				$item_ids['p' . $post->id] = 1;
			}
		}

		$ar = new AjaxResponse();
		$ar->data = array(
			'items' => $items,
			'item_ids' => $item_ids,
			'timeline' => $timeline,
		);
		$ar->out();
	}

	/**
	 * Handles AJAX from /manage/posts.
	 * Used to delete posts.
	 */
	public function ajax_update_posts( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );
		$response = new AjaxResponse();

		$wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
		if ( $handler_vars['digest'] != $wsse['digest'] ) {
			$response->message = _t( 'WSSE authentication failed.' );
			$response->out();
			return;
		}

		$ids = array();
		foreach ( $_POST as $id => $delete ) {
			// skip POST elements which are not post ids
			if ( preg_match( '/^p\d+$/', $id ) && $delete ) {
				$ids[] = (int) substr( $id, 1 );
			}
		}
		if ( count( $ids ) == 0 ) {
			$posts = new Posts();
		}
		else {
			$posts = Posts::get( array( 'id' => $ids, 'nolimit' => true ) );
		}

		Plugins::act( 'admin_update_posts', $handler_vars['action'], $posts, $this );
		$status_msg = _t( 'Unknown action "%s"', array( $handler_vars['action'] ) );
		switch ( $handler_vars['action'] ) {
			case 'delete':
				$deleted = 0;
				foreach ( $posts as $post ) {
					if ( ACL::access_check( $post->get_access(), 'delete' ) ) {
						$post->delete();
						$deleted++;
					}
				}
				if ( $deleted != count( $posts ) ) {
					$response->message = _t( 'You did not have permission to delete some posts.' );
				}
				else {
					$response->message = sprintf( _n( 'Deleted %d post', 'Deleted %d posts', count( $ids ) ), count( $ids ) );
				}
				break;
			default:
				// Specific plugin-supplied action
				Plugins::act( 'admin_posts_action', $response, $handler_vars['action'], $posts );
				break;
		}

		$response->out();
		exit;
	}
}


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminTagsHandler Class
 * Handles tag-related actions in the admin
 *
 */
class AdminTagsHandler extends AdminHandler
{
	/**
	 * Handle GET requests for /admin/tags to display the tags.
	 */
	public function get_tags()
	{
		$this->theme->wsse = Utils::WSSE();

		$this->theme->tags = Tags::vocabulary()->get_tree( 'term_display asc' );
		$this->theme->max = Tags::vocabulary()->max_count();

		$this->display( 'tags' );
	}

	/**
	 * Handles ajax searching from admin/tags
	 * @param type $handler_vars The variables passed to the page by the server
	 * @return AjaxResponse The updated data for the tags page, with any messages
	 */
	public function ajax_get_tags( $handler_vars )
	{
		Utils::check_request_method( array( 'GET', 'HEAD' ) );
		$response = new AjaxResponse();

		$wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
		if ( $handler_vars['digest'] != $wsse['digest'] ) {
			$response->message = _t( 'WSSE authentication failed.' );
			$response->out();
			return;
		}

		$this->create_theme();

		$search = $handler_vars['search'];

		$this->theme->tags = Tags::vocabulary()->get_search( $search, 'term_display asc' );
		$this->theme->max = Tags::vocabulary()->max_count();
		$response->data = $this->theme->fetch( 'tag_collection' );
		$response->out();
	}

	/**
	 * Handles AJAX from /admin/tags
	 * Used to delete and rename tags
	 */
	public function ajax_tags( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );
		$response = new AjaxResponse();

		$wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
		if ( $handler_vars['digest'] != $wsse['digest'] ) {
			$response->message = _t( 'WSSE authentication failed.' );
			$response->out();
			return;
		}

		$tag_names = array();
		$this->create_theme();
		$action = $this->handler_vars['action'];
		switch ( $action ) {
			case 'delete':
				foreach ( $_POST as $id => $delete ) {
					// skip POST elements which are not tag ids
					if ( preg_match( '/^tag_\d+/', $id ) && $delete ) {
						$id = substr( $id, 4 );
						$tag = Tags::get_by_id( $id );
						$tag_names[] = $tag->term_display;
						Tags::vocabulary()->delete_term( $tag );
					}
				}
				$response->message = _n( _t( 'Tag %s has been deleted.', array( implode( '', $tag_names ) ) ), _t( '%d tags have been deleted.', array( count( $tag_names ) ) ), count( $tag_names ) );
				break;

			case 'rename':
				if ( !isset( $this->handler_vars['master'] ) ) {
					$response->message = _t( 'Error: New name not specified.' );
					$response->out();
					return;
				}
				$master = $this->handler_vars['master'];
				$tag_names = array();
				foreach ( $_POST as $id => $rename ) {
					// skip POST elements which are not tag ids
					if ( preg_match( '/^tag_\d+/', $id ) && $rename ) {
						$id = substr( $id, 4 );
						$tag = Tags::get_by_id( $id );
						$tag_names[] = $tag->term_display;
					}
				}
				Tags::vocabulary()->merge( $master, $tag_names );
				$response->message = sprintf(
					_n('Tag %1$s has been renamed to %2$s.',
						'Tags %1$s have been renamed to %2$s.',
							count( $tag_names )
					), implode( $tag_names, ', ' ), $master
				);
				break;

		}
		$this->theme->tags = Tags::vocabulary()->get_tree( 'term_display ASC' );
		$this->theme->max = Tags::vocabulary()->max_count();
		$response->data = $this->theme->fetch( 'tag_collection' );
		$response->out();
	}

}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminThemesHandler Class
 * Handles theme-related actions in the admin
 *
 */
class AdminThemesHandler extends AdminHandler
{
	/**
	 * Handles GET requests for the theme listing
	 */
	public function get_themes()
	{
		$all_themes = Themes::get_all_data();
		$theme_names = Utils::array_map_field($all_themes, 'name');

		$available_updates = Options::get( 'updates_available', array() );

		foreach ( $all_themes as $name => $theme ) {

			// only themes with a guid can be checked for updates
			if ( isset( $theme['info']->guid ) ) {
				if ( isset( $available_updates[ (string)$theme['info']->guid ] ) ) {
					// @todo this doesn't use the URL and is therefore worthless
					$all_themes[ $name ]['info']->update = $available_updates[ (string)$theme['info']->guid ]['latest_version'];
				}
			}

			// If this theme requires a parent to be present and it's not, send an error
			if(isset($theme['info']->parent) && !in_array((string)$theme['info']->parent, $theme_names)) {
				$all_themes[$name]['req_parent'] = $theme['info']->parent;
			}
		}

		$this->theme->all_themes = $all_themes;

		$this->theme->active_theme = Themes::get_active_data( true );
		$this->theme->active_theme_dir = $this->theme->active_theme['path'];

		// If the active theme is configurable, allow it to configure
		$this->theme->active_theme_name = $this->theme->active_theme['info']->name;
		$this->theme->configurable = Plugins::filter( 'theme_config', false, $this->active_theme );
		$this->theme->assign( 'configure', Controller::get_var( 'configure' ) );

		$this->theme->areas = $this->get_areas(0);
		$this->theme->previewed = Themes::get_theme_dir( false );

		$this->theme->help = isset($this->theme->active_theme['info']->help) ? $this->theme->active_theme['info']->help : false;
		$this->theme->help_active = Controller::get_var('help') == $this->theme->active_theme['dir'];

		$this->prepare_block_list();

		$blocks_areas_t = DB::get_results( 'SELECT b.*, ba.scope_id, ba.area, ba.display_order FROM {blocks} b INNER JOIN {blocks_areas} ba ON ba.block_id = b.id ORDER BY ba.scope_id ASC, ba.area ASC, ba.display_order ASC', array() );
		$blocks_areas = array();
		foreach ( $blocks_areas_t as $block ) {
			if ( !isset( $blocks_areas[$block->scope_id] ) ) {
				$blocks_areas[$block->scope_id] = array();
			}
			$blocks_areas[$block->scope_id][$block->area][$block->display_order] = $block;
		}
		$this->theme->blocks_areas = $blocks_areas;

		$scopes = DB::get_results( 'SELECT * FROM {scopes} ORDER BY name ASC;' );
		$scopes = Plugins::filter( 'get_scopes', $scopes );
		$this->theme->scopes = $scopes;
		$this->theme->scopeid = 0;

		$this->theme->theme_loader = Plugins::filter( 'theme_loader', '', $this->theme );

		$this->theme->display( 'themes' );
	}

	/**
	 * A POST handler for the admin themes page that simply passes those options through.
	 */
	public function post_themes()
	{
		return $this->get_themes();
	}

	/**
	 * Activates a theme.
	 */
	public function get_activate_theme()
	{
		$theme_name = $this->handler_vars['theme_name'];
		$theme_dir = $this->handler_vars['theme_dir'];
		$activated = false;
		if ( isset( $theme_name ) && isset( $theme_dir ) ) {
			$activated = Themes::activate_theme( $theme_name, $theme_dir );
		}
		if($activated) {
			Session::notice( _t( "Activated theme '%s'", array( $theme_name ) ) );
		}
		Utils::redirect( URL::get( 'admin', 'page=themes' ) );
	}

	/**
	 * Configures a theme to be active for the current user's session.
	 */
	public function get_preview_theme()
	{
		$theme_name = $this->handler_vars['theme_name'];
		$theme_dir = $this->handler_vars['theme_dir'];
		if ( isset( $theme_name )  && isset( $theme_dir ) ) {
			if ( Themes::get_theme_dir() == $theme_dir ) {
				Themes::cancel_preview();
				Session::notice( _t( "Ended the preview of the theme '%s'", array( $theme_name ) ) );
			}
			else {
				if(Themes::preview_theme( $theme_name, $theme_dir )) {
					Session::notice( _t( "Previewing theme '%s'", array( $theme_name ) ) );
				}
			}
		}
		Utils::redirect( URL::get( 'admin', 'page=themes' ) );
	}

	/**
	 * Get the block configuration form to show in a modal iframe on the themes page
	 *
	 */
	public function get_configure_block()
	{
		Utils::check_request_method( array( 'GET', 'POST' ) );

		$block = DB::get_row( 'SELECT b.* FROM {blocks} b WHERE id = :id ORDER BY b.title ASC', array( 'id' => $_GET['blockid'] ), 'Block' );
		$block_form = $block->get_form();
		$block_form->set_option( 'success_message', '

' . _t( 'Saved block configuration.' ) . '

');

		$first_control = reset ( $block_form->controls );
		if ( $first_control ) {
			$block_form->insert( $first_control->name, 'fieldset', 'block_admin', _t( 'Block Display Settings' ) );
		}
		else {
			$block_form->append( 'fieldset', 'block_admin', _t( 'Block Display Settings' ) );
		}

		$block_form->block_admin->append( 'text', '_title', array( 'configure_block_title', $block ), _t( 'Block Title:' ) );
		$block_form->_title->value = $block->title;
		$block_form->_title->add_validator( 'validate_required' );
		$block_form->block_admin->append( 'checkbox', '_show_title', $block, _t( 'Display Block Title:' ) );
		$block_form->append( 'submit', 'save', _t( 'Save' ) );

		Plugins::register( array( $this, 'action_configure_block_title' ), 'action', 'configure_block_title' );

		$this->theme->content = $block_form->get();

		$this->display( 'block_configure' );
	}

	function action_configure_block_title( $value, $name, $storage )
	{
		$storage[0]->title = $value;
		return false;
	}

	/**
	 * A POST handler for the block configuration form
	 *
	 * @see AdminHandler::get_configure_block
	 * @return
	 */
	public function post_configure_block()
	{
		$this->get_configure_block();
	}

	/**
	 * Called from the themes page to create a new block instace
	 *
	 * @param mixed $handler_vars
	 */
	public function ajax_add_block( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$this->setup_admin_theme( '' );

		$title = $_POST['title'];
		$type = $_POST['type'];

		if ( !isset( $_POST['title'] ) ) {
			$this->theme->blocks = Plugins::filter( 'block_list', array() );
			$this->theme->block_instances = DB::get_results( 'SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block' );
			$this->theme->active_theme = Themes::get_active_data( true );

			$this->display( 'block_instances' );
		}
		elseif ( $title == '' ) {
			$this->theme->blocks = Plugins::filter( 'block_list', array() );
			$this->theme->block_instances = DB::get_results( 'SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block' );
			$this->theme->active_theme = Themes::get_active_data( true );

			$this->display( 'block_instances' );

			$msg = json_encode( _t( 'A new block must first have a name.' ) );

			echo '';
		}
		else {
			$block = new Block( array( 'title' => $title, 'type' => $type ) );
			$block->insert();

			$this->prepare_block_list();
			$this->theme->active_theme = Themes::get_active_data( true );

			$this->display( 'block_instances' );

			$msg = json_encode( _t( 'Added new block "%1s" of type "%2s".', array( $title, $type ) ) );

			echo '';
		}
	}

	/**
	 * Called from the themes page to delete a block instance
	 *
	 * @param mixed $handler_vars
	 */
	public function ajax_delete_block( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$this->setup_admin_theme( '' );

		$block_id = $_POST['block_id'];
		$block = DB::get_row( 'SELECT b.* FROM {blocks} b WHERE id = :block_id', array( 'block_id' => $block_id ), 'Block' );
		if ( $block->delete() ) {
			$msg = json_encode( _t( 'Deleted block "%1s" of type "%2s".', array( $block->title, $block->type ) ) );
		}
		else {
			$msg = json_encode( _t( 'Failed to delete block "%1s" of type "%2s".', array( $block->title, $block->type ) ) );
		}

		$this->prepare_block_list();

		$this->theme->active_theme = Themes::get_active_data( true );

		$this->display( 'block_instances' );

		echo '';
	}

	/**
	 * Called from the themes page to save the blocks instances into areas
	 *
	 * @param mixed $handler_vars
	 * @return
	 */
	public function ajax_save_areas( $handler_vars )
	{
		Utils::check_request_method( array( 'POST' ) );

		$scope = $_POST['scope'];

		$msg = '';

		$response = new AjaxResponse();
		if ( isset( $_POST['area_blocks'] ) ) {
			$area_blocks = $_POST['area_blocks'];
			DB::query( 'DELETE FROM {blocks_areas} WHERE scope_id = :scope_id', array( 'scope_id' => $scope ) );

			foreach ( (array)$area_blocks as $area => $blocks ) {
				$display_order = 0;

				// if there are no blocks for a given area, skip it
				if ( empty( $blocks ) ) {
					continue;
				}

				foreach ( $blocks as $block ) {
					$display_order++;
					DB::query( 'INSERT INTO {blocks_areas} (block_id, area, scope_id, display_order) VALUES (:block_id, :area, :scope_id, :display_order)', array( 'block_id'=>$block, 'area'=>$area, 'scope_id'=>$scope, 'display_order'=>$display_order ) );
				}
			}

//			$msg = json_encode( _t( 'Saved block areas settings.' ) );
//			$msg = '';
			$response->message = _t( 'Saved block areas settings.' );
		}

		$this->setup_admin_theme( '' );

		$blocks_areas_t = DB::get_results( 'SELECT b.*, ba.scope_id, ba.area, ba.display_order FROM {blocks} b INNER JOIN {blocks_areas} ba ON ba.block_id = b.id ORDER BY ba.scope_id ASC, ba.area ASC, ba.display_order ASC', array() );
		$blocks_areas = array();
		foreach ( $blocks_areas_t as $block ) {
			if ( !isset( $blocks_areas[$block->scope_id] ) ) {
				$blocks_areas[$block->scope_id] = array();
			}
			$blocks_areas[$block->scope_id][$block->area][$block->display_order] = $block;
		}
		$this->theme->blocks_areas = $blocks_areas;
		$this->theme->scopeid = $scope;
		$this->theme->areas = $this->get_areas($scope);
		$scopes = DB::get_results( 'SELECT * FROM {scopes} ORDER BY name ASC;' );
		$scopes = Plugins::filter( 'get_scopes', $scopes );
		$this->theme->scopes = $scopes;
		$this->theme->active_theme = Themes::get_active_data( true );

		$output = $this->theme->fetch( 'block_areas' );
		$response->html('block_areas', $output);

		$response->out();
	}

	function get_areas($scope) {
		$activedata = Themes::get_active_data( true );
		$areas = array();
		if ( isset( $activedata['info']->areas->area ) ) {
			foreach ( $activedata['info']->areas->area as $area ) {
				$areas[(string)$area['name']] = (string)$area->description;
			}
		}
		$areas = Plugins::filter('areas', $areas, $scope);
		return $areas;
	}

	/**
	 * Load the block types and block instances into the appropriate structures for the theme to output
	 */
	function prepare_block_list() {
		$block_types = Plugins::filter( 'block_list', array() );
		$dash_blocks = Plugins::filter( 'dashboard_block_list', array() );
		$block_types = array_diff_key($block_types, $dash_blocks);
		$all_block_instances = DB::get_results( 'SELECT b.* FROM {blocks} b ORDER BY b.title ASC', array(), 'Block' );
		$block_instances = array();
		$invalid_block_instances = array();
		foreach($all_block_instances as $instance) {
			if(isset($block_types[$instance->type])) {
				$block_instances[] = $instance;
			}
			else {
				$instance->invalid_message = _t('This data is for a block of type "%s", which is no longer provided by a theme or plugin.', array($instance->type));
				$invalid_block_instances[] = $instance;
			}
		}
		$this->theme->blocks = $block_types;
		$this->theme->block_instances = $block_instances;
		$this->theme->invalid_block_instances = $invalid_block_instances;
	}
}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Habari AdminUsersHandler Class
 * Handles user-related actions in the admin
 *
 */
class AdminUsersHandler extends AdminHandler
{
	/**
	 * Handles GET requests of a user page.
	 */
	public function get_user()
	{
		$edit_user = User::identify();
		$permission = false;

		// Check if the user is editing their own profile
		$self = $this->handler_vars['user'] == '' || User::get_by_name($this->handler_vars['user']) == $edit_user;
		if ($self) {
			if ( $edit_user->can( 'manage_self' ) || $edit_user->can( 'manage_users' ) ) {
				$permission = true;
			}
			$who = _t( "You" );
			$possessive = _t( "Your User Information" );
		}
		else {
			if ( $edit_user->can( 'manage_users' ) ) {
				$permission = true;
			}
			$edit_user = User::get_by_name( $this->handler_vars['user'] );
			$who = $edit_user->username;
			$possessive = _t( "%s's User Information", array( $who ) );
		}

		if ( !$permission ) {
			Session::error( _t( 'Access to that page has been denied by the administrator.' ) );
			$this->get_blank();
			return;
		}

		// Get author list
		$author_list = Users::get_all();
		$authors[0] = _t( 'nobody' );
		foreach ( $author_list as $author ) {
			$authors[ $author->id ] = $author->displayname;
		}

		unset( $authors[ $edit_user->id ] ); // We can't reassign posts to ourself

		$this->theme->authors = $authors;
		$this->theme->edit_user = $edit_user;
		$this->theme->who = $who;
		$this->theme->possessive = $possessive;

		// Redirect to the users management page if we're trying to edit a non-existent user
		if ( !$edit_user ) {
			Session::error( _t( 'No such user!' ) );
			Utils::redirect( URL::get( 'admin', 'page=users' ) );
		}

		$this->theme->edit_user = $edit_user;

		$field_sections = array(
			'user_info' => $possessive,
			'change_password' => _t( 'Change Password' ),
			'regional_settings' => _t( 'Regional Settings' ),
			'dashboard' => _t( 'Dashboard' ),
		);

			$form = new FormUI( 'User Options' );

		// Create a tracker for who we are dealing with
		$form->append( 'hidden', 'edit_user', 'edit_user' );
		$form->edit_user->value = $edit_user->id;

		// Generate sections
		foreach ( $field_sections as $key => $name ) {
			$fieldset = $form->append( 'wrapper', $key, $name );
			$fieldset->class = 'container settings';
			$fieldset->append( 'static', $key, '
' . htmlentities( $name, ENT_COMPAT, 'UTF-8' ) . '
' );
		}

		// User Info
		$displayname = $form->user_info->append( 'text', 'displayname', 'null:null', _t( 'Display Name' ), 'optionscontrol_text' );
		$displayname->class[] = 'important item clear';
		$displayname->value = $edit_user->displayname;

		$username = $form->user_info->append( 'text', 'username', 'null:null', _t( 'User Name' ), 'optionscontrol_text' );
		$username->class[] = 'item clear';
		$username->value = $edit_user->username;
		$username->add_validator( 'validate_username', $edit_user->username );

		$email = $form->user_info->append( 'text', 'email', 'null:null', _t( 'Email' ), 'optionscontrol_text' );
		$email->class[] = 'item clear';
		$email->value = $edit_user->email;
		$email->add_validator( 'validate_email' );

		$imageurl = $form->user_info->append( 'text', 'imageurl', 'null:null', _t( 'Portrait URL' ), 'optionscontrol_text' );
		$imageurl->class[] = 'item clear';
		$imageurl->value = $edit_user->info->imageurl;

		// Change Password
		$password1 = $form->change_password->append( 'text', 'password1', 'null:null', _t( 'New Password' ), 'optionscontrol_text' );
		$password1->class[] = 'item clear';
		$password1->type = 'password';
		$password1->value = '';
		$password1->autocomplete = 'off';

		$password2 = $form->change_password->append( 'text', 'password2', 'null:null', _t( 'New Password Again' ), 'optionscontrol_text' );
		$password2->class[] = 'item clear';
		$password2->type = 'password';
		$password2->value = '';
		$password2->autocomplete = 'off';

		$delete = $this->handler_vars->filter_keys( 'delete' );
		// don't validate password match if action is delete
		if ( !isset( $delete['delete'] ) ) {
			$password2->add_validator( 'validate_same', $password1, _t( 'Passwords must match.' ) );
		}

		// Regional settings
		$timezones = DateTimeZone::listIdentifiers();
		$timezones = array_merge( array_combine( array_values( $timezones ), array_values( $timezones ) ) );
		$locale_tz = $form->regional_settings->append( 'select', 'locale_tz', 'null:null', _t( 'Timezone' ) );
		$locale_tz->class[] = 'item clear';
		$locale_tz->value = $edit_user->info->locale_tz;
		$locale_tz->options = $timezones;
		$locale_tz->multiple = false;
		$locale_tz->template = 'optionscontrol_select';

		$locale_date_format = $form->regional_settings->append( 'text', 'locale_date_format', 'null:null', _t( 'Date Format' ), 'optionscontrol_text' );
		$locale_date_format->class[] = 'item clear';
		$locale_date_format->value = $edit_user->info->locale_date_format;
		if ( isset( $edit_user->info->locale_date_format ) && $edit_user->info->locale_date_format != '' ) {
			$current = HabariDateTime::date_create()->get( $edit_user->info->locale_date_format );
		}
		else {
			$current = HabariDateTime::date_create()->date;
		}
		$locale_date_format->helptext = _t( 'See php.net/date for details. Current format: %s', array( 'http://php.net/date', $current ) );

		$locale_time_format = $form->regional_settings->append( 'text', 'locale_time_format', 'null:null', _t( 'Time Format' ), 'optionscontrol_text' );
		$locale_time_format->class[] = 'item clear';
		$locale_time_format->value = $edit_user->info->locale_time_format;
		if ( isset( $edit_user->info->locale_time_format ) && $edit_user->info->locale_time_format != '' ) {
			$current = HabariDateTime::date_create()->get( $edit_user->info->locale_time_format );
		}
		else {
			$current = HabariDateTime::date_create()->time;
		}
		$locale_time_format->helptext = _t( 'See php.net/date for details. Current format: %s', array( 'http://php.net/date', $current ) );

		$spam_count = $form->dashboard->append( 'checkbox', 'dashboard_hide_spam_count', 'null:null', _t( 'Hide Spam Count' ), 'optionscontrol_checkbox' );
		$spam_count->class[] = 'item clear';
		$spam_count->helptext = _t( 'Hide the number of SPAM comments on your dashboard.' );
		$spam_count->value = $edit_user->info->dashboard_hide_spam_count;

		// Groups
		if(User::identify()->can('manage_groups')) {
			$fieldset = $form->append( 'wrapper', 'groups', _t('Groups'));
			$fieldset->class = 'container settings';
			$fieldset->append( 'static', 'groups', '
' . htmlentities( _t('Groups'), ENT_COMPAT, 'UTF-8' ) . '
' );
			$form->groups->append( 'checkboxes', 'user_group_membership', 'null:null', _t('Groups'), Utils::array_map_field(UserGroups::get_all(), 'name', 'id') );
			$form->user_group_membership->value = $edit_user->groups;
		}

		// Controls
		$controls = $form->append( 'wrapper', 'page_controls' );
		$controls->class = 'container controls transparent';

		$submit = $controls->append( 'submit', 'apply', _t( 'Apply' ), 'optionscontrol_submit' );
		$submit->class[] = 'pct30';

		$controls->append( 'static', 'reassign', '' . _t( 'Reassign posts to: %s', array( Utils::html_select( 'reassign', $authors ) ) ) . '' . _t( 'and' ) . '<input type="submit" name="delete" value="' . _t( 'Delete' ) . '" class="delete button">' );

		$form->on_success( array( $this, 'form_user_success' ) );

		// Let plugins alter this form
		Plugins::act( 'form_user', $form, $edit_user );

		$this->theme->form = $form->get();
		$this->theme->admin_page = $self ? _t( 'My Profile') : _t( 'User' );

		$this->theme->display( 'user' );

	}

	/**
	 * Handles form submission from a user's page.
	 */
	public function form_user_success( $form )
	{
		$edit_user = User::get_by_id( $form->edit_user->value );
		$current_user = User::identify();

		// Let's check for deletion
		if ( Controller::get_var( 'delete' ) != null ) {
			if ( $current_user->id != $edit_user->id ) {

				// We're going to delete the user before we need it, so store the username
				$username = $edit_user->username;

				$posts = Posts::get( array( 'user_id' => $edit_user->id, 'nolimit' => true ) );

				if ( ( Controller::get_var( 'reassign' ) != null ) && ( Controller::get_var( 'reassign' ) != 0 ) && ( Controller::get_var( 'reassign' ) != $edit_user->id ) ) {
					// we're going to re-assign all of this user's posts
					$newauthor = Controller::get_var( 'reassign' );
					Posts::reassign( $newauthor, $posts );
					$edit_user->delete();
				}
				else {
					// delete user, then delete posts
					$edit_user->delete();

					// delete posts
					foreach ( $posts as $post ) {
						$post->delete();
					}
				}

				Session::notice( _t( '%s has been deleted', array( $username ) ) );

				Utils::redirect( URL::get( 'admin', array( 'page' => 'users' ) ) );
			}
			else {
				Session::notice( _t( 'You cannot delete yourself.' ) );
			}
		}

		$update = false;

		// Change username
		if ( isset( $form->username ) && $edit_user->username != $form->username->value ) {
			Session::notice( _t( '%1$s has been renamed to %2$s.', array( $edit_user->username, $form->username->value ) ) );
			$edit_user->username = $form->username->value;
			$update = true;
		}

		// Change email
		if ( isset( $form->email ) && $edit_user->email != $form->email->value ) {
			$edit_user->email = $form->email->value;
			$update = true;
		}

		// Change password
		if ( isset( $form->password1 ) && !( Utils::crypt( $form->password1->value, $edit_user->password ) ) && ( $form->password1->value != '' ) ) {
			Session::notice( _t( 'Password changed.' ) );
			$edit_user->password = Utils::crypt( $form->password1->value );
			$edit_user->update();
		}

		// Change group membership
		if(User::identify()->can('manage_groups')) {
			$allgroups = UserGroups::get_all();
			$new_groups = $form->user_group_membership->value;
			foreach($allgroups as $group) {
				if(!$edit_user->in_group($group) && in_array($group->id, $new_groups)) {
					$edit_user->add_to_group($group);
				}
				if($edit_user->in_group($group) && !in_array($group->id, $new_groups)) {
					$edit_user->remove_from_group($group);
				}
			}
		}

		// Set various info fields
		$info_fields = array( 'displayname', 'imageurl', 'locale_tz', 'locale_date_format', 'locale_time_format', 'dashboard_hide_spam_count' );

		// let plugins easily specify other user info fields to pick
		$info_fields = Plugins::filter( 'adminhandler_post_user_fields', $info_fields );

		foreach ( $info_fields as $info_field ) {
			if ( isset( $form->{$info_field} ) && ( $edit_user->info->{$info_field} != $form->{$info_field}->value ) ) {
				$edit_user->info->{$info_field} = $form->$info_field->value;
				$update = true;
			}
		}

		// Let plugins tell us to update
		$update = Plugins::filter( 'form_user_update', $update, $form, $edit_user );
		$form->save();

		if ( $update ) {
			$edit_user->update();
			Session::notice( _t( 'User updated.' ) );
		}

		Utils::redirect( URL::get( 'admin', array( 'page' => 'user', 'user' => $edit_user->username ) ) );
	}

	/**
	 * Handles POST requests from the user profile page.
	 */
	public function post_user()
	{
		$this->get_user();
	}

	/**
	 * Update an array of POSTed users.
	 */
	public function update_users( $handler_vars )
	{
		if ( isset( $handler_vars['delete'] ) ) {

			$currentuser = User::identify();

			$wsse = Utils::WSSE( $handler_vars['nonce'], $handler_vars['timestamp'] );
			if ( isset( $handler_vars['digest'] ) && $handler_vars['digest'] != $wsse['digest'] ) {
				Session::error( _t( 'WSSE authentication failed.' ) );
				return Session::messages_get( true, 'array' );
			}

			foreach ( $_POST as $id => $delete ) {

				// skip POST elements which are not user ids
				if ( preg_match( '/^p\d+$/', $id ) && $delete ) {
					$id = (int) substr( $id, 1 );

					$ids[] = array( 'id' => $id );

				}

			}

			if ( isset( $handler_vars['checkbox_ids'] ) ) {
				$checkbox_ids = $handler_vars['checkbox_ids'];
				foreach ( $checkbox_ids as $id => $delete ) {
					if ( $delete ) {
						$ids[] = array( 'id' => $id );
					}
				}
			}

			$count = 0;

			if ( ! isset( $ids ) ) {
				Session::notice( _t( 'No users deleted.' ) );
				return Session::messages_get( true, 'array' );
			}

			foreach ( $ids as $id ) {
				$id = $id['id'];
				$user = User::get_by_id( $id );

				if ( $currentuser != $user ) {
					$assign = intval( $handler_vars['reassign'] );

					if ( $user->id == $assign ) {
						return;
					}

					$posts = Posts::get( array( 'user_id' => $user->id, 'nolimit' => 1) );

					$user->delete();

					if ( isset( $posts[0] ) ) {
						if ( 0 == $assign ) {
							foreach ( $posts as $post ) {
								$post->delete();
							}
						}
						else {
							Posts::reassign( $assign, $posts );
						}
					}
				}
				else {
					$msg_status = _t( 'You cannot delete yourself.' );
				}

				$count++;
			}

			if ( !isset( $msg_status ) ) {
				$msg_status = _t( 'Deleted %d users.', array( $count ) );
			}

			Session::notice( $msg_status );
		}
	}

	/**
	 * Assign values needed to display the users listing
	 *
	 */
	private function fetch_users( $params = null )
	{
		// prepare the WSSE tokens
		$this->theme->wsse = Utils::WSSE();

		// Get author list
		$author_list = Users::get_all();
		$authors[0] = _t( 'nobody' );
		foreach ( $author_list as $author ) {
			$authors[ $author->id ] = $author->displayname;
		}
		$this->theme->authors = $authors;
	}

	/**
	 * Handles GET requests of the users page.
	 */
	public function get_users()
	{
		$this->fetch_users();

		$this->theme->display( 'users' );
	}

	/**
	 * Handles POST requests from the Users listing (ie: creating a new user)
	 */
	public function post_users()
	{
		$wsse = Utils::WSSE( $this->handler_vars['nonce'], $this->handler_vars['timestamp'] );
		if ( $this->handler_vars['password_digest'] != $wsse['digest'] ) {
			Session::error( _t( 'WSSE authentication failed.' ) );
			return Session::messages_get( true, 'array' );
		}

		$this->fetch_users();

		$extract = $this->handler_vars->filter_keys( 'newuser', 'delete', 'new_pass1', 'new_pass2', 'new_email', 'new_username' );
		foreach ( $extract as $key => $value ) {
			$$key = $value;
		}

		if ( isset( $newuser ) ) {
			$action = 'newuser';
		}
		elseif ( isset( $delete ) ) {
			$action = 'delete';
		}

		$error = '';
		if ( isset( $action ) && ( 'newuser' == $action ) ) {
			if ( !isset( $new_pass1 ) || !isset( $new_pass2 ) || empty( $new_pass1 ) || empty( $new_pass2 ) ) {
				Session::error( _t( 'Password is required.' ), 'adduser' );
			}
			else if ( $new_pass1 !== $new_pass2 ) {
				Session::error( _t( 'Password mis-match.' ), 'adduser' );
			}
			if ( !isset( $new_email ) || empty( $new_email ) || ( !strstr( $new_email, '@' ) ) ) {
				Session::error( _t( 'Please supply a valid email address.' ), 'adduser' );
			}
			if ( !isset( $new_username ) || empty( $new_username ) ) {
				Session::error( _t( 'Please supply a user name.' ), 'adduser' );
			}
			// safety check to make sure no such username exists
			$user = User::get_by_name( $new_username );
			if ( isset( $user->id ) ) {
				Session::error( _t( 'That username is already assigned.' ), 'adduser' );
			}
			if ( !Session::has_errors( 'adduser' ) ) {
				$user = new User( array( 'username' => $new_username, 'email' => $new_email, 'password' => Utils::crypt( $new_pass1 ) ) );
				if ( $user->insert() ) {
					Session::notice( _t( "Added user '%s'", array( $new_username ) ) );
				}
				else {
					$dberror = DB::get_last_error();
					Session::error( $dberror[2], 'adduser' );
				}
			}
			else {
				$settings = array();
				if ( isset( $new_username ) ) {
					$settings['new_username'] = $new_username;
				}
				if ( isset( $new_email ) ) {
					$settings['new_email'] = $new_email;
				}
				$this->theme->assign( 'settings', $settings );
			}
		}
		else if ( isset( $action ) && ( 'delete' == $action ) ) {

			$this->update_users( $this->handler_vars );

		}

		$this->theme->display( 'users' );
	}

}
?>


code:
<?php
/**
 * @package Habari
 *
 */

/**
 * Handles Ajax requests, sending them to plugin sinks.
 *
 */
class AjaxHandler extends ActionHandler
{

	/**
	 * Handles incoming ajax requests for which the user need not be authenticated.
	 * Forwards the request to plugin actions for the "context" portion of the URL.
	 * The following example would set the context of 'foo' and trigger
	 * the plugin action 'ajax_foo'.
	 *
	 * URL::get( 'ajax', 'context=foo' );
	 *
	 */
	public function act_ajax()
	{
		/**
		 * Triggers the ajax plugin action for the context.
		 *
		 * @see AjaxHandler::act_ajax()
		 * @action ajax_{$context}
		 */
		Plugins::act( 'ajax_' . $this->handler_vars['context'], $this );
	}

	/**
	 * Handles incoming ajax requests for which the user must be authenticated.
	 * Forwards the request to plugin actions for the "context" portion of the URL.
	 *
	 * @see act_ajax()
	 */
	public function act_auth_ajax()
	{
		$user = User::identify();
		if ( $user->loggedin ) {
			/**
			 * Triggers the ajax plugin action for the context if user is authenticated.
			 *
			 * @see act_auth_ajax()
			 * @action ajax_auth_{$context}
			 */
			Plugins::act( 'auth_ajax_' . $this->handler_vars['context'], $this );
			exit;
		}
	}

}

?>