function index()
    {
        OutputModes(array('xhtml', 'fbml'));
        if (!CheckPermissions('public')) {
            return;
        }
        //poll handling
        $poll_id = $this->polls_model->GetDisplayedPoll();
        $user_voted = $this->polls_model->HasUserVoted($poll_id, $this->user_auth->entityId);
        $poll_show_results = false;
        if ($poll_id && !$user_voted) {
            if (isset($_POST['submit_vote'])) {
                if ($this->input->post('poll_vote')) {
                    if ($this->polls_model->IsChoicePartOfPoll($poll_id, $this->input->post('poll_vote'))) {
                        $this->polls_model->SetUserPollVote($poll_id, $this->user_auth->entityId, $this->input->post('poll_vote'));
                        $this->messages->AddMessage('success', 'Your vote has been cast.');
                        $user_voted = true;
                    } else {
                        $this->messages->AddMessage('error', 'Invalid option.');
                    }
                }
            } elseif (isset($_POST['submit_results'])) {
                $poll_show_results = true;
            }
        } else {
            $poll_show_results = true;
        }
        if ('fbml' === OutputMode()) {
            return $this->_FacebookHome();
        }
        $this->pages_model->SetPageCode('home_main');
        $this->load->library('image');
        //Various arrays defined
        $data = array();
        //Stores all data to be passed to view
        $res = array();
        $data['welcome_title'] = $this->pages_model->GetPropertyText('welcome_title');
        $data['welcome_text'] = $this->pages_model->GetPropertyWikitext('welcome_text');
        $data['articles'] = array('uninews' => array(), 'sport' => array(), 'features' => array(), 'arts' => array(), 'videocasts' => array(), 'lifestyle' => array(), 'blogs' => array());
        // Get the article ids of all articles to be displayed
        $article_all_ids = $this->Home_Hack_Model->getLatestArticleIds(array('uninews' => 3, 'sport' => 3, 'features' => 1, 'arts' => 1, 'videocasts' => 1, 'lifestyle' => 1, 'blogs' => 1));
        //$this->messages->AddDumpMessage('ids',$article_all_ids);
        // Create an array to map an article id to an article type
        $article_base_types = array();
        foreach ($article_all_ids as $type => $ids) {
            foreach ($ids as $id) {
                $article_base_types[$id] = $type;
            }
        }
        // Get the ids of articles which require summaries
        $article_summary_ids = array();
        if (count($article_all_ids['uninews']) > 0) {
            $article_summary_ids[] = $article_all_ids['uninews'][0];
        }
        if (count($article_all_ids['sport']) > 0) {
            $article_summary_ids[] = $article_all_ids['sport'][0];
        }
        if (count($article_all_ids['features']) > 0) {
            $article_summary_ids[] = $article_all_ids['features'][0];
        }
        if (count($article_all_ids['arts']) > 0) {
            $article_summary_ids[] = $article_all_ids['arts'][0];
        }
        if (count($article_all_ids['videocasts']) > 0) {
            $article_summary_ids[] = $article_all_ids['videocasts'][0];
        }
        // Get the article summaries, create html for image tags
        $article_summaries = $this->Home_Hack_Model->getArticleSummaries($article_summary_ids, '%W, %D %M %Y');
        foreach ($article_summaries as $summary) {
            $type = $article_base_types[$summary['id']];
            $summary['photo_xhtml'] = $this->image->getThumb($summary['photo_id'], 'medium', false, array('class' => 'left'));
            $data['articles'][$type][] = $summary;
        }
        // Get the ids of articles which require titles
        $article_title_ids = array();
        foreach ($article_all_ids as $type => $ids) {
            foreach ($ids as $id) {
                if (!in_array($id, $article_summary_ids)) {
                    $article_title_ids[] = $id;
                }
            }
        }
        // Get the article titles
        $article_titles = $this->Home_Hack_Model->getArticleTitles($article_title_ids);
        foreach ($article_titles as $title) {
            $type = $article_base_types[$title['id']];
            $title['photo_xhtml'] = $this->image->getThumb($title['photo_id'], 'small', false, array('class' => 'left'));
            $data['articles'][$type][] = $title;
        }
        // Get latest comments made on articles
        $this->load->library('comment_views');
        $data['latest_comments'] = $this->comment_views->GetLatestComments();
        //Obtain Links
        if ($this->user_auth->isLoggedIn) {
            $data['link'] = $this->Links_Model->GetUserLinks($this->user_auth->entityId);
        } else {
            $data['link'] = $this->Links_Model->GetUserLinks(0);
        }
        //Obtain weather
        $data['weather_forecast'] = $this->Home_Model->GetWeather();
        //Obtain quote
        $data['quote'] = $this->Home_Model->GetQuote();
        //Obtain banner
        $data['banner'] = $this->Home_Model->GetBannerImageForHomepage();
        //Obtain specials
        //list here the specials to get, along with their title
        $specials = array(array('lifestyle', 'Latest Lifestyle'), array('blogs', 'Latest Blog'));
        //foreach type given setup the data, assumes [0] is has a small image and heading
        foreach ($specials as $special) {
            $data['special'][$special[0]]['title'] = $special[1];
            if (isset($data['articles'][$special[0]][0])) {
                $data['special'][$special[0]]['show'] = true;
                $data['special'][$special[0]]['data'] = $data['articles'][$special[0]][0];
            } else {
                $data['special'][$special[0]]['show'] = false;
            }
        }
        /* this is the old method, getting articles set using specials
        		$specials_types = $this->Article_Model->getMainArticleTypes();
        		foreach ($specials_types as $special){
        			$special_id = $this->News_model->GetLatestFeaturedId($special['codename']);
        			$data['special'][$special['codename']]['title'] = $special['name'];
        			if(!empty($special_id)) {
        				$data['special'][$special['codename']]['show'] = true;
        				$data['special'][$special['codename']]['data'] = $this->News_model->GetSummaryArticle($special_id);
        			}
        			else {
        				$data['special'][$special['codename']]['show'] = false;
        			}
        		}*/
        // Minifeeds
        list($data['events'], $data['todo']) = $this->_GetMiniCalendars();
        // Poll data
        if ($poll_id) {
            $data['poll_vote_box'] = new PollsVoteBox($this->polls_model->GetPollDetails($poll_id), $this->polls_model->GetPollChoiceVotes($poll_id), $user_voted, $poll_show_results);
        } else {
            $data['poll_vote_box'] = null;
        }
        /**
         *	@brief	TEMPORARY HACKED FOR ROSES 2008
         *	@todo	Remove after Roses and incorporate ideas into new flexi-box homepage
         *	@author	Chris Travis (cdt502 - ctravis@gmail.com)
         *	@date	27th April 2008
         */
        $r8s_sql = 'SELECT		photo_tags.photo_tag_photo_id
					FROM		tags,
								photo_tags,
								photos
					WHERE		tags.tag_name = \'roses\'
					AND			tags.tag_type = \'photo\'
					AND			tags.tag_deleted = 0
					AND			tags.tag_id = photo_tags.photo_tag_tag_id
					AND			photo_tags.photo_tag_photo_id = photos.photo_id
					ORDER BY	photos.photo_timestamp DESC
					LIMIT		0, 5';
        $r8s_query = $this->db->query($r8s_sql);
        $data['roses_slideshow'] = array();
        foreach ($r8s_query->result_array() as $r8s_photo) {
            $data['roses_slideshow'][] = array('id' => $r8s_photo['photo_tag_photo_id'], 'xhtml' => $this->image->getThumb($r8s_photo['photo_tag_photo_id'], 'small', false));
        }
        /* END TEMPORARY CODE */
        // Set up the public frame
        $this->main_frame->SetContentSimple('general/home2', $data);
        $this->main_frame->IncludeCss('stylesheets/home.css');
        $this->main_frame->IncludeJs('javascript/prototype.js');
        $this->main_frame->IncludeJs('javascript/scriptaculous.js?load=effects,dragdrop');
        // Load the public frame view (which will load the content view)
        $this->main_frame->Load();
    }
 /** Crosswords management.
  */
 function crossword($crossword = null, $operation = null)
 {
     if ('save' === $operation) {
         OutputModes('ajax');
     }
     if (!CheckPermissions('office')) {
         return;
     }
     if (null !== $crossword && is_numeric($crossword)) {
         $crossword = (int) $crossword;
         $crosswords = $this->crosswords_model->GetCrosswords($crossword);
         if (count($crosswords) === 0) {
             show_404();
         }
         $crossword_info = $crosswords[0];
         $this->load->model('permissions_model');
         $data = array('Permissions' => array('modify' => $this->permissions_model->hasUserPermission('CROSSWORD_MODIFY'), 'stats_basic' => $this->permissions_model->hasUserPermission('CROSSWORD_STATS_BASIC')), 'Crossword' => &$crossword_info);
         if (null === $operation) {
             if (!CheckRolePermissions('CROSSWORD_VIEW')) {
                 return;
             }
             $puzzle = 0;
             $worked = $this->crosswords_model->LoadCrossword($crossword_info['id'], $puzzle);
             if (!$worked) {
                 show_404();
             }
             $crosswordView = new CrosswordView($puzzle);
             $crosswordView->setClueTypes($crossword_info['has_quick_clues'], $crossword_info['has_cryptic_clues']);
             $crosswordView->setReadOnly(true, true);
             $data['Grid'] =& $crosswordView;
             $data['Tips'] = new CrosswordTipsList(null, $crossword_info['id'], true, false);
             $this->pages_model->SetPageCode('crosswords_office_xword_view');
             $this->main_frame->SetContentSimple('crosswords/office/crossword_view', $data);
         } else {
             if ('save' === $operation) {
                 if (!CheckRolePermissions('CROSSWORD_VIEW', 'CROSSWORD_MODIFY')) {
                     return;
                 }
                 if (isset($_POST['xw']['save'])) {
                     $puzzle = new CrosswordPuzzle();
                     $worked = $puzzle->importData($_POST['xw']);
                     if ($worked) {
                         $this->crosswords_model->SaveCrossword($crossword, $puzzle);
                         $status = 'success';
                     } else {
                         $this->main_frame->Error(array('class' => 'error', 'text' => 'Invalid crossword data.'));
                         $status = 'fail';
                     }
                 } else {
                     $this->main_frame->Error(array('class' => 'error', 'text' => 'Unable to edit crossword.'));
                     $status = 'fail';
                 }
                 $root = array('_tag' => 'crossword', 'status' => $status);
                 $this->main_frame->SetXml($root);
                 $this->main_frame->Load();
                 return;
             } else {
                 if ('edit' === $operation) {
                     if (!CheckRolePermissions('CROSSWORD_VIEW', 'CROSSWORD_MODIFY')) {
                         return;
                     }
                     $this->pages_model->SetPageCode('crosswords_office_xword_edit');
                     $this->load->helper('input_date');
                     $this->load->helper('input_progress');
                     $puzzle = 0;
                     $worked = $this->crosswords_model->LoadCrossword($crossword, $puzzle);
                     if (!$worked) {
                         $puzzle = new CrosswordPuzzle(13, 13);
                     }
                     $crosswordView = new CrosswordView($puzzle, true);
                     $data = array();
                     // MAIN CONFIGURATION
                     $config = new InputInterfaces();
                     $quick_clues_interface = new InputCheckboxInterface('has_quick_clues', $crossword_info['has_quick_clues']);
                     $config->Add('Quick clues', $quick_clues_interface);
                     $cryptic_clues_interface = new InputCheckboxInterface('has_cryptic_clues', $crossword_info['has_cryptic_clues']);
                     $config->Add('Cryptic Clues', $cryptic_clues_interface);
                     $categories = $this->crosswords_model->GetAllCategories();
                     $category_names = array();
                     foreach ($categories as $id => $category) {
                         $category_names[$id] = $category['name'];
                     }
                     $category_interface = new InputSelectInterface('category_id', $crossword_info['category_id']);
                     $category_interface->SetOptions($category_names);
                     $config->Add('Category', $category_interface);
                     $layouts = $this->crosswords_model->GetAllLayouts();
                     $layout_names = array();
                     foreach ($layouts as $id => $layout) {
                         $layout_names[$id] = $layout['name'];
                     }
                     $layout_interface = new InputSelectInterface('layout_id', $crossword_info['layout_id']);
                     $layout_interface->SetOptions($layout_names);
                     $config->Add('Layout', $layout_interface);
                     $deadline_interface = new InputDateInterface('deadline', $crossword_info['deadline'], true);
                     $config->Add('Deadline', $deadline_interface);
                     $publication_interface = new InputDateInterface('publication', $crossword_info['publication'], true);
                     $config->Add('Publication', $publication_interface);
                     $expiry_interface = new InputDateInterface('expiry', $crossword_info['expiry'], true);
                     $config->Add('Expiry', $expiry_interface);
                     $winners_value = $crossword_info['winners'];
                     $winners_interface = new InputIntInterface('winners', $winners_value, $winners_value > 0);
                     $winners_interface->SetRange(1, 100);
                     $config->Add('Winners', $winners_interface);
                     $completeness_interface = new InputProgressInterface('completeness', $crossword_info['completeness']);
                     $config->Add('Progress', $completeness_interface);
                     $authors_interface = new InputSelectInterface('authors', $crossword_info['author_ids']);
                     $authors = $this->crosswords_model->GetAllAuthors();
                     $author_options = array();
                     foreach ($authors as $author) {
                         $author_options[(int) $author['id']] = $author['fullname'];
                     }
                     foreach ($crossword_info['authors'] as $author) {
                         if (!isset($author_options[$author['id']])) {
                             $author_options[$author['id']] = $author['fullname'];
                         }
                     }
                     $authors_interface->SetOptions($author_options);
                     $config->Add('Authors', $authors_interface);
                     // VALIDATION
                     $num_errors = $config->Validate();
                     if (0 == $num_errors && $config->Updated()) {
                         $values = $config->ChangedValues();
                         $error = false;
                         if (count($values) == 0) {
                             $this->messages->AddMessage('information', "You did not make any changes");
                             $error = true;
                         }
                         // Apply rules to changes here
                         $integrated_values = $crossword_info;
                         foreach ($values as $id => $value) {
                             $integrated_values[$id] = $value;
                         }
                         // can't have deadline after publishing
                         if ($integrated_values['deadline'] !== null && $integrated_values['publication'] !== null && $integrated_values['deadline'] > $integrated_values['publication']) {
                             $this->messages->AddMessage('error', 'Deadline should not be set after publication');
                             $error = true;
                         }
                         // can't have expiry before publishing
                         if ($integrated_values['publication'] !== null && $integrated_values['expiry'] !== null && $integrated_values['publication'] > $integrated_values['expiry']) {
                             $this->messages->AddMessage('error', 'Expiry should not be set before publication');
                             $error = true;
                         }
                         if (!$error) {
                             if (isset($values['authors'])) {
                                 $authors = $values['authors'];
                                 $values['authors'] = array();
                                 foreach ($authors as $author_id) {
                                     $values['authors'][(int) $author_id] = array('id' => (int) $author_id, 'fullname' => $author_options[(int) $author_id]);
                                 }
                             }
                             $values['id'] = $crossword_info['id'];
                             if (!$this->crosswords_model->UpdateCrossword($values)) {
                                 $this->messages->AddMessage('error', 'Changes could not be saved');
                             } else {
                                 $this->messages->AddMessage('success', 'Changes have been saved successfully');
                                 foreach ($values as $id => $value) {
                                     $crossword_info[$id] = $value;
                                 }
                             }
                         }
                     }
                     // Which clues are enabled may have just changed
                     $crosswordView->setClueTypes($crossword_info['has_quick_clues'], $crossword_info['has_cryptic_clues']);
                     $data['Configuration'] =& $config;
                     $data['Tips'] = new CrosswordTipsList(null, $crossword_info['id'], true);
                     $data['Grid'] =& $crosswordView;
                     $data['Paths'] = array('view' => site_url("office/crosswords/crossword/{$crossword}"), 'save' => site_url("office/crosswords/crossword/{$crossword}/save"));
                     $this->main_frame->SetContentSimple('crosswords/office/crossword_edit', $data);
                 } else {
                     if ('stats' === $operation) {
                         if (!CheckRolePermissions('CROSSWORD_STATS_BASIC')) {
                             return;
                         }
                         // find information about this crossword
                         $data['Stats'] = $this->crosswords_model->CalculateStats($crossword_info['id'], array('saves', 'save_users'));
                         $data['Stats']['winners'] = $crossword_info['winners_so_far'];
                         $data['StatLabels'] = array('save_users' => 'Number of users who have attempted crossword (based on saves)', 'save_mean_per_user' => 'Mean number of saves per user (approx 30 secs between saves)', 'winners' => 'Number of winners');
                         $this->main_frame->SetContentSimple('crosswords/office/crossword_stats', $data);
                     } elseif ($operation == 'preview') {
                         if (!CheckRolePermissions('CROSSWORD_VIEW')) {
                             return;
                         }
                         $this->crosswords_model->GetCrosswordThumbnail($crossword);
                         return;
                     } else {
                         show_404();
                     }
                 }
             }
         }
     } else {
         show_404();
     }
     $this->main_frame->Load();
 }
 function tips($category = null)
 {
     OutputModes('xhtml', FeedOutputModes());
     if (!CheckPermissions('public')) {
         return;
     }
     if (null === $category) {
         $data = array('Categories' => $this->crosswords_model->GetTipCategories(null, true), 'SelfUri' => $this->uri->uri_string());
         $this->main_frame->SetFeedTitle('The Yorker Crossword Tips');
         if (FeedOutputMode()) {
             $this->main_frame->Channel()->SetDescription('All crossword tips.');
             $this->_fillTipsFeed();
         } else {
             $this->main_frame->setContentSimple('crosswords/tips', $data);
             /// @todo Use pages interface
             $this->main_frame->SetTitle('Crossword Tips');
         }
     } else {
         $category_info = null;
         if (is_numeric($category)) {
             $category_info = $this->crosswords_model->GetTipCategories((int) $category, true);
             if (empty($category_info)) {
                 $category_info = null;
             } else {
                 $category_info = $category_info[0];
             }
         }
         if (null === $category_info) {
             show_404();
         }
         $this->main_frame->SetFeedTitle('The Yorker Crossword Tips - ' . $category_info['name']);
         if (FeedOutputMode()) {
             $this->main_frame->Channel()->SetDescription('All crossword tips in category "' . $category_info['name'] . '".');
             $this->_fillTipsFeed($category_info['id']);
         } else {
             $data = array('Category' => $category_info, 'Tips' => new CrosswordTipsList($category_info['id'], null), 'PostAction' => $this->uri->uri_string());
             $this->main_frame->setContentSimple('crosswords/tip_cat_view', $data);
             /// @todo Use pages interface
             $this->main_frame->SetTitle('Crossword Tips - ' . $category_info['name']);
         }
     }
     $this->main_frame->Load();
 }
 function index()
 {
     OutputModes(array('xhtml', 'fbml'));
     if (!CheckPermissions('public')) {
         return;
     }
     if ('fbml' === OutputMode()) {
         return $this->_FacebookHome();
     }
     $this->load->model('home_hack_model');
     $this->load->model('flickr_model');
     $this->load->model('crosswords_model');
     $this->load->model('comments_model');
     $spotlight = $this->home_hack_model->getArticlesByTags(array('front-page'), 1);
     $this->home_hack_model->ignore($spotlight);
     $uninews = $this->home_hack_model->getArticlesByTags(array('news'), 3);
     $sport = $this->home_hack_model->getArticlesByTags(array('sport'), 4);
     $arts = $this->home_hack_model->getArticlesByTags(array('arts'), 4);
     $lifestyle = $this->home_hack_model->getArticlesByTags(array('lifestyle'), 4);
     $photos = $this->flickr_model->getLatestPhotos(9);
     $boxes = array();
     $boxes[] = array('type' => 'spotlight', 'articles' => $spotlight);
     $boxes[] = array('type' => 'article_rollover', 'title' => 'latest news', 'title_link' => '/news', 'articles' => $uninews);
     $boxes[] = array('type' => 'adsense_third', 'last' => true);
     $boxes[] = array('type' => 'article_list', 'title' => 'latest sport', 'title_link' => '/sport', 'size' => '1/3', 'last' => false, 'articles' => $sport);
     $boxes[] = array('type' => 'article_list', 'title' => 'latest arts', 'title_link' => '/arts', 'size' => '1/3', 'last' => false, 'articles' => $arts);
     $boxes[] = array('type' => 'article_list', 'title' => 'latest lifestyle', 'title_link' => '/lifestyle', 'size' => '1/3', 'last' => true, 'articles' => $lifestyle);
     $boxes[] = array('type' => 'photo_bar', 'size' => 'full', 'last' => true, 'photos' => $photos);
     $boxes[] = array('type' => 'adsense_half', 'last' => false);
     //		$boxes[] = array(
     //			'type'			=>	'advert_half',
     //			'image'			=>	'/images/adverts/woodstock.jpg',
     //			'image_title'		=>	'RAG Woodstock Saturday Week 9',
     //			'link'			=>	'http://www.facebook.com/event.php?eid=100229538904',
     //			'last'			=>	false
     //		);
     $comments_config = $this->config->item('comments');
     $boxes[] = array('type' => 'comments_latest', 'title' => 'latest comments', 'title_link' => '', 'size' => '1/2', 'last' => true, 'comments' => $this->comments_model->GetLatestComments(10), 'comments_per_page' => $comments_config['max_per_page']);
     $boxes[] = array('type' => 'crossword_latest', 'title' => 'latest crosswords', 'title_link' => '/crosswords', 'size' => '1/2', 'last' => false, 'next' => $this->crosswords_model->GetCrosswords(null, null, null, true, null, null, 1, 'ASC'), 'latest' => $this->crosswords_model->GetCrosswords(null, null, null, null, true, null, 2, 'DESC'));
     $data = array('boxes' => $boxes);
     $this->pages_model->SetPageCode('home_main');
     $this->main_frame->SetData('menu_tab', 'home');
     $this->main_frame->SetContentSimple('flexibox/layout', $data);
     $this->main_frame->IncludeCss('stylesheets/home.css');
     $this->main_frame->Load();
     //Obtain weather
     //$data['weather_forecast'] = $this->Home_Model->GetWeather();
     // Minifeeds
     //list($data['events'], $data['todo']) = $this->_GetMiniCalendars();
     // Poll data
     /*
     if ($poll_id)
     {
     	$data['poll_vote_box'] = new PollsVoteBox(
     		$this->polls_model->GetPollDetails($poll_id),
     		$this->polls_model->GetPollChoiceVotes($poll_id),
     		$user_voted,
     		$poll_show_results
     	);
     }
     else
     {
     	$data['poll_vote_box'] = null;
     }
     */
     //poll handling
     /*
     $poll_id = $this->polls_model->GetDisplayedPoll();
     $user_voted = $this->polls_model->HasUserVoted($poll_id, $this->user_auth->entityId);
     $poll_show_results = false;
     if ($poll_id && !$user_voted)
     {
     	if (isset($_POST['submit_vote'])) {
     		if ($this->input->post('poll_vote'))
     		{
     			if ($this->polls_model->IsChoicePartOfPoll($poll_id, $this->input->post('poll_vote')))
     			{
     				$this->polls_model->SetUserPollVote($poll_id, $this->user_auth->entityId, $this->input->post('poll_vote'));
     				$this->messages->AddMessage('success', 'Your vote has been cast.');
     				$user_voted = true;
     			}
     			else
     			{
     				$this->messages->AddMessage('error', 'Invalid option.');
     			}
     		}
     	}
     	elseif (isset($_POST['submit_results'])) {
     		$poll_show_results = true;
     	}
     } else {
     	$poll_show_results = true;
     }
     */
 }
 function export_ical()
 {
     OutputModes('ical');
     if (!CheckPermissions($this->mPermission)) {
         return;
     }
     $this->_LoadCalendarSystem();
     $sources = $this->_SetupSources(time(), strtotime('1week'));
     $calendar_data = new CalendarData();
     $this->messages->AddMessages($sources->FetchEvents($calendar_data));
     // Display data
     $this->load->library('calendar_view_icalendar');
     $ical = new CalendarViewICalendar();
     $ical->SetCalendarData($calendar_data);
     $ical->Load();
 }
/**
 * @param $Permission string or array of the following levels (in the order that
 *	they are to be obtained:
 *	- 'public' - anyone
 *	- 'student' - must be logged on
 *	- 'vip' - must be logged on as a vip
 *	- 'vip+pr' - must be logged on as a vip or a pr rep
 *	- 'office' - must be in the office
 *	- 'pr' - must be in the office as a pr rep
 *	- 'editor' - must be in the office as an editor
 *	- 'admin' - must be in the office as an administrator
 * @param $LoadMainFrame bool Whether to load the mainframe if permision hasn't
 *	 yet been acquired (for the login screen).
 * @return bool Whether enough privilages.
 */
function CheckPermissions($Permission = 'public', $LoadMainFrame = TRUE, $NoPost = FALSE)
{
    // Start a session
    $CI =& get_instance();
    // Initialisation stuff
    $CI->load->library('messages');
    $CI->load->model('user_auth');
    $CI->load->model('pages_model');
    // Decide on output format
    if (isset($_POST['fb_sig'])) {
        /// @todo AUTHENTICATE FACEBOOK
        OutputMode('fbml');
        global $_SESSION;
        $_SESSION = array();
    } else {
        if (isset($_GET['opmode'])) {
            OutputMode($_GET['opmode']);
        } else {
            OutputMode(DefaultOutputMode());
        }
    }
    // If the output mode is not supported, show a 404
    if (!in_array(OutputMode(), OutputModes())) {
        show_404();
    }
    // Translate some auxilliary permissions
    $auxilliary_permissions = array('moderator' => 'editor');
    if (array_key_exists($Permission, $auxilliary_permissions)) {
        $Permission = $auxilliary_permissions[$Permission];
    }
    $user_level = GetUserLevel();
    // URL analysis regarding vip area
    $thru_viparea = $CI->uri->total_segments() >= 1 && $CI->uri->segment(1) === 'viparea';
    $thru_office_pr = $CI->uri->total_segments() >= 3 && $CI->uri->segment(1) === 'office' && $CI->uri->segment(2) === 'pr' && $CI->uri->segment(3) === 'org';
    $thru_office_manage = $CI->uri->total_segments() >= 2 && $CI->uri->segment(1) === 'office' && $CI->uri->segment(2) === 'manage';
    $company_short_name = $CI->config->Item('company_organisation_id');
    $organisation_specified = FALSE;
    if ($thru_viparea) {
        if ($CI->uri->total_segments() > 1) {
            $organisation_shortname = $CI->uri->segment(2);
            $organisation_specified = TRUE;
            VipSegments(2);
        } else {
            $organisation_shortname = $CI->user_auth->organisationShortName;
        }
        // don't allow access to vip area of the company, only through office/manage
        if ($organisation_shortname === $company_short_name) {
            $organisation_shortname = '';
            $CI->user_auth->logoutOrganisation();
            redirect('');
        }
        vip_url('viparea/' . $organisation_shortname . '/', TRUE);
    } elseif ($thru_office_pr) {
        $organisation_shortname = $CI->uri->segment(4);
        $organisation_specified = TRUE;
        VipSegments(4);
        vip_url('office/pr/org/' . $organisation_shortname . '/', TRUE);
    } elseif ($thru_office_manage) {
        $organisation_shortname = $company_short_name;
        $organisation_specified = TRUE;
        VipSegments(2);
        vip_url('office/manage/', TRUE);
    } else {
        $organisation_shortname = '';
    }
    VipOrganisation(FALSE, $organisation_shortname);
    VipOrganisation(TRUE, $CI->user_auth->organisationShortName);
    // Login actions for student/vip/office logins
    $student_login_action = array('redirect+url', 'login/main', 'post' => TRUE);
    if ($organisation_specified) {
        $vip_login_action = array('redirect+url', 'login/vipswitch/' . $organisation_shortname, 'post' => TRUE);
    } else {
        $vip_login_action = array('redirect+url', 'login/vip', 'post' => TRUE);
    }
    $office_login_action = array('redirect+url', 'login/office', 'post' => TRUE);
    // If vip+pr, use URI to decide which
    if ($Permission === 'vip+pr') {
        $Permission = $thru_viparea ? 'vip' : ($thru_office_pr ? 'pr' : ($thru_office_manage ? 'manage' : ''));
    } elseif ($Permission === 'vip') {
        $Permission = $thru_viparea ? 'vip' : ($thru_office_manage ? 'manage' : '');
    } elseif ($thru_office_pr && $Permission !== 'pr' || $thru_viparea && $Permission !== 'vip' || $thru_office_manage && $Permission !== 'manage') {
        $Permission = '';
    }
    // Matrix indexed by user level, then page level, of behaviour
    // Possible values:
    //	NULL/notset	http error 404
    //	TRUE		allowed
    //	array		specially handled
    //	otherwise	access denied
    if ($user_level === 'public') {
        $action_levels = array('public' => TRUE, 'student' => $student_login_action, 'vip' => $student_login_action, 'office' => $student_login_action, 'pr' => $student_login_action, 'editor' => $student_login_action, 'manage' => $student_login_action, 'admin' => $student_login_action);
    } elseif ($user_level === 'student') {
        $action_levels = array('public' => TRUE, 'student' => TRUE, 'vip' => $vip_login_action, 'office' => $office_login_action, 'pr' => $office_login_action, 'editor' => $office_login_action, 'manage' => $office_login_action, 'admin' => $office_login_action);
    } elseif ($user_level === 'organisation') {
        // Logged in from public as organisation
        $allow_vip = array_key_exists($organisation_shortname, $CI->user_auth->allTeams);
        $action_levels = array('public' => TRUE, 'student' => TRUE, 'vip' => $allow_vip, 'office' => FALSE, 'pr' => FALSE, 'editor' => FALSE, 'manage' => FALSE, 'admin' => FALSE);
        if ($allow_vip) {
            VipOrganisationId(FALSE, $CI->user_auth->allTeams[$organisation_shortname][0]);
            VipOrganisationName(FALSE, $CI->user_auth->allTeams[$organisation_shortname][1]);
            VipOrganisationId(TRUE, $CI->user_auth->organisationLogin);
            VipOrganisationName(TRUE, $CI->user_auth->organisationName);
            VipMode('viparea');
            VipLevel('write', TRUE);
        }
    } elseif ($user_level === 'vip') {
        // Logged in as student and in VIP area
        $vip_door_open_action = array('message', 'warning', HtmlButtonLink(site_url('logout/vip' . $CI->uri->uri_string()), 'Leave VIP Area') . $CI->pages_model->GetPropertyText('login:warn_open_vip', TRUE), TRUE);
        $allow_vip = array_key_exists($organisation_shortname, $CI->user_auth->allTeams);
        if ($allow_vip) {
            $vip_accessible = TRUE;
            VipOrganisationId(FALSE, $CI->user_auth->allTeams[$organisation_shortname][0]);
            VipOrganisationName(FALSE, $CI->user_auth->allTeams[$organisation_shortname][1]);
            VipOrganisationId(TRUE, $CI->user_auth->organisationLogin);
            VipOrganisationName(TRUE, $CI->user_auth->organisationName);
            VipMode('viparea');
            VipLevel('write', TRUE);
        } else {
            // check permissions to access this organisation
            $vip_organisations = $CI->user_auth->getOrganisationLogins();
            foreach ($vip_organisations as $organisation) {
                if ($organisation['organisation_directory_entry_name'] == $organisation_shortname) {
                    $vip_accessible = $vip_login_action;
                    break;
                }
            }
            if (!isset($vip_accessible)) {
                $vip_accessible = FALSE;
            }
        }
        $action_levels = array('public' => $vip_door_open_action, 'student' => $vip_door_open_action, 'vip' => $vip_accessible, 'office' => $office_login_action, 'pr' => $office_login_action, 'editor' => $office_login_action, 'manage' => $office_login_action, 'admin' => $office_login_action);
    } else {
        // Office
        // Door left open actions
        $office_door_open_action = array('message', 'warning', HtmlButtonLink(site_url('logout/office' . $CI->uri->uri_string()), 'Leave Office') . $CI->pages_model->GetPropertyText('login:warn_open_office', TRUE), TRUE);
        $admin_door_open_action = $office_door_open_action;
        // check permissions to access this organisation
        $manage_accessible = FALSE;
        $vip_organisations = $CI->user_auth->getOrganisationLogins();
        foreach ($vip_organisations as $organisation) {
            if ($organisation['organisation_directory_entry_name'] == $company_short_name) {
                $manage_accessible = TRUE;
                break;
            }
        }
        // Refine further
        if ($user_level === 'office') {
            $action_levels = array('public' => $office_door_open_action, 'student' => $office_door_open_action, 'vip' => $vip_login_action, 'office' => TRUE, 'pr' => 'pr', 'editor' => FALSE, 'manage' => FALSE, 'admin' => FALSE);
        } elseif ($user_level === 'editor') {
            $action_levels = array('public' => $office_door_open_action, 'student' => $office_door_open_action, 'vip' => $vip_login_action, 'office' => TRUE, 'pr' => TRUE, 'editor' => TRUE, 'manage' => $manage_accessible, 'admin' => FALSE);
        } elseif ($user_level === 'admin') {
            $action_levels = array('public' => $admin_door_open_action, 'student' => $admin_door_open_action, 'vip' => $vip_login_action, 'office' => TRUE, 'pr' => TRUE, 'editor' => TRUE, 'manage' => $manage_accessible, 'admin' => TRUE);
        }
        // Change an office user to pr if they rep for the organisation
        static $vipModes = array('pr' => 'office', 'manage' => 'manage');
        if (array_key_exists($Permission, $vipModes)) {
            // Get organisation information
            $CI->db->select('organisation_entity_id AS id,' . 'organisation_name AS name,' . 'organisation_pr_rep AS rep');
            $CI->db->join('entities', 'organisation_entity_id = entity_id', 'inner');
            $CI->db->where(array('organisation_directory_entry_name' => $organisation_shortname, 'entity_deleted = FALSE'));
            $matching_org = $CI->db->get('organisations')->result_array();
            if (empty($matching_org)) {
                $action_levels[$Permission] = FALSE;
            } else {
                $matching_org = $matching_org[0];
                if ($action_levels[$Permission] === 'pr') {
                    $action_levels[$Permission] = TRUE;
                    $rep = $matching_org['rep'] == $CI->user_auth->entityId;
                    if ($rep) {
                        VipLevel('rep', TRUE);
                    } else {
                        VipLevel('read', TRUE);
                    }
                } elseif ($action_levels[$Permission]) {
                    VipLevel('write', TRUE);
                }
                VipOrganisationId(FALSE, $matching_org['id']);
                VipOrganisationName(FALSE, $matching_org['name']);
                VipOrganisationId(TRUE, $matching_org['id']);
                VipOrganisationName(TRUE, $matching_org['name']);
                VipMode($vipModes[$Permission]);
            }
        }
    }
    $access_allowed = FALSE;
    // No permission set or NULL indicates page doesn't exist at this URI
    if (!array_key_exists($Permission, $action_levels) || NULL === $action_levels[$Permission]) {
        return show_404();
    } else {
        $action = $action_levels[$Permission];
        // True is allow
        if (TRUE === $action) {
            $access_allowed = TRUE;
        } elseif (is_array($action)) {
            // Array is special decider
            // Perform action
            switch ($action[0]) {
                case 'handle':
                    $access_allowed = $action[1]($action[2], $Permission);
                    if (array_key_exists(3, $action)) {
                        $CI->messages->AddMessage($action[3], $action[4], FALSE);
                    }
                    break;
                case 'redirect+url':
                    $action[1] .= $CI->uri->uri_string();
                case 'redirect':
                    if (array_key_exists(2, $action)) {
                        $CI->messages->AddMessage($action[2], $action[3]);
                    }
                    if (array_key_exists('post', $action) && $action['post']) {
                        // store post data
                        if (!empty($_POST)) {
                            SetRedirectData($action[1], serialize($_POST));
                        }
                    }
                    // Before redirecting, forward on the redirected post data
                    $post_data = GetRedirectData();
                    if (NULL !== $post_data) {
                        SetRedirectData($action[1], $post_data);
                    }
                    // Do the redirect
                    redirect($action[1]);
                    return FALSE;
                case 'message':
                    $CI->messages->AddMessage($action[1], $action[2], FALSE);
                    $access_allowed = $action[3];
                    break;
                default:
                    break;
            }
        } else {
            // Anything else is disallow
            $CI->messages->AddMessage('warning', 'You do not have the ' . $Permission . ' privilages required!');
            //redirect('');
        }
        // Restore post data
        if ((TRUE === $action || is_array($action)) && !$NoPost) {
            $post_data = GetRedirectData();
            if (NULL !== $post_data) {
                $post_data = @unserialize($post_data);
                if (is_array($post_data)) {
                    if (!isset($_POST)) {
                        global $_POST;
                        $_POST = array();
                    }
                    foreach ($post_data as $key => $value) {
                        $_POST[$key] = $value;
                    }
                }
            }
        }
    }
    if ('fbml' === OutputMode()) {
        $Permission = 'facebookapp';
    } elseif ('ajax' === OutputMode()) {
        $Permission = 'ajax';
    } elseif (FeedOutputMode()) {
        $Permission = 'feed';
    }
    SetupMainFrame($Permission, FALSE);
    if (!$access_allowed && $LoadMainFrame) {
        $CI->load->library('Custom_pages');
        $page = new CustomPageView('error:permissions');
        $CI->main_frame->SetContent($page);
        $CI->main_frame->Load();
    }
    return $access_allowed;
}
 function SetFeedTitle($Title)
 {
     // If this page supports RSS, link it.
     if (in_array('rss', OutputModes())) {
         $this->IncludeRss(OutputModeChangeUri('rss'), $Title);
     }
 }