/** * Class constructor * * @access public */ public function __construct() { parent::__construct(); $this->_title = 'Dashboard'; if ($this->_user['dashboard']) { $this->get_activity(); $this->get_recent_comments(); $this->get_draft(); Helper::get_categories($this->_categories, $this->_action_msg, 'post'); if (Helper::check_update() === true) { $this->_action_msg = ActionMessages::ws_update_check(true, true); } } }
/** * Log in the user if credentials are correct * * @access public */ public function login() { $to_read['table'] = 'user'; $to_read['columns'] = array('USER_ID', 'user_username', 'user_password'); $to_read['condition_columns'][':name'] = 'user_username'; $to_read['condition_types'][':name'] = 'AND'; $to_read['condition_select_types'][':name'] = '='; $to_read['condition_values'][':name'] = VPost::login(); $to_read['value_types'][':name'] = 'str'; $user = $this->_db->read($to_read); if ($user === false || empty($user)) { throw new Exception('Invalid Username'); } else { if ($user[0]['user_username'] == VPost::login() && $user[0]['user_password'] == Helper::make_password(VPost::login(), VPost::password())) { $_SESSION['username'] = $user[0]['user_username']; $_SESSION['user_id'] = $user[0]['USER_ID']; header('Location: index.php'); } else { throw new Exception('Invalid Password'); } } }
/** * Display page content * * @access public */ public function display_content() { $this->display_menu(); if ($this->_user['post']) { echo $this->_action_msg; echo '<div id="list_wrapper">'; Html::form('o', 'post', 'index.php?ns=posts&ctl=manage'); $this->display_post_status(); $this->display_actions('top'); $this->display_table(); $this->display_actions('butt'); $this->display_pagination(); echo Helper::datalist('titles', $this->_content, '_title'); Html::form('c'); } else { echo ActionMessages::part_no_perm(); } }
/** * Move uploaded files to the right place and insert metadata in the database * * @access private */ private function create() { if (VPost::upload(false)) { try { $path = 'content/' . date('Y/m/'); $img = new HandleMedia(); $img->load_upload('file'); $name = Helper::remove_accent($img->_name); $mime = $img->_mime; if (file_exists(PATH . $path . $name)) { throw new Exception('The file "' . $name . '" already exists'); } $img->save(PATH . $path . $name); if (substr($mime, 0, 5) == 'image') { $img->thumb(150, 0); $img->thumb(300, 0); $img->thumb(1000, 0); $this->_media->_status = 'draft'; } elseif (substr($mime, 0, 5) == 'video') { $this->_media->_status = 'publish'; } $this->_media->_name = $name; $this->_media->_type = $mime; $this->_media->_author = $this->_user['user_id']; $this->_media->_allow_comment = 'closed'; $this->_media->_permalink = $path . $name; $this->_media->_album = 0; $this->_media->create(); Session::monitor_activity('has uploaded a file named: ' . $this->_media->_name); if (substr($mime, 0, 5) == 'video') { header('Location: index.php?ns=media&ctl=manage&type=video'); } else { header('Location: index.php?ns=media&ctl=manage'); } } catch (Exception $e) { $this->_action_msg = ActionMessages::custom_wrong($e->getMessage()); } } elseif (VPost::create_album(false) && $this->_user['album_photo']) { if (!VPost::name()) { $this->_action_msg = ActionMessages::custom_wrong('Album name missing'); } else { try { $name = VPost::name(); $path = 'content/albums/' . Helper::slug($name) . '/'; if (file_exists(PATH . $path)) { throw new Exception('The album "' . $name . '" already exists'); } $this->_media->_name = $name; $this->_media->_type = 'album'; $this->_media->_author = $this->_user['user_id']; $this->_media->_status = 'draft'; $this->_media->_permalink = $path; $this->_media->_description = stripslashes(VPost::description()); $this->_media->_category = implode(',', VPost::cat(array())); $this->_media->_allow_comment = VPost::allow_comment('closed'); $this->_media->_album = 0; $img = new HandleMedia(); $img->load_upload('cover'); $img->save(PATH . $path . 'cover.png'); $img->thumb(150, 0); $img->thumb(300, 0); $img->thumb(1000, 0); $this->_media->create(); Session::monitor_activity('created an album named: ' . $this->_media->_name); header('Location: index.php?ns=media&ctl=albums&action=edit&id=' . $this->_media->_id); } catch (Exception $e) { $this->_action_msg = ActionMessages::custom_wrong($e->getMessage()); } } } elseif (VPost::link_alien(false)) { if (!VPost::name() || !VPost::embed_code()) { $this->_action_msg = ActionMessages::custom_wrong('There\'s missing informations'); } else { try { $this->_media->_name = VPost::name(); $this->_media->_type = 'alien'; $this->_media->_author = $this->_user['user_id']; $this->_media->_status = 'draft'; $this->_media->_allow_comment = 'closed'; $this->_media->_permalink = Helper::slug(VPost::name()); $this->_media->_embed_code = VPost::embed_code(); $this->_media->_album = 0; $this->_media->create(); Session::monitor_activity('linked a new video named: ' . $this->_media->_name); header('Location: index.php?ns=media&ctl=manage&type=video'); } catch (Exception $e) { $this->_action_msg = ActionMessages::custom_wrong($e->getMessage()); } } } elseif (VPost::register_video(false)) { try { if (!file_exists(PATH . VPost::url())) { throw new Exception('Video not found'); } if (!VPost::mime()) { throw new Exception('Video mime type missing'); } $this->_media->_name = VPost::name(); $this->_media->_type = VPost::mime(); $this->_media->_author = $this->_user['user_id']; $this->_media->_status = 'publish'; $this->_media->_allow_comment = 'closed'; $this->_media->_permalink = VPost::url(); $this->_media->_album = 0; $this->_media->create(); Session::monitor_activity('registered a new video named: ' . $this->_media->_name); header('Location: index.php?ns=media&ctl=manage&action=edit&type=video&id=' . $this->_media->_id); } catch (Exception $e) { $this->_action_msg = ActionMessages::custom_wrong($e->getMessage()); } } }
/** * Set data in user object and returns errors if data doesn't fit * * @access private * @return boolean */ private function check_post_data() { $results = array(); $errors = array(); array_push($results, $this->_profile->__set('_firstname', VPost::firstname())); array_push($results, $this->_profile->__set('_lastname', VPost::lastname())); array_push($results, $this->_profile->__set('_nickname', VPost::nickname())); array_push($results, $this->_profile->__set('_publicname', VPost::public_name())); if (VPost::role(false)) { //don't set when update own profile array_push($results, $this->_profile->__set('_role', VPost::role())); } array_push($results, $this->_profile->__set('_email', VPost::email())); array_push($results, $this->_profile->__set('_website', VPost::website())); array_push($results, $this->_profile->__set('_msn', VPost::msn())); array_push($results, $this->_profile->__set('_twitter', VPost::twitter())); array_push($results, $this->_profile->__set('_facebook', VPost::fb())); array_push($results, $this->_profile->__set('_google', VPost::google())); array_push($results, $this->_profile->__set('_avatar', VPost::avatar())); array_push($results, $this->_profile->__set('_bio', VPost::bio())); if (VPost::new_pwd(false) && VPost::new_pwd() == VPost::re_new_pwd()) { array_push($results, $this->_profile->__set('_password', Helper::make_password($this->_profile->_username, VPost::new_pwd()))); } elseif (VPost::new_pwd(false) && VPost::new_pwd() != VPost::re_new_pwd()) { array_push($results, 'Passwords does\'t match'); } foreach ($results as $result) { if ($result !== true) { //so it contains an error message array_push($errors, '<li>- ' . $result . '<li>'); } } if (!empty($errors)) { $error_msg = 'Check your informations:<br/><ul>' . implode('', $errors) . '</ul>'; $this->_action_msg = ActionMessages::custom_wrong($error_msg); return false; } else { return true; } }
/** * Update lynxpress * * @access private */ private function update() { if (VPost::update()) { try { if (Helper::check_update() === false) { throw new Exception('No update available!'); } //make a backup of the database first, with an email sent to webmaster with the whole dump $bk = new Backup(); $bk->save('backup/dump-' . date('Y-m-d-H:i:s') . '.sql'); $html = new File(); $html->_content = '<!--The Lynx is not here!-->'; $html->save('backup/index.html'); $mail = new Mail(WS_EMAIL, 'Databse dump made before update at ' . date('Y-m-d H:i:s'), $bk->_sql); $mail->send(); //end backup //retrieve json manifest from the server $manifest = new Curl('http://update.lynxpress.org/manifest.json'); $manifest = json_decode($manifest->_content, true); //retrieve zip with all files inside $curl_zip = new Curl('http://versions.lynxpress.org/Lynxpress-' . $manifest['version'] . '.zip'); if ($curl_zip->_content == '<!--The Lynx is not here!-->') { throw new Exception('Can\'t retrieve lynxpress archive'); } $zip = new File(); $zip->_content = $curl_zip->_content; $zip->save('tmp/update.zip'); unset($zip); unset($curl_zip); File::unzip('tmp/update.zip', 'tmp/update/'); File::delete('tmp/update.zip'); //check if all files are readable foreach ($manifest['src'] as $src) { File::read('tmp/update/Lynxpress-' . $manifest['version'] . '/' . $src); } //replace all files registered in the manifest foreach ($manifest['src'] as $key => $src) { File::read('tmp/update/Lynxpress-' . $manifest['version'] . '/' . $src)->save($manifest['dest'][$key]); File::delete('tmp/update/Lynxpress-' . $manifest['version'] . '/' . $src); } //execute special queries foreach ($manifest['queries'] as $query) { $this->_db->query(str_replace('{{prefix}}', DB_PREFIX, $query)); } //remove files foreach ($manifest['remove'] as $file) { File::delete($file, false); } $config = File::read(PATH . 'config.php'); $config->_content = str_replace('(\'WS_VERSION\', \'' . WS_VERSION . '\')', '(\'WS_VERSION\', \'' . $manifest['version'] . '\')', $config->_content); $config->save(); unset($config); $config = File::read(PATH . 'config.sample.php'); $config->_content = str_replace('(\'WS_VERSION\', \'' . WS_VERSION . '\')', '(\'WS_VERSION\', \'' . $manifest['version'] . '\')', $config->_content); $config->save(); $result = true; } catch (Exception $e) { $result = $e->getMessage(); } $this->_action_msg = ActionMessages::ws_update($result); } }
/** * Set data from the form into the object * * If errors detected in the object it's returned into an array * * @access private * @return boolean */ private function check_post_data() { $results = array(); $errors = array(); array_push($results, $this->_post->__set('_title', VPost::title())); array_push($results, $this->_post->__set('_content', VPost::content())); array_push($results, $this->_post->__set('_allow_comment', VPost::allow_comment('closed'))); if (VPost::publish(false)) { array_push($results, $this->_post->__set('_status', 'publish')); } else { array_push($results, $this->_post->__set('_status', 'draft')); } array_push($results, $this->_post->__set('_category', implode(',', VPost::categories(array())))); //insertion of an empty aarray to return error message defined in the object array_push($results, $this->_post->__set('_tags', VPost::tags('divers'))); if ($this->_action == 'to_insert') { array_push($results, $this->_post->__set('_permalink', Helper::slug($this->_post->__get('_title')))); } //we should make it in create method, but we need to handle the error foreach ($results as $result) { if ($result !== true) { array_push($errors, '<li>- ' . $result . '</li>'); } } if (!empty($errors)) { $error_msg = 'Check your informations:<br/><ul>' . implode('', $errors) . '</ul>'; $this->_action_msg = ActionMessages::custom_wrong($error_msg); return false; } else { return true; } }
/** * Install website * * @access private */ private function install() { $this->_db_host = VPost::db_host(); $this->_db_name = VPost::db_name(); $this->_db_user = VPost::db_user(); $this->_db_pwd = VPost::db_pwd(); $this->_db_prefix = VPost::db_prefix(); $this->_ws_url = VPost::ws_url(); $this->_ws_name = VPost::ws_name(); $this->_ws_email = VPost::ws_email(); $this->_username = VPost::username(); $this->_password = VPost::password(); $conf = "<?php\n"; $conf .= "\n"; $conf .= "\t/**\n"; $conf .= "\t\t* @author\t\tBaptiste Langlade\n"; $conf .= "\t\t* @copyright\t2011-2012\n"; $conf .= "\t\t* @license\t\thttp://www.gnu.org/licenses/gpl.html GNU GPL V3\n"; $conf .= "\t\t* @package\t\tLynxpress\n"; $conf .= "\t\t*\n"; $conf .= "\t\t* This file is part of Lynxpress.\n"; $conf .= "\t\t*\n"; $conf .= "\t\t* Lynxpress is free software: you can redistribute it and/or modify\n"; $conf .= "\t\t* it under the terms of the GNU General Public License as published by\n"; $conf .= "\t\t* the Free Software Foundation, either version 3 of the License, or\n"; $conf .= "\t\t* (at your option) any later version.\n"; $conf .= "\t\t*\n"; $conf .= "\t\t* Lynxpress is distributed in the hope that it will be useful,\n"; $conf .= "\t\t* but WITHOUT ANY WARRANTY; without even the implied warranty of\n"; $conf .= "\t\t* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"; $conf .= "\t\t* GNU General Public License for more details.\n"; $conf .= "\t\t*\n"; $conf .= "\t\t* You should have received a copy of the GNU General Public License\n"; $conf .= "\t\t* along with Lynxpress. If not, see http://www.gnu.org/licenses/.\n"; $conf .= "\t*/\n"; $conf .= "\n"; $conf .= "\t/**\n"; $conf .= "\t\t* Configuration of the website\n"; $conf .= "\t*/\n"; $conf .= "\n"; $conf .= "\tdefine('WS_NAME', '" . $this->_ws_name . "');\n"; $conf .= "\tdefine('WS_URL', '" . $this->_ws_url . "');\n"; $conf .= "\tdefine('WS_EMAIL', '" . $this->_ws_email . "');\n"; $conf .= "\tdefine('DB_HOST', '" . $this->_db_host . "');\n"; $conf .= "\tdefine('DB_NAME', '" . $this->_db_name . "');\n"; $conf .= "\tdefine('DB_USER', '" . $this->_db_user . "');\n"; $conf .= "\tdefine('DB_PWD', '" . $this->_db_pwd . "');\n"; $conf .= "\tdefine('DB_PREFIX', '" . $this->_db_prefix . "');\n"; $conf .= "\n"; $conf .= "\tdefine('SALT', '" . Helper::generate_salt() . "');\t\t//after installation, don't change this constant\n"; $conf .= "\n"; $conf .= "\tdefine('WS_VERSION', '" . self::VERSION . "');\n"; $conf .= "\n"; $conf .= "?>"; $this->_conf = $conf; try { //config.php creation $config = @fopen('config.php', 'w'); if (!$config) { throw new Exception('false fopen'); } fwrite($config, $conf); fclose($config); //end config creation //try to connect to database, if not exception raisen and we create it $this->_db = new PDO('mysql:dbname=' . $this->_db_name . ';host=' . $this->_db_host . ';', $this->_db_user, $this->_db_pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); require 'config.php'; //create tables $this->create_activity(); $this->create_category(); $this->create_comment(); $this->create_link(); $this->create_media(); $this->create_post(); $this->create_setting(); $this->create_user(); $this->_result = 'successful'; } catch (Exception $e) { if ($e->getMessage() == 'false fopen') { $this->_result = 'false fopen'; } elseif ($e->getMessage() == 'SQLSTATE[28000] [1045] Access denied for user \'' . $this->_db_user . '\'@\'' . $this->_db_host . '\' (using password: YES)') { $this->_result = 'false connect'; unlink('config.php'); } elseif ($e->getMessage() == 'SQLSTATE[42000] [1049] Unknown database \'' . $this->_db_name . '\'') { try { $this->_db = new PDO('mysql:host=' . $this->_db_host . ';', $this->_db_user, $this->_db_pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); $this->create_database(); $this->_db = new PDO('mysql:dbname=' . $this->_db_name . ';host=' . $this->_db_host . ';', $this->_db_user, $this->_db_pwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); require 'config.php'; $this->create_activity(); $this->create_category(); $this->create_comment(); $this->create_link(); $this->create_media(); $this->create_post(); $this->create_setting(); $this->create_user(); $this->_result = 'successful'; } catch (Exception $e) { if ($e->getMessage() == 'false create') { $this->_result = 'false create'; } else { $this->_result = 'unknown'; } unlink('config.php'); } } elseif ($e->getMessage() == 'false create') { $this->_result = 'false create'; unlink('config.php'); } else { $this->_result = 'unknown'; unlink('config.php'); } } }
/** * Create method to add a row in user table * * After creation success, the id of the row is inserted in id attribute * * @access public */ public function create() { $to_create['table'] = $this->_sql_table; $to_create['columns'] = array(':name' => 'user_username', ':nname' => 'user_nickname', ':fname' => 'user_firstname', ':lname' => 'user_lastname', ':pname' => 'user_publicname', ':pwd' => 'user_password', ':mail' => 'user_email', ':web' => 'user_website', ':msn' => 'user_msn', ':tweet' => 'user_twitter', ':fb' => 'user_facebook', ':gg' => 'user_google', ':av' => 'user_avatar', ':bio' => 'user_bio', ':role' => 'user_role'); $to_create['values'] = array(':name' => $this->_username, ':nname' => $this->_nickname, ':fname' => $this->_firstname, ':lname' => $this->_lastname, ':pname' => $this->_publicname, ':pwd' => Helper::make_password($this->_username, $this->_password), ':mail' => $this->_email, ':web' => $this->_website, ':msn' => $this->_msn, ':tweet' => $this->_twitter, ':fb' => $this->_facebook, ':gg' => $this->_google, ':av' => $this->_avatar, ':bio' => $this->_bio, ':role' => $this->_role); $to_create['types'] = array(':name' => 'str', ':nname' => 'str', ':fname' => 'str', ':lname' => 'str', ':pname' => 'str', ':pwd' => 'str', ':mail' => 'str', ':web' => 'str', ':msn' => 'str', ':tweet' => 'str', ':fb' => 'str', ':gg' => 'str', ':av' => 'int', ':bio' => 'str', ':role' => 'str'); $is_int = $this->_db->create($to_create); if (is_int($is_int)) { $this->_id = $is_int; $this->_result_action = true; } else { throw new Exception('There\'s a problem creating your ' . __CLASS__); } }
/** * Method that display the page * * @access public */ public function display_content() { $this->display_menu(); if ($this->_user['comments']) { echo $this->_action_msg . '<div id="list_wrapper">'; Html::form('o', 'post', 'index.php?ns=comments&ctl=manage'); if (VGet::action() == 'edit') { $this->display_edit(); } elseif (VGet::action() == 'reply') { $this->display_reply(); } else { $this->display_comment_status(); if (!empty($this->_content)) { $this->display_actions('top'); $this->display_table(); $this->display_actions('butt'); $this->display_pagination(); } else { Html::table('o'); if (VPost::search_button(false)) { $no_post = '<tr><td colspan="4">No comments found'; if ($this->_status == 'trash') { $no_post .= ' in Trash'; } echo $no_post . '</td></tr>'; } else { echo '<tr><td colspan="4">There is no comments yet.</td></tr>'; } Html::table('c'); } } echo Helper::datalist('names', $this->_content, '_name'); Html::form('c'); echo '</div>'; } else { echo ActionMessages::part_no_perm(); } }
/** * Display page content * * @access public */ public function display_content() { $this->display_menu(); if ($this->_user['settings']) { echo $this->_action_msg; Html::form('o', 'post', 'index.php?ns=links&ctl=manage'); $this->display_actions('top'); $this->display_table(); $this->display_actions('butt'); echo Helper::datalist('titles', $this->_content, '_name'); Html::form('c'); } else { echo ActionMessages::part_no_perm(); } }
/** * Display page content * * @access public */ public function display_content() { $this->display_menu(); if ($this->_user['media']) { echo $this->_action_msg; echo '<div id="list_wrapper">'; Html::form('o', 'post', 'index.php?ns=media&ctl=manage'); if (VGet::action() == 'edit' && VGet::type() && VGet::id()) { $method = 'display_edit_' . VGet::type(); $this->{$method}(); } else { $this->display_view_types(); $this->display_actions('top'); $this->display_table(); $this->display_actions('butt'); $this->display_pagination(); echo Helper::datalist('titles', $this->_medias, '_title'); } Html::form('c'); } else { echo ActionMessages::part_no_perm(); } }
/** * Move uploaded files in the associated album directory and insert metadata in the database * * @access private */ private function create() { if (VPost::upload(false) && !empty($_FILES)) { try { $album = new Media(); $album->_id = VPost::album_id(); $album->read('_name'); $album->read('_permalink'); $path = $album->_permalink; foreach (VFiles::all() as $key => $img) { if (empty($img['name'])) { continue; } $pic = new HandleMedia(); $pic->load_upload($key); $name = Helper::remove_accent($pic->_name); $mime = $pic->_mime; if (substr($mime, 0, 5) == 'image') { if (file_exists(PATH . $path . $name)) { throw new Exception('The file "' . $name . '" already exists'); } $pic->save(PATH . $path . $name); $pic->thumb(150, 0); $pic->thumb(300, 0); $pic->thumb(1000, 0); $picture = new Media(); $picture->_name = $name; $picture->_type = $mime; $picture->_author = $this->_user['user_id']; $picture->_album = $album->_id; $picture->_allow_comment = 'closed'; $picture->_permalink = $path . $name; $picture->_status = 'publish'; $picture->create(); } } Session::monitor_activity('added new photos to ' . $album->_name); $result = true; } catch (Exception $e) { $result = $e->getMessage(); } $this->_action_msg = ActionMessages::created($result); } elseif (VPost::upload_zip() && !empty($_FILES)) { try { $album = new Media(); $album->_id = VPost::album_id(); $album->read('_name'); $album->read('_permalink'); $path = $album->_permalink; $tmp = 'tmp/albums/'; if (empty($_FILES['zip']['tmp_name'])) { throw new Exception('No archive uploaded!'); } File::unzip($_FILES['zip']['tmp_name'], $tmp); $files = @scandir($tmp); if (empty($files)) { throw new Exception('Your archive is empty!'); } foreach ($files as $file) { $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($tmp . $file); if ($mime == 'directory') { continue; } $pic = new HandleMedia(); $pic->_mime = $mime; $pic->load($tmp . $file); $name = Helper::remove_accent($pic->_name); if (substr($mime, 0, 5) == 'image') { if (file_exists(PATH . $path . $name)) { throw new Exception('The file "' . $name . '" already exists'); } File::read($tmp . $file)->save(PATH . $path . $name); $pic->_file = PATH . $path . $name; $pic->thumb(150, 0); $pic->thumb(300, 0); $pic->thumb(1000, 0); $picture = new Media(); $picture->_name = $name; $picture->_type = $mime; $picture->_author = $this->_user['user_id']; $picture->_album = $album->_id; $picture->_allow_comment = 'closed'; $picture->_permalink = $path . $name; $picture->_status = 'publish'; $picture->create(); File::delete($tmp . $file); } } Session::monitor_activity('added new photos to ' . $album->_name); $result = true; } catch (Exception $e) { $result = $e->getMessage(); } $this->_action_msg = ActionMessages::created($result); } }
<li><a href="index.php?ns=comments&ctl=manage">Pending</a></li> <li><a href="index.php?ns=comments&ctl=manage&comment_status=approved">Approved</a></li> <li><a href="index.php?ns=comments&ctl=manage&comment_status=spam">Spam</a></li> <li><a href="index.php?ns=comments&ctl=manage&comment_status=trash">Trash</a></li> </ul> </li> <li> <a href="index.php?ns=users&ctl=profile">Profile</a> </li> <li> <a href="index.php?ns=plugins&ctl=bridge">Plugins</a> <?php $plugins = Helper::plugins_infos(); if (!empty($plugins)) { echo '<ul id="mplg">'; foreach ($plugins as $plg) { echo '<li><a href="index.php?ns=' . $plg['namespace'] . '&ctl=' . $plg['entry_point'] . '">' . $plg['name'] . '</a></li>'; } echo '</ul>'; } ?> </li> <?php if ($page->settings) { echo '<li>' . '<a href="index.php?ns=settings&ctl=manage">Settings</a>' . '<ul>' . '<li><a href="index.php?ns=categories&ctl=manage">Categories</a></li>' . '<li><a href="index.php?ns=posts&ctl=settingpage">Posts</a></li>' . '<li>' . '<a href="index.php?ns=users&ctl=manage">Users</a>' . '<ul>' . '<li><a href="index.php?ns=users&ctl=add">Add</a></li>' . '</ul>' . '</li>' . '<li><a href="index.php?ns=roles&ctl=manage">Roles</a></li>' . '<li><a href="index.php?ns=social&ctl=manage">Social Buttons</a></li>' . '<li><a href="index.php?ns=defaultpage&ctl=manage">Default Page</a></li>' . '<li>' . '<a href="index.php?ns=templates&ctl=manage">Templates</a>' . '<ul>' . '<li><a href="index.php?ns=templates&ctl=add">Add</a></li>' . '<li><a href="index.php?ns=templates&ctl=library">Library</a></li>' . '</ul>' . '</li>' . '<li>' . '<a href="index.php?ns=plugins&ctl=manage">Plugins</a>' . '<ul>' . '<li><a href="index.php?ns=plugins&ctl=add">Add</a></li>' . '<li><a href="index.php?ns=plugins&ctl=library">Library</a></li>' . '</ul>' . '</li>' . '<li>' . '<a href="index.php?ns=links&ctl=manage">Links</a>' . '<ul>' . '<li><a href="index.php?ns=links&ctl=add">Add</a></li>' . '</ul>' . '</li>' . '<li><a href="index.php?ns=activity&ctl=manage">Activity</a></li>' . '<li><a href="index.php?ns=update&ctl=manage">Update</a></li>' . '</ul>' . '<li>'; }