Error:
12 | 14 |├── .gitignore ├── .htaccess ├── LICENSE ├── README.md ├── applications ├── admin │ ├── admin.php │ ├── index.php │ └── routes.php ├── auth │ ├── auth.php │ ├── index.php │ └── routes.php ├── index.php └── todo │ ├── index.php │ ├── routes.php │ └── todo.php ├── assets └── js │ └── preview.js ├── cms_todo.sql ├── config.example.php ├── includes ├── Application.php ├── Base.php ├── TemplateFunctions.php ├── Widget.php └── index.php ├── index.php ├── libraries └── core │ ├── database │ ├── index.php │ └── mysql_database.php │ └── http │ ├── index.php │ └── routes.php ├── templates ├── default │ ├── 403.php │ ├── 404.php │ ├── 500.php │ ├── Screenshot.png │ ├── admin │ │ ├── index.php │ │ ├── themes.php │ │ ├── user_edit.php │ │ └── users_list.php │ ├── auth │ │ ├── auth.php │ │ ├── message.php │ │ └── resetpassword.php │ ├── css │ │ ├── bootstrap.min.css │ │ ├── style.css │ │ └── theme-list.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── footer.php │ ├── functions.php │ ├── header.php │ ├── index.php │ ├── js │ │ ├── bootstrap.min.js │ │ └── jquery-2.1.1.min.js │ ├── sidebar.php │ └── todo │ │ ├── edit.php │ │ ├── index.php │ │ ├── new.php │ │ └── show.php └── fixed_top │ ├── 400.php │ ├── 403.php │ ├── 404.php │ ├── 500.php │ ├── Screenshot.png │ ├── admin │ ├── index.php │ ├── themes.php │ ├── user_edit.php │ └── users_list.php │ ├── auth │ ├── auth.php │ ├── message.php │ └── resetpassword.php │ ├── css │ ├── bootstrap.min.css │ ├── style.css │ └── theme-list.css │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff │ ├── footer.php │ ├── functions.php │ ├── header.php │ ├── index.php │ ├── js │ ├── bootstrap.min.js │ └── jquery-2.1.1.min.js │ ├── sidebar.php │ └── todo │ ├── edit.php │ ├── index.php │ ├── new.php │ └── show.php └── widgets ├── logo ├── index.php └── logo.php ├── nav ├── index.php └── nav.php ├── sidemenu ├── index.php └── sidemenu.php └── sidemenu2 ├── index.php └── sidemenu2.php /.gitignore: -------------------------------------------------------------------------------- 1 | config.php -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{REQUEST_FILENAME} !-d 3 | RewriteCond %{REQUEST_FILENAME} !-f 4 | RewriteCond $1 !^(images|photos|css|js|robots\.txt) 5 | RewriteRule ^(.+)$ index.php/$1 [NC,L] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Harish Kumar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # todolist 2 | A truly free and open source self created cms demo by creating a todo app which you can contribute to the develop. Features include 3 | 4 | * Sleek, stylish, portable and well-distributed interface 5 | * Login, Log out and Register Users 6 | * A default to do application which add, edit and delete to do entries under different labels. Save a due date and calculate remaining time and mansion the progress of the work 7 | * Portability for modules and widgets 8 | * customizable themes ( new themes can be added) 9 | * Admin section 10 | * Privacy and Security 11 | * No Ads 12 | * No Spam 13 | 14 | Contact [Harish](https://www.facebook.com/profile.php?id=100003606204068) for more details. 15 | 16 | Installation 17 | ------- 18 | 19 | The frontend is developed [Bootstrap](http://getbootstrap.com/). 20 | If you wish to test it out, install xampp and fork the repository to `~\xampp\htdocs` for windows and `/var/www/html/` in linux. 21 | 22 | * Change config.example.php to config.php and set required config as mention in file. 23 | * Import sql file 24 | * Start apache and mysql services and go to `localhost\phpcms` . 25 | 26 | tutorials 27 | ------------ 28 | 29 | I am creating this cms as well as tutorial for this cms. The tutorials will be uploaded on my blogging webiste [Flowkl](https://www.flowkl.com/tutorial/web-development/learn-building-cms-from-scratch-with-todo-list-demo-in-php-and-mysql/) . 30 | 31 | Demo 32 | ------------ 33 | The simple demo of this project is live on [https://todo.flowkl.com](https://todo.flowkl.com). 34 | 35 | Contributing 36 | ------------ 37 | 38 | See [Contributing](CONTRIBUTING.md) 39 | 40 | -------------------------------------------------------------------------------- /applications/admin/admin.php: -------------------------------------------------------------------------------- 1 | update theme, update widgets, handle menues, handle users 10 | */ 11 | 12 | require_once('includes/Application.php'); 13 | require_once('includes/TemplateFunctions.php'); 14 | 15 | class AdminApplication extends Application 16 | { 17 | 18 | /** 19 | * login is required for accessing admin 20 | * NOTE: in production also restrict only for admin 21 | */ 22 | function __construct() 23 | { 24 | $this->login_required(); 25 | // uncomment this line for admin required 26 | // $this->admin_required(); 27 | } 28 | 29 | /** 30 | * restrict only for admin 31 | */ 32 | private function admin_required() 33 | { 34 | if ($_SESSION['user_session']['role'] !== 'admin') { 35 | $_SESSION['error'] = 'Only admin can access this page.'; 36 | $this->redirect($this->to_url('home')); 37 | } 38 | } 39 | 40 | /** 41 | * default display function for admin 42 | */ 43 | function display() 44 | { 45 | $this->index(); 46 | } 47 | 48 | /** 49 | * view admin dashboard 50 | */ 51 | function index() 52 | { 53 | require_once(TEMPLATE_PATH . '/admin/index.php'); 54 | } 55 | 56 | /** 57 | * show the list of all themes 58 | */ 59 | function theme_list() 60 | { 61 | $themes = scandir('templates'); 62 | require_once(TEMPLATE_PATH . '/admin/themes.php'); 63 | } 64 | 65 | /** 66 | * check if user is admin 67 | * @return string $theme 68 | */ 69 | private function theme_validator() 70 | { 71 | // this if statement is only because admin_required is not called in constructor 72 | // only for demo purpose 73 | if ($_SESSION['user_session']['role'] !== 'admin') { 74 | $_SESSION['error'] = 'Only admin can change the theme. You can use live preview'; 75 | $this->redirect($this->to_url('theme-settings')); 76 | } 77 | 78 | if (!isset($_GET['theme']) || empty($_GET['theme'])) { 79 | require TEMPLATE_PATH . '/400.php'; 80 | http_response_code(400); 81 | exit; 82 | } 83 | 84 | $theme = $_GET['theme']; 85 | $dir = 'templates/' . $theme; 86 | if (!is_dir($dir)) { 87 | require TEMPLATE_PATH . '/400.php'; 88 | http_response_code(400); 89 | exit; 90 | } 91 | 92 | return $theme; 93 | } 94 | 95 | /** 96 | * activate a new theme 97 | */ 98 | function theme_activate() 99 | { 100 | 101 | $theme = $this->theme_validator(); 102 | $db = $this->get_dbo(); 103 | $sql = "UPDATE `site_option` SET `option_value` = ? WHERE option_name = 'theme'"; 104 | if ($db->prepare($sql, array($theme))->rowCount()) { 105 | $_SESSION['success'] = 'theme is updated'; 106 | $this->redirect($this->to_url('theme-settings')); 107 | } 108 | $_SESSION['error'] = 'theme could not be updated'; 109 | $this->redirect($this->to_url('theme-settings')); 110 | } 111 | 112 | /** 113 | * live preview of theme 114 | */ 115 | function preview() 116 | { 117 | if (!isset($_GET['theme']) || empty($_GET['theme']) || !isset($_GET['url'])) { 118 | require TEMPLATE_PATH . '/400.php'; 119 | http_response_code(400); 120 | exit; 121 | } 122 | 123 | $theme = $_GET['theme']; 124 | $url = $_GET['url']; 125 | $this->redirect($url . '?preview=true&theme=' . $theme); 126 | } 127 | 128 | /** 129 | * display list of all users 130 | */ 131 | function admin_user_list() 132 | { 133 | $db = $this->get_dbo(); 134 | $sql = "SELECT * FROM `users`"; 135 | $users = $db->load_result($sql, array()); 136 | if ($users) { 137 | include(TEMPLATE_PATH . 'admin/users_list.php'); 138 | } else { 139 | $_SESSION['error'] = 'database connection error'; 140 | $this->redirect($this->to_url('admin-home')); 141 | } 142 | } 143 | 144 | /** 145 | * send edit user form 146 | * only admin restrict function 147 | */ 148 | function admin_edit_user($args) 149 | { 150 | $this->admin_required(); 151 | $id = $args['id']; 152 | $db = $this->get_dbo(); 153 | $sql = "SELECT * FROM `users` WHERE id= ?"; 154 | $user = $db->load_single_result($sql, array($id)); 155 | if ($user) { 156 | include(TEMPLATE_PATH . 'admin/user_edit.php'); 157 | } else { 158 | $_SESSION['error'] = 'database connection error'; 159 | $this->redirect($this->to_url('admin-home')); 160 | } 161 | } 162 | 163 | /** 164 | * if password is updated by admin 165 | */ 166 | private function handle_password($id, $password1, $password2) 167 | { 168 | if ($password2 != $password1) { 169 | $_SESSION['error'] = 'passwords do not match'; 170 | $this->redirect($this->to_url('admin-edit-user', ['id' => $id])); 171 | } 172 | 173 | $password = crypt($password1, sprintf('$6$rounds=%d$%s$', 10000, SECRET)); 174 | return $password; 175 | } 176 | 177 | /** 178 | * update an user 179 | */ 180 | function admin_update_user($args) 181 | { 182 | $this->admin_required(); 183 | $id = $args['id']; 184 | 185 | if (!isset($_POST['email']) || !isset($_POST['role'])) { 186 | $_SESSION['error'] = 'fill required fields'; 187 | $this->redirect($this->to_url('admin-edit-user', ['id' => $id])); 188 | } 189 | 190 | $email = $_POST['email']; 191 | if (!isset($_POST['is_active'])) 192 | $is_active = 1; 193 | else 194 | $is_active = 0; 195 | 196 | $role = $_POST['role']; 197 | $password = null; 198 | 199 | if (isset($_POST['password1']) || isset($_POST['password2'])) { 200 | $password = $this->handle_password($id, $_POST['password1'], $_POST['password2']); 201 | } 202 | 203 | if ($password) { 204 | $sql = "UPDATE `users` as user SET user.email=?,user.role=?,user.is_active=?,user.password=? WHERE user.id= ?"; 205 | $parms = [$email, $role, $is_active, $password, $id]; 206 | } else { 207 | $sql = "UPDATE `users` as user SET user.email=?,user.role=?,user.is_active=? WHERE user.id= ?"; 208 | $parms = [$email, $role, $is_active, $id]; 209 | } 210 | 211 | $db = $this->get_dbo(); 212 | $query = $db->prepare($sql, $parms); 213 | if ($query) { 214 | $_SESSION['success'] = 'User updated'; 215 | $this->redirect($this->to_url('admin-edit-user', ['id' => $id])); 216 | } else { 217 | $_SESSION['error'] = 'database connection error'; 218 | $this->redirect($this->to_url('admin-edit-user', ['id' => $id])); 219 | } 220 | } 221 | 222 | /** 223 | * delete an user 224 | */ 225 | function admin_delete_user($args) 226 | { 227 | $this->admin_required(); 228 | $id = $args['id']; 229 | $parms = [$id]; 230 | 231 | $db = $this->get_dbo(); 232 | $sql = "DELETE FROM `users` WHERE id=?"; 233 | $query = $db->prepare($sql, $parms); 234 | if ($query->rowCount !== 0) { 235 | $_SESSION['success'] = 'User deleted successfully'; 236 | $this->redirect($this->to_url('admin-user-list', ['id' => $id])); 237 | } else { 238 | $_SESSION['error'] = 'Database connection error'; 239 | $this->redirect($this->to_url('admin-user-list', ['id' => $id])); 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /applications/admin/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/applications/admin/index.php -------------------------------------------------------------------------------- /applications/admin/routes.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'name' => 'admin-home', 6 | 'control' => 'admin@index', 7 | 'allow' => ['GET', 'POST'] 8 | ], 9 | 10 | 'admin/theme' => [ 11 | 'name' => 'theme-settings', 12 | 'control' => 'admin@theme_list', 13 | 'allow' => ['GET'] 14 | ], 15 | 16 | 'admin/theme/activate' => [ 17 | 'name' => 'theme-activate', 18 | 'control' => 'admin@theme_activate', 19 | 'allow' => ['POST'] 20 | ], 21 | 22 | 'admin/theme/preview' => [ 23 | 'name' => 'live-preview', 24 | 'control' => 'admin@preview', 25 | 'allow' => ['GET', 'POST'] 26 | ], 27 | /* 28 | these disable links are port for next versionq 29 | 30 | 'admin/widget' => [ 31 | 'name' => 'widget-settings', 32 | 'control' => 'admin@widgets_list', 33 | 'allow' => ['GET']], 34 | 35 | 'admin/widget/update' => [ 36 | 'name' => 'widgets-update', 37 | 'control' => 'admin@user_list', 38 | 'allow' => ['POST']], 39 | 40 | 'admin/menus' => [ 41 | 'name' => 'menu-list', 42 | 'control' =>'admin@menu_list', 43 | 'allow' => ['GET']], 44 | 45 | 'admin/menus/add' => [ 46 | 'name' => 'add-menu', 47 | 'control' =>'admin@add_menu', 48 | 'allow' => ['POST']], 49 | 50 | 'admin/menus/{id}[0-9]+' => [ 51 | 'name' => 'edit-menu', 52 | 'control' =>'admin@edit_menu', 53 | 'allow' => ['GET']], 54 | 55 | 'admin/menus/{id}[0-9]+/delete' => [ 56 | 'name' => 'delete-menu', 57 | 'control' =>'admin@delete_menu', 58 | 'allow' => ['POST']], 59 | 60 | 'admin/menus/manage' => [ 61 | 'name' => 'manage-menu-list', 62 | 'control' =>'admin@manage_menu_list', 63 | 'allow' => ['GET']], 64 | 65 | 'admin/menus/manage/update' => [ 66 | 'name' => 'manage-menu', 67 | 'control' =>'admin@manage_menu', 68 | 'allow' => ['POST']], 69 | 70 | 'admin/users/new' => [ 71 | 'name' => 'admin-new-user', 72 | 'control' =>'admin@admin_new_user', 73 | 'allow' => ['GET']], 74 | 75 | 'admin/users/add' => [ 76 | 'name' => 'admin-add-user', 77 | 'control' =>'admin@admin_add_user', 78 | 'allow' => ['POST']], 79 | 80 | */ 81 | 82 | 'admin/users' => [ 83 | 'name' => 'admin-user-list', 84 | 'control' => 'admin@admin_user_list', 85 | 'allow' => ['GET'] 86 | ], 87 | 88 | 'admin/user/{id}[0-9]+/edit' => [ 89 | 'name' => 'admin-edit-user', 90 | 'control' => 'admin@admin_edit_user', 91 | 'allow' => ['GET'] 92 | ], 93 | 94 | 'admin/user/{id}[0-9]+/update' => [ 95 | 'name' => 'admin-update-user', 96 | 'control' => 'admin@admin_update_user', 97 | 'allow' => ['POST'] 98 | ], 99 | 100 | 'admin/user/{id}[0-9]+/delete' => [ 101 | 'name' => 'admin-delete-user', 102 | 'control' => 'admin@admin_delete_user', 103 | 'allow' => ['POST'] 104 | ], 105 | ]; 106 | -------------------------------------------------------------------------------- /applications/auth/auth.php: -------------------------------------------------------------------------------- 1 | login, logout, register, reset-password, send verification email 10 | */ 11 | 12 | require_once('includes/Application.php'); 13 | 14 | class AuthApplication extends Application 15 | { 16 | 17 | /** 18 | * default function that will run if no operation is choosen 19 | */ 20 | function display() 21 | { 22 | //check if any session exists otherwise login 23 | $this->check_login($this->to_url('login-form')); 24 | } 25 | 26 | /** 27 | * verify if any session exists 28 | * @param string $url 29 | */ 30 | private function check_login($url = null) 31 | { 32 | if (isset($_SESSION['user_session'])) { 33 | $this->redirect(); 34 | } 35 | if ($url !== null) { 36 | $this->redirect($url); 37 | } 38 | } 39 | 40 | /** 41 | * return authentication form 42 | */ 43 | function login_form() 44 | { 45 | $this->check_login(); 46 | require_once(TEMPLATE_PATH . 'auth/auth.php'); 47 | } 48 | 49 | /** 50 | * login user 51 | * @param string $email 52 | * @param string $password 53 | * @return redirect 54 | */ 55 | private function login($email, $password) 56 | { 57 | $db = $this->get_dbo(); 58 | $email = $db->quote($email); 59 | $password = crypt($password, sprintf('$6$rounds=%d$%s$', 10000, SECRET)); 60 | 61 | $sql = "SELECT * FROM `users` WHERE email=? AND password=? AND is_active = 1"; 62 | $query = $db->load_single_result($sql, array($email, $password)); 63 | 64 | if (isset($query['id'])) { 65 | $_SESSION['user_session'] = $query; 66 | 67 | if (isset($_SESSION['user_session'])) { 68 | $this->redirect(); 69 | } else { 70 | $_SESSION['l_error'] = 'Email and password do not match'; 71 | $this->redirect($this->to_url('login-form')); 72 | } 73 | } else { 74 | $_SESSION['l_error'] = 'Email and password do not match'; 75 | $this->redirect($this->to_url('login-form')); 76 | } 77 | 78 | $this->redirect(); 79 | } 80 | 81 | /** 82 | * take login credentials from user 83 | * pass credentials to login function 84 | */ 85 | function login_user() 86 | { 87 | $this->check_login(); 88 | $email = $_POST['login-email']; 89 | $password = $_POST['password']; 90 | $this->login($email, $password); 91 | } 92 | 93 | /** 94 | * logout the user 95 | */ 96 | private function logout() 97 | { 98 | if (isset($_SESSION['user_session']) && $_SESSION['user_session']) { 99 | session_destroy(); 100 | } 101 | $this->redirect($this->to_url('login-form')); 102 | } 103 | 104 | /** 105 | * logout a user 106 | */ 107 | function logout_user() 108 | { 109 | $this->logout(); 110 | } 111 | 112 | /** 113 | * returns user information 114 | * @param string $email 115 | * @return query $query 116 | */ 117 | private function get_user_info($email) 118 | { 119 | $db = $this->get_dbo(); 120 | $query = $db->load_single_result("SELECT * FROM users WHERE email = ?", array($email)); 121 | return $query; 122 | } 123 | 124 | /** 125 | * send error if any exists during registeration 126 | * @param staring $error_code 127 | * @return redirect 128 | */ 129 | private function error_info($error_code = null) 130 | { 131 | switch ($error_code) { 132 | case 'incomplete': 133 | $error = 'All fields are required'; 134 | break; 135 | case 'passmismatch': 136 | $error = 'Passwords do not match'; 137 | break; 138 | case 'alreadyexist': 139 | $error = 'Email already exists'; 140 | break; 141 | case 'loginfail': 142 | $error = 'Email and password do not match'; 143 | break; 144 | case 'min_lenght_error': 145 | $error = 'minimum 8 character password required'; 146 | break; 147 | default: 148 | $error = 'Some error occurred'; 149 | break; 150 | } 151 | 152 | $_SESSION['error'] = $error; 153 | $url = $this->to_url('signup-form'); 154 | $this->redirect($url); 155 | } 156 | 157 | /** 158 | * register new user 159 | * @param string $email 160 | * @param string $password 161 | * @return int $count 162 | */ 163 | private function register($email, $password) 164 | { 165 | $db = $this->get_dbo(); 166 | $eml = $db->quote($email); 167 | if ($this->get_user_info($eml)) { 168 | $this->error_info('alreadyexist'); 169 | } 170 | $password = crypt($password, sprintf('$6$rounds=%d$%s$', 10000, SECRET)); 171 | $code = hash('sha512', 'register' . $email . '' . time()); 172 | $created_at = new DateTime(); 173 | $created_at = $created_at->format('Y-m-d H:i:s'); 174 | $updated_at = new DateTime(); 175 | $updated_at = $updated_at->format('Y-m-d H:i:s'); 176 | 177 | $sql = "INSERT INTO `users` (email,password,confirm_code,created_at,updated_at) VALUES(?,?,?,?,?)"; 178 | $query = $db->prepare($sql, array($eml, $password, $code, $created_at, $updated_at)); 179 | $count = $query->rowCount(); 180 | if ($count) { 181 | $this->send_register_email($email, $code); 182 | } 183 | return $count; 184 | } 185 | 186 | /** 187 | * prepare verification email for registering user 188 | * @param string $title 189 | * @param string $link 190 | * @param string $message 191 | * @return string(html) $body 192 | */ 193 | private function email_message($title, $link, $message) 194 | { 195 | return " 196 |
197 |Click on the link " . $message . ">
199 | 200 | 201 | It is auto generated message. Don't reply for this message. Only click on the links. 202 | 203 | "; 204 | } 205 | 206 | /** 207 | * send email to registered user 208 | * config your init.php for working this function 209 | * @param string $email 210 | * @param string $code 211 | */ 212 | private function send_register_email($email, $code) 213 | { 214 | $subject = "My to do email register"; 215 | //put domain name instead of localhost 216 | $link = $this->to_url('verify-email', ['code' => $code, 'email' => $email]); 217 | $title = 'Confirm email for registeration'; 218 | $message = 'Confirm Email'; 219 | $txt = $this->email_message($title, $link, $message); 220 | $headers = "MIME-Version: 1.0" . "\r\n"; 221 | $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n"; 222 | // $headers .= "From: webmaster@example.com"; 223 | 224 | mail($email, $subject, $txt, $headers); 225 | } 226 | 227 | /** 228 | * take registeration credentials from user 229 | */ 230 | function register_user() 231 | { 232 | $this->check_login(); 233 | $email = $_POST['email']; 234 | $pass1 = $_POST['password1']; 235 | $pass2 = $_POST['password2']; 236 | if (!isset($email) or !isset($pass1) or !isset($pass2)) { 237 | $this->error_info('incomplete'); 238 | } 239 | 240 | if ($pass1 !== $pass2) { 241 | $this->error_info('passmismatch'); 242 | } 243 | 244 | if (strlen($pass1) < 8) { 245 | $this->error_info('min_lenght_error'); 246 | } 247 | 248 | if ($this->register($email, $pass1)) { 249 | $message = 'You have register succesfully. Now open your email id and click on the confirmation link'; 250 | $heading = 'Success'; 251 | require(TEMPLATE_PATH . 'auth/message.php'); 252 | } else { 253 | $this->error_info(); 254 | } 255 | } 256 | 257 | /** 258 | * match the confirmation code in link for verifying registered email 259 | * @param array $args 260 | * @param string $args['code'] 261 | * @param staring $args['email'] 262 | */ 263 | function verify_email($args) 264 | { 265 | $this->check_login(); 266 | if (!isset($args['code']) or !isset($args['email'])) { 267 | $this->redirect(); 268 | } 269 | 270 | $code = $args['code']; 271 | $email = $args['email']; 272 | $db = $this->get_dbo(); 273 | $email = $db->quote($email); 274 | $data = $this->get_user_info($email); 275 | $query = null; 276 | if ($data['confirm_code'] == $code && $code != '0') { 277 | $updated_at = new DateTime(); 278 | $updated_at = $updated_at->format('Y-m-d H:i:s'); 279 | $sql = "UPDATE `users` as user SET user.is_active='1', user.confirm_code='0', user.updated_at=? WHERE user.email= ?"; 280 | $query = $db->prepare($sql, array($updated_at, $email)); 281 | } else { 282 | $this->redirect(); 283 | } 284 | 285 | if ($query->rowCount()) { 286 | $_SESSION['user_session'] = $data; 287 | } 288 | $this->redirect(); 289 | } 290 | 291 | /** 292 | * return reset password form 293 | * @return HTMLResponse 294 | */ 295 | function forget_password() 296 | { 297 | $this->check_login(); 298 | if (!isset($_POST['forget-email'])) { 299 | $this->redirect(); 300 | } 301 | 302 | $email = $_POST['forget-email']; 303 | $code = hash('sha512', 'forget$kfsdgf8dsfds' . $email . '' . time()); 304 | $db = $this->get_dbo(); 305 | $eml = $db->quote($email); 306 | $updated_at = new DateTime(); 307 | $updated_at = $updated_at->format('Y-m-d H:i:s'); 308 | $sql = "UPDATE `users` SET confirm_code= '$code', updated_at=? WHERE email= ?"; 309 | $query = $db->prepare($sql, array($updated_at, $eml)); 310 | if ($query->rowCount()) { 311 | $this->send_reset_email($code, $email); 312 | $message = 'Your reset password information has been sent to your email address.'; 313 | $heading = 'Success'; 314 | } else { 315 | $message = 'You have provide invalid email address'; 316 | $heading = 'Error'; 317 | } 318 | require(TEMPLATE_PATH . 'auth/message.php'); 319 | } 320 | 321 | /** 322 | * emails reset password link 323 | * @param string $code 324 | * @param string $email 325 | */ 326 | private function send_reset_email($code, $email) 327 | { 328 | $subject = "My to do password reset"; 329 | //put domain name instead of localhost 330 | $link = $this->to_url('reset-password', ['code' => $code, 'email' => $email]); 331 | $title = 'Reset Password'; 332 | $message = "confirm reset Password"; 333 | $txt = $this->email_message($title, $link, $message); 334 | $headers = "From: webmaster@example.com" . "\r\n" . 335 | "CC: somebodyelse@example.com"; 336 | 337 | mail($email, $subject, $txt, $headers); 338 | } 339 | 340 | /** 341 | * send reset password form 342 | * @param array $args 343 | * @param string $args['code'] 344 | * @param string $args['email'] 345 | */ 346 | function reset_password_form($args) 347 | { 348 | $this->check_login(); 349 | if (!isset($args['code']) or !isset($args['email'])) { 350 | $this->redirect(); 351 | } 352 | 353 | $code = $args['code']; 354 | $email = $args['email']; 355 | $db = $this->get_dbo(); 356 | $email = $db->quote($email); 357 | $data = $this->get_user_info($email); 358 | 359 | if ($data['confirm_code'] !== $code || $code == '0') { 360 | $this->redirect(); 361 | } 362 | 363 | require(TEMPLATE_PATH . 'auth/resetpassword.php'); 364 | } 365 | 366 | /** 367 | * reset user password 368 | * @return HTMLResponse 369 | */ 370 | function reset_password() 371 | { 372 | $this->check_login(); 373 | if (!isset($_POST['i']) or !isset($_POST['e']) or !isset($_POST['pass1']) or !isset($_POST['pass2'])) { 374 | header('HTTP/1.1 403 Forbidden'); 375 | $heading = 'forbidden request!'; 376 | $message = 'all fields are required. Try again by clicking on link in email.'; 377 | require(TEMPLATE_PATH . 'auth/message.php'); 378 | exit(); 379 | } 380 | 381 | $pass1 = $_POST['pass1']; 382 | $pass2 = $_POST['pass2']; 383 | $email = $_POST['e']; 384 | $code = $_POST['i']; 385 | 386 | if ($pass2 !== $pass1) { 387 | $error = 'password mismatch'; 388 | require(TEMPLATE_PATH . 'auth/resetpassword.php'); 389 | exit(); 390 | } 391 | 392 | $db = $this->get_dbo(); 393 | $eml = $db->quote($email); 394 | $data = $this->get_user_info($eml); 395 | $query = null; 396 | 397 | if ($data['confirm_code'] == $code && $code != '0') { 398 | $updated_at = new DateTime(); 399 | $updated_at = $updated_at->format('Y-m-d H:i:s'); 400 | $sql = "UPDATE `users` as user SET user.confirm_code='0', user.updated_at=? WHERE user.email= ?"; 401 | $query = $db->prepare($sql, array($updated_at, $eml)); 402 | } else { 403 | header('HTTP/1.1 403 Forbidden'); 404 | $heading = 'forbidden request!'; 405 | $message = 'Validation error. Try again by clicking on link in email.'; 406 | require(TEMPLATE_PATH . 'auth/message.php'); 407 | exit(); 408 | } 409 | 410 | if ($query and $query->rowCount()) { 411 | $pass1 = crypt($pass1, sprintf('$6$rounds=%d$%s$', 10000, SECRET)); 412 | $db = $this->get_dbo(); 413 | $eml = $db->quote($email); 414 | $updated_at = new DateTime(); 415 | $updated_at = $updated_at->format('Y-m-d H:i:s'); 416 | $sql = "UPDATE `users` SET confirm_code= '0', password = ?, updated_at=? WHERE email= ?"; 417 | $query = $db->prepare($sql, array($pass1, $eml, $updated_at)); 418 | if ($query->rowCount()) { 419 | $message = 'Your reset password has been reseted.'; 420 | $heading = 'Success'; 421 | } else { 422 | $message = 'You have provide invalid data'; 423 | $heading = 'Error'; 424 | } 425 | } else { 426 | $message = 'You have provide invalid data'; 427 | $heading = 'Error'; 428 | } 429 | require(TEMPLATE_PATH . 'auth/message.php'); 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /applications/auth/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/applications/auth/index.php -------------------------------------------------------------------------------- /applications/auth/routes.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'name' => 'login-form', 6 | 'control' => 'auth@login_form', 7 | 'allow' => ['GET', 'POST'] 8 | ], 9 | 10 | 'auth/login-form\#signup' => [ 11 | 'name' => 'signup-form', 12 | 'control' => 'auth@login_form', 13 | 'allow' => ['GET', 'POST'] 14 | ], 15 | 16 | 'auth/login' => [ 17 | 'name' => 'login', 18 | 'control' => 'auth@login_user', 19 | 'allow' => ['POST'] 20 | ], 21 | 22 | 'auth/register' => [ 23 | 'name' => 'register', 24 | 'control' => 'auth@register_user', 25 | 'allow' => ['POST'] 26 | ], 27 | 28 | 'auth/verify-email/{code}[0-9a-z]+/{email}[0-9a-zA-Z\.@]+' => [ 29 | 'name' => 'verify-email', 30 | 'control' => 'auth@verify_email', 31 | 'allow' => ['GET'] 32 | ], 33 | 34 | 'auth/forget-password' => [ 35 | 'name' => 'forget-password', 36 | 'control' => 'auth@forget_password', 37 | 'allow' => ['POST'] 38 | ], 39 | 40 | 'auth/reset' => [ 41 | 'name' => 'reset', 42 | 'control' => 'auth@reset_password', 43 | 'allow' => ['POST'] 44 | ], 45 | 46 | 'auth/reset-password/{code}[0-9a-z]+/{email}[0-9a-zA-Z\.@]+' => [ 47 | 'name' => 'reset-password', 48 | 'control' => 'auth@reset_password_form', 49 | 'allow' => ['GET'] 50 | ], 51 | 52 | 'auth/logout' => [ 53 | 'name' => 'logout', 54 | 'control' => 'auth@logout_user', 55 | 'allow' => ['GET'] 56 | ], 57 | ]; 58 | -------------------------------------------------------------------------------- /applications/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/applications/index.php -------------------------------------------------------------------------------- /applications/todo/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/applications/todo/index.php -------------------------------------------------------------------------------- /applications/todo/routes.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'name' => 'home', 6 | 'control' => 'todo@index', 7 | 'allow' => ['GET',] 8 | ], 9 | 'todo' => [ 10 | 'name' => 'todo-home', 11 | 'control' => 'todo@index', 12 | 'allow' => ['GET',] 13 | ], 14 | 15 | 'todo/new' => [ 16 | 'name' => 'new-todo', 17 | 'control' => 'todo@add', 18 | 'allow' => ['GET',] 19 | ], 20 | 21 | 'todo/add' => [ 22 | 'name' => 'add-todo', 23 | 'control' => 'todo@create', 24 | 'allow' => ['POST'] 25 | ], 26 | 27 | 'todo/edit/{id}[0-9]+' => [ 28 | 'name' => 'edit-todo', 29 | 'control' => 'todo@edit', 30 | 'allow' => ['GET'] 31 | ], 32 | 33 | 'todo/update' => [ 34 | 'name' => 'update-todo', 35 | 'control' => 'todo@update', 36 | 'allow' => ['POST'] 37 | ], 38 | 39 | 'todo/delete/{id}[0-9]+' => [ 40 | 'name' => 'delete-todo', 41 | 'control' => 'todo@destroy', 42 | 'allow' => ['POST'] 43 | ], 44 | 45 | 'todo/list' => [ 46 | 'name' => 'todo-list', 47 | 'control' => 'todo@index', 48 | 'allow' => ['GET'] 49 | ], 50 | 51 | 'todo/list/{label}[a-z]+' => [ 52 | 'name' => 'todo-label', 53 | 'control' => 'todo@index', 54 | 'allow' => ['GET'] 55 | ], 56 | 57 | 'todo/show/{id}[0-9]+' => [ 58 | 'name' => 'show-todo', 59 | 'control' => 'todo@show', 60 | 'allow' => ['GET'] 61 | ], 62 | ]; 63 | -------------------------------------------------------------------------------- /applications/todo/todo.php: -------------------------------------------------------------------------------- 1 | login_required(); 19 | } 20 | 21 | /** 22 | * display list of all todos 23 | */ 24 | function display() 25 | { 26 | $this->index(); 27 | } 28 | 29 | /** 30 | * calculate time left for listed todo tasks 31 | * @param date $end_date 32 | * @return string $time_left 33 | */ 34 | private function time_left($end_date) 35 | { 36 | $today = strtotime("now"); 37 | $due_date = strtotime($end_date); 38 | if($due_date>$today) 39 | { 40 | $hours = $due_date - $today; 41 | $hours = $hours/3600; 42 | $time_left = $hours/24; 43 | 44 | if($time_left < 1) 45 | { 46 | $time_left = 'Less than 1 day'; 47 | } 48 | else 49 | { 50 | $time_left = round($time_left).' days'; 51 | } 52 | } 53 | else 54 | { 55 | $time_left = 'Expired'; 56 | } 57 | 58 | return $time_left; 59 | } 60 | 61 | /** 62 | * show the list of listed todos 63 | * @param array $args 64 | * @param string $args['label'] 65 | * @return HttpResponse 66 | */ 67 | function index($args= null) 68 | { 69 | $label = isset($args['label']) ? $args['label']:'all'; 70 | $user_id = $_SESSION['user_session']['id']; 71 | $db=$this->get_dbo(); 72 | if($label == 'all') 73 | { 74 | $sql="SELECT * FROM `todolist` WHERE user_id=?"; 75 | $args = array($user_id); 76 | } 77 | else 78 | { 79 | $sql="SELECT * FROM `todolist` WHERE label=? AND user_id=? "; 80 | $args = array($label,$user_id); 81 | } 82 | $rows=$db->load_result($sql,$args); 83 | // include view todo list 84 | include_once(TEMPLATE_PATH.'/todo/index.php'); 85 | } 86 | 87 | /** 88 | * form for adding a new todo 89 | * @return HttpResponse 90 | */ 91 | function add() 92 | { 93 | include_once(TEMPLATE_PATH.'/todo/new.php'); 94 | } 95 | 96 | /** 97 | * add a new todo task 98 | * @return redirect 99 | */ 100 | function create() 101 | { 102 | 103 | $title= filter_input(INPUT_POST, 'title', FILTER_SANITIZE_SPECIAL_CHARS); 104 | $desc= filter_input(INPUT_POST, 'desc', FILTER_SANITIZE_SPECIAL_CHARS); 105 | $end_date= filter_input(INPUT_POST, 'end_date', FILTER_SANITIZE_SPECIAL_CHARS); 106 | $label= filter_input(INPUT_POST, 'label', FILTER_SANITIZE_SPECIAL_CHARS); 107 | $start_date = date("Y-m-d"); 108 | $sql="INSERT INTO `todolist` VALUES(?,?,?,?,?,?,?,?)"; 109 | $user_id = $_SESSION['user_session']['id']; 110 | $args = array(NULL,$title,$desc,0,$start_date,$end_date,$label,$user_id); 111 | $db=$this->get_dbo(); 112 | if($db->prepare($sql,$args)) 113 | { 114 | $this->redirect($this->to_url('todo-home')); 115 | } 116 | else 117 | { 118 | $this->redirect(); 119 | } 120 | 121 | } 122 | 123 | /** 124 | * form for editing a todo entry 125 | * @param array $args 126 | * @param string $args['id'] 127 | * @return HttpResponse 128 | */ 129 | function edit($args) 130 | { 131 | $id=$args['id']; 132 | $user_id = $_SESSION['user_session']['id']; 133 | $sql="SELECT * FROM `todolist` WHERE id=? AND user_id=?"; 134 | $db=$this->get_dbo(); 135 | $row=$db->load_single_result($sql,array($id,$user_id)); 136 | include_once(TEMPLATE_PATH.'/todo/edit.php'); 137 | } 138 | 139 | /** 140 | * edit an existing todo 141 | * @return redirect 142 | */ 143 | function update() 144 | { 145 | $id= filter_input(INPUT_POST, 'id', FILTER_SANITIZE_SPECIAL_CHARS); 146 | $title= filter_input(INPUT_POST, 'title', FILTER_SANITIZE_SPECIAL_CHARS); 147 | $desc= filter_input(INPUT_POST, 'desc', FILTER_SANITIZE_SPECIAL_CHARS); 148 | $end_date= filter_input(INPUT_POST, 'end_date', FILTER_SANITIZE_SPECIAL_CHARS); 149 | $label= filter_input(INPUT_POST, 'label', FILTER_SANITIZE_SPECIAL_CHARS); 150 | $progress = $_POST['progress']; 151 | $user_id = $_SESSION['user_session']['id']; 152 | $sql="UPDATE `todolist` as tasks SET tasks.title=?,tasks.desc=?, tasks.progress=?, tasks.end_date=?, tasks.label=? WHERE id=? AND user_id =?"; 153 | $db=$this->get_dbo(); 154 | if($db->prepare($sql,array($title,$desc,$progress,$end_date,$label,$id,$user_id))) 155 | { 156 | $this->redirect($this->to_url('todo-home')); 157 | } 158 | else 159 | { 160 | $this->redirect(); 161 | } 162 | } 163 | 164 | /** 165 | * show discription of todo 166 | * @param array $args 167 | * @param string $args['id'] 168 | * @return HttpResponse 169 | */ 170 | function show($args = null) 171 | { 172 | $id = $args['id']; 173 | $user_id = $_SESSION['user_session']['id']; 174 | $sql="SELECT * FROM `todolist` WHERE id=? AND user_id=?"; 175 | $args = array($id,$user_id); 176 | $db=$this->get_dbo(); 177 | $row=$db->load_single_result($sql,$args); 178 | // include view todo list 179 | include_once(TEMPLATE_PATH.'/todo/show.php'); 180 | } 181 | 182 | /** 183 | * delete an existing task 184 | * @param array $args 185 | * @param string $args['id'] 186 | * @return redirect 187 | */ 188 | function destroy($args) 189 | { 190 | $id=$args['id']; 191 | $user_id = $_SESSION['user_session']['id']; 192 | $db=$this->get_dbo(); 193 | $sql="DELETE FROM `todolist` WHERE id=? AND user_id =?"; 194 | if($db->prepare($sql,array($id,$user_id))->rowCount()!==0) 195 | { 196 | $_SESSION['success'] = 'deleted successfully'.$id; 197 | $this->redirect($this->to_url('todo-home')); 198 | } 199 | $_SESSION['error'] = 'could not deleted successfully'; 200 | $this->redirect($this->to_url('todo-home')); 201 | } 202 | 203 | 204 | } 205 | -------------------------------------------------------------------------------- /assets/js/preview.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | var links = $('body a[href]'); 3 | $.each(links,function preview_function(key,link){ 4 | console.log(link); 5 | if(link.href.indexOf('?') > -1) 6 | { 7 | link.href = link.href+"&preview=true&theme=default"; 8 | } 9 | else 10 | link.href = link.href+"?preview=true&theme=default"; 11 | }); 12 | }); -------------------------------------------------------------------------------- /cms_todo.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.2.12deb2 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: Jul 10, 2015 at 07:42 PM 7 | -- Server version: 5.5.43-0+deb7u1 8 | -- PHP Version: 5.6.7-1 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8 */; 18 | 19 | -- 20 | -- Database: `cms_todo` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- Table structure for table `site_option` 27 | -- 28 | 29 | CREATE TABLE IF NOT EXISTS `site_option` ( 30 | `id` int(11) NOT NULL, 31 | `option_name` varchar(250) NOT NULL, 32 | `option_value` varchar(250) NOT NULL 33 | ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; 34 | 35 | -- 36 | -- Dumping data for table `site_option` 37 | -- 38 | 39 | INSERT INTO `site_option` (`id`, `option_name`, `option_value`) VALUES 40 | (1, 'theme', 'fixed_top'); 41 | 42 | -- -------------------------------------------------------- 43 | 44 | -- 45 | -- Table structure for table `todolist` 46 | -- 47 | 48 | CREATE TABLE IF NOT EXISTS `todolist` ( 49 | `id` int(11) NOT NULL, 50 | `title` varchar(255) NOT NULL, 51 | `desc` text NOT NULL, 52 | `progress` smallint(3) NOT NULL DEFAULT '0', 53 | `start_date` date NOT NULL, 54 | `end_date` date NOT NULL, 55 | `label` varchar(50) NOT NULL, 56 | `user_id` bigint(20) NOT NULL 57 | ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; 58 | 59 | 60 | -- -------------------------------------------------------- 61 | 62 | -- 63 | -- Table structure for table `users` 64 | -- 65 | 66 | CREATE TABLE IF NOT EXISTS `users` ( 67 | `id` bigint(20) NOT NULL, 68 | `email` varchar(60) NOT NULL, 69 | `password` varchar(256) NOT NULL, 70 | `confirm_code` varchar(256) NOT NULL DEFAULT '0', 71 | `is_active` tinyint(1) NOT NULL DEFAULT '0', 72 | `role` enum('admin','demo_checker','user') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'demo_checker', 73 | `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 74 | `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' 75 | ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; 76 | 77 | -- 78 | -- Indexes for dumped tables 79 | -- 80 | 81 | -- 82 | -- Indexes for table `option` 83 | -- 84 | ALTER TABLE `site_option` 85 | ADD PRIMARY KEY (`id`); 86 | 87 | -- 88 | -- Indexes for table `todolist` 89 | -- 90 | ALTER TABLE `todolist` 91 | ADD PRIMARY KEY (`id`); 92 | 93 | -- 94 | -- Indexes for table `users` 95 | -- 96 | ALTER TABLE `users` 97 | ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `email` (`email`); 98 | 99 | -- 100 | -- AUTO_INCREMENT for dumped tables 101 | -- 102 | 103 | -- 104 | -- AUTO_INCREMENT for table `option` 105 | -- 106 | ALTER TABLE `site_option` 107 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1; 108 | -- 109 | -- AUTO_INCREMENT for table `todolist` 110 | -- 111 | ALTER TABLE `todolist` 112 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1; 113 | -- 114 | -- AUTO_INCREMENT for table `users` 115 | -- 116 | ALTER TABLE `users` 117 | MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1; 118 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 119 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 120 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 121 | -------------------------------------------------------------------------------- /config.example.php: -------------------------------------------------------------------------------- 1 | 'mysql', 8 | 9 | // config database connections 10 | 'connection' => [ 11 | 'mysql' => [ 12 | 'driver' => 'mysql', 13 | 'host' => 'your host', 14 | 'database' => 'your database name', 15 | 'username' => 'your username', 16 | 'password' => 'your password', 17 | ], 18 | ], 19 | 20 | // set the location of application withour trailing slash 21 | 'root' => '', // example 'http://localhost/todolist' or http://demo.findalltogeher.com 22 | 23 | // register apps 24 | 'apps' => [ 25 | 'auth', 26 | 'todo', 27 | 'admin', 28 | ], 29 | 30 | // secret string for encreption 31 | 'secret' => 'this_is_secret_string', // example 'fa&k+j@sdf!has^dh-iu!d#dh$sd' 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /includes/Application.php: -------------------------------------------------------------------------------- 1 | $method($args); 23 | } else { 24 | $this->$method(); 25 | } 26 | } 27 | 28 | /** 29 | * default response to user for any request 30 | * 31 | */ 32 | abstract function display(); 33 | 34 | /** 35 | * redirect function for application 36 | */ 37 | protected function redirect($url = null, $msg = null) 38 | { 39 | if (empty($url)) { 40 | header('Location:' . ROOT); 41 | } else { 42 | header('Location:' . $url); 43 | } 44 | exit(0); 45 | } 46 | 47 | /** 48 | * protect application with logged in required layer 49 | */ 50 | protected function login_required() 51 | { 52 | if (!isset($_SESSION['user_session'])) { 53 | $this->redirect($this->to_url('login-form')); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /includes/Base.php: -------------------------------------------------------------------------------- 1 | load_routes(); 60 | } 61 | return $routes; 62 | } 63 | 64 | /** 65 | * it is used for named urls 66 | * @param string $name 67 | * @param array $args 68 | * @return string url 69 | */ 70 | protected function to_url($name, $args = null) 71 | { 72 | $r = $this->get_routes(); 73 | if ($args !== null) 74 | return $r->to_route($name, $args); 75 | else 76 | return $r->to_route($name); 77 | } 78 | 79 | /** 80 | * abatract function run for executing applicaiton 81 | */ 82 | abstract function run($arg = null, $param = null); 83 | } 84 | -------------------------------------------------------------------------------- /includes/TemplateFunctions.php: -------------------------------------------------------------------------------- 1 | template_name == null) { 28 | $this->template_name = $this->get_current_template(); 29 | } 30 | } 31 | 32 | /** 33 | * run whole CMS and render generated html page 34 | */ 35 | function run($arg = null, $param = null) 36 | { 37 | require_once(TEMPLATE_PATH . 'functions.php'); 38 | require_once(TEMPLATE_PATH . 'index.php'); 39 | } 40 | 41 | /** 42 | * set a template 43 | */ 44 | function set_template($template_name) 45 | { 46 | $this->template_name = $template_name; 47 | } 48 | 49 | /** 50 | * get currently active template 51 | */ 52 | private function get_current_template() 53 | { 54 | if (isset($_GET['preview']) && isset($_GET['theme']) && $_SESSION['user_session']['role'] !== 'user') { 55 | define('PREVIEW', true); 56 | return $_GET['theme']; 57 | } 58 | 59 | $db = $this->get_dbo(); 60 | $sql = "SELECT `option_value` FROM `site_option` WHERE option_name = ?"; 61 | $template_name = $db->load_single_result($sql, array('theme')); 62 | 63 | if ($template_name) { 64 | return $template_name['option_value']; 65 | } 66 | 67 | return 'default'; 68 | } 69 | 70 | /** 71 | * return current theme name 72 | * @return string $this->template_name 73 | */ 74 | function get_current_theme() 75 | { 76 | return $this->template_name; 77 | } 78 | 79 | /** 80 | * return currently active template path 81 | * it is relative path to root index.php 82 | * @return string template_path 83 | */ 84 | function get_current_template_path() 85 | { 86 | return 'templates/' . $this->template_name . '/'; 87 | } 88 | 89 | /** 90 | * return static media path in template path 91 | * it is absolute path 92 | * @return string template_path 93 | */ 94 | function get_static_path() 95 | { 96 | return ROOT . '/' . TEMPLATE_PATH; 97 | } 98 | 99 | /** 100 | * action for app output 101 | * resoulve app name and requested function from url 102 | * then run application class for generating output 103 | */ 104 | function app_output() 105 | { 106 | // Route class instance 107 | $routes = $this->get_routes(); 108 | // fetch app and function name 109 | $destination = $routes->get_destination(); 110 | 111 | $app_name = explode('@', $destination['control']); 112 | 113 | require_once('applications/' . $app_name[0] . '/' . $app_name[0] . '.php'); 114 | $application = ucfirst($app_name[0]) . 'Application'; 115 | $app = new $application(); 116 | $app->run($app_name[1], $destination['args']); 117 | } 118 | 119 | /** 120 | * take output from widget 121 | */ 122 | function widget_output($position = 'default') 123 | { 124 | if (!empty($this->widget_positions[$position])) { 125 | //gets all widgets in given 126 | $widgets = $this->widget_positions[$position]; 127 | 128 | //display each widget 129 | foreach ($widgets as $widget_object) { 130 | $widget_name = $widget_object->name; 131 | $widget_parameters = $widget_object->parameters; 132 | require_once('widgets/' . $widget_name . '/' . $widget_name . '.php'); 133 | $widget_class = ucfirst($widget_name) . 'Widget'; 134 | $widget = new $widget_class(); 135 | $widget->run($widget_name, $widget_parameters); 136 | } 137 | } 138 | } 139 | 140 | /** 141 | * regiseter widgets for theme 142 | */ 143 | function set_widget($position, $widget_name, $params = array()) 144 | { 145 | $widget = new StdClass; 146 | $widget->name = $widget_name; 147 | $widget->parameters = $params; 148 | //if there is no widget in position then create a new array 149 | if (empty($this->widget_positions[$position])) { 150 | $this->widget_positions[$position] = array($widget); 151 | } 152 | //if there is already a widget present in that position then just push new widget in array 153 | else { 154 | array_push($this->widget_positions[$position], $widget); 155 | } 156 | } 157 | 158 | /** 159 | * return header.php file from current template 160 | */ 161 | function get_header() 162 | { 163 | require_once(TEMPLATE_PATH . 'header.php'); 164 | } 165 | 166 | /** 167 | * return footer.php file from current template 168 | */ 169 | function get_footer() 170 | { 171 | require_once(TEMPLATE_PATH . 'footer.php'); 172 | } 173 | 174 | /** 175 | * return sidebar.php file from current template 176 | */ 177 | function get_sidebar() 178 | { 179 | require_once(TEMPLATE_PATH . 'sidebar.php'); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /includes/Widget.php: -------------------------------------------------------------------------------- 1 | widget_path = 'widgets/' . $widget_name . '/'; 23 | $this->widget_name = $widget_name; 24 | } 25 | 26 | function get_widget_path() 27 | { 28 | return $this->widget_path; 29 | } 30 | 31 | abstract function display(); 32 | 33 | function run($widget_name = null, $params = null) // this function will be called by template function class to display widget 34 | { 35 | $this->parameters = $params; 36 | $this->set_widget_path($widget_name); 37 | $this->display(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /includes/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/includes/index.php -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | get_current_template_path()); 55 | define('STATIC_PATH', $tmpl->get_static_path()); 56 | define('THEME', $tmpl->get_current_theme()); 57 | 58 | $tmpl->run(); 59 | -------------------------------------------------------------------------------- /libraries/core/database/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/libraries/core/database/index.php -------------------------------------------------------------------------------- /libraries/core/database/mysql_database.php: -------------------------------------------------------------------------------- 1 | db_server = $server; 40 | $this->db_name = $db; 41 | $this->db_user = $user; 42 | $this->db_pass = $pass; 43 | } 44 | 45 | /** 46 | * connecting with a mysql database 47 | */ 48 | private function connect() 49 | { 50 | $info = 'mysql:host=' . $this->db_server . ';dbname=' . $this->db_name; 51 | try { 52 | $this->con = new PDO($info, $this->db_user, $this->db_pass); //data server connection 53 | } catch (PDOException $Exception) { 54 | header('HTTP/1.1 500 Database Error'); 55 | exit; 56 | } 57 | 58 | 59 | if (!$this->con) { 60 | die('Could not connect: ' . mysql_error()); 61 | } 62 | } 63 | 64 | /** 65 | * disconnecting database connection 66 | */ 67 | private function disconnect() 68 | { 69 | $this->con = null; 70 | } 71 | 72 | /** 73 | * quoting string 74 | * @param string $args 75 | * @return sting $args 76 | */ 77 | function quote($arg) 78 | { 79 | $this->connect(); 80 | $arg = $this->con->quote($arg); 81 | $this->disconnect(); 82 | return $arg; 83 | } 84 | 85 | /** 86 | * prepare statement for single fetch 87 | * @param string $sql 88 | * @param array $args 89 | * @return query $q 90 | */ 91 | function prepare($sql, $args) 92 | { 93 | $this->connect(); 94 | $q = $this->con->prepare($sql); 95 | $q->execute($args); 96 | $this->disconnect(); 97 | return $q; 98 | } 99 | 100 | /** 101 | * Return array of results 102 | * @param string $sql 103 | * @param array $args 104 | * @return query array $rows 105 | */ 106 | function load_result($sql, $args) 107 | { 108 | $this->connect(); 109 | $q = $this->con->prepare($sql); 110 | $q->execute($args); 111 | $rows = $q->fetchAll(); 112 | $this->disconnect(); 113 | return $rows; 114 | } 115 | 116 | /** 117 | * Return single result 118 | * @param string $sql 119 | * @param array $args 120 | * @return query $row 121 | */ 122 | function load_single_result($sql, $args) 123 | { 124 | $this->connect(); 125 | $q = $this->con->prepare($sql); 126 | $q->execute($args); 127 | $row = $q->fetch(); 128 | $this->disconnect(); 129 | return $row; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /libraries/core/http/index.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/libraries/core/http/index.php -------------------------------------------------------------------------------- /libraries/core/http/routes.php: -------------------------------------------------------------------------------- 1 | $control) { 30 | $this->routes[$regex] = $control; 31 | } 32 | } 33 | } 34 | 35 | /** 36 | * get requested url 37 | * @return string $url 38 | */ 39 | private function get_url() 40 | { 41 | $trimed = trim(explode('\?', $_SERVER['REQUEST_URI'])[0], '/'); 42 | $url = explode('/', $trimed); 43 | 44 | $number_of_folders = count(explode('/', ROOT)) - 3; 45 | for ($i = 0; $i < $number_of_folders; $i++) { 46 | array_shift($url); 47 | } 48 | 49 | $url = join("/", $url); 50 | return $url; 51 | } 52 | 53 | /** 54 | * filter parameters from url's regex 55 | * @param string $regex 56 | * @return array (string $regex) (array $args) (array $arg_pos) 57 | */ 58 | private function filter_regex($regex) 59 | { 60 | $args = array(); 61 | $arg_pos = array(); 62 | $regex_array = explode('/', $regex); 63 | 64 | foreach ($regex_array as $pos => $r) { 65 | // if there is a dynamic parameter in url 66 | if (strpos($r, '{') !== false) { 67 | $perm = substr($r, strpos($r, '{') + 1, strpos($r, '}') - strpos($r, '{') - 1); 68 | array_push($args, $perm); 69 | array_push($arg_pos, $pos); 70 | $regex_array[$pos] = str_replace('{' . $perm . '}', '', $r); 71 | } 72 | } 73 | $regex = join('/', $regex_array); 74 | return ['regex' => $regex, 'args' => $args, 'arg_pos' => $arg_pos]; 75 | } 76 | 77 | /** 78 | * match current url with registered url regexes 79 | */ 80 | private function check_regex() 81 | { 82 | $url = $this->get_url(); 83 | foreach ($this->routes as $route => $url_meta) { 84 | // filter the regex string 85 | $filtered_regex = $this->filter_regex($route); 86 | $url_location = explode('?', $url)[0]; 87 | 88 | // matich regex 89 | preg_match('#^' . $filtered_regex['regex'] . '$#', $url_location, $matches, PREG_OFFSET_CAPTURE); 90 | if (!empty($matches)) { 91 | if (is_array($url_meta)) { 92 | $control = $url_meta['control']; 93 | if (array_search($_SERVER['REQUEST_METHOD'], $url_meta['allow']) === false) { 94 | return false; 95 | } 96 | } else { 97 | $control = $url_meta; 98 | } 99 | 100 | $args = array(); 101 | if (!empty($filtered_regex['args'])) { 102 | $url_split = explode('/', $url); 103 | $pos = 0; 104 | foreach ($filtered_regex['args'] as $arg) { 105 | $args[$arg] = $url_split[$filtered_regex['arg_pos'][$pos++]]; 106 | } 107 | } 108 | 109 | return ['control' => $control, 'args' => $args]; 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | /** 116 | * find right app class and its funciton 117 | * @return array $destination 118 | */ 119 | function get_destination() 120 | { 121 | $destination = $this->check_regex(); 122 | if ($destination !== false) { 123 | return $destination; 124 | } 125 | header('HTTP/1.1 404 Page not found'); 126 | exit; 127 | } 128 | 129 | /** 130 | * map values to parameters in url regex 131 | */ 132 | private function map_url($regex, $args) 133 | { 134 | $regex_array = explode('/', $regex); 135 | foreach ($args as $k => $v) { 136 | $pos = 0; 137 | foreach ($regex_array as $r) { 138 | if (strpos($r, '{' . $k . '}') !== false) { 139 | $regex_array[$pos] = $v; 140 | } 141 | $pos++; 142 | } 143 | } 144 | return join($regex_array, '/'); 145 | } 146 | 147 | /** 148 | * return a named url 149 | * @return string url 150 | */ 151 | public function to_route($name, $args = null) 152 | { 153 | foreach ($this->routes as $regex => $meta) { 154 | if (is_array($meta)) { 155 | if ($name === $meta['name']) { 156 | if ($args !== null) { 157 | return ROOT . '/' . $this->map_url($regex, $args); 158 | } else { 159 | return ROOT . '/' . $regex; 160 | } 161 | } 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /templates/default/403.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/templates/default/403.php -------------------------------------------------------------------------------- /templates/default/404.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/templates/default/404.php -------------------------------------------------------------------------------- /templates/default/500.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/templates/default/500.php -------------------------------------------------------------------------------- /templates/default/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/28harishkumar/phpcms/61b1e7afb41c24425352e7e70a5e2697026a0521/templates/default/Screenshot.png -------------------------------------------------------------------------------- /templates/default/admin/index.php: -------------------------------------------------------------------------------- 1 |Handle user interface from here. It is kept simple for basic learning.
4 |Change your theme from here! NOTE: Theme can be activated by only admin. If you are looking demo then use live preview
5 | Back to admin panel 6 |List of all users.
4 |By default record of the admin will not be displayed. User can be edited or deleted by only admin. If you are looking demo then you can not do this.
5 | Back to admin panel 6 |Role | 14 |Is Active | 15 |Actions | 16 ||
---|---|---|---|
24 | | 25 | | 30 | |
31 | Edit |
32 |
36 | |
37 |
Error:
12 | 14 |