diff --git a/application/config/form_validation.php b/application/config/form_validation.php index 550e298..116dff5 100644 --- a/application/config/form_validation.php +++ b/application/config/form_validation.php @@ -1,45 +1,206 @@ array( - array( - 'field' => 'username', - 'label' => _('Username'), - 'rules' => 'trim|required|min_length[4]|max_length[20]|unique[users.username]', - ), - array( - 'field' => 'password', - 'label' => _('Password'), - 'rules' => 'required|min_length[6]|matches[password_confirm]', - ), - array( - 'field' => 'password_confirm', - 'label' => _('Confirm password'), - ), - array( - 'field' => 'firstname', - 'label' => _('First name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'lastname', - 'label' => _('Last name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'email', - 'label' => _('Email address'), - 'rules' => 'trim|required|valid_email', - ), - array( - 'field' => 'institution', - 'label' => _('Institution'), - 'rules' => 'trim|max_length[100]', - ), - array( - 'field' => 'phone', - 'label' => _('Phone number'), - 'rules' => 'trim|regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]', - ) - ) -); \ No newline at end of file +/** + * Rules for login page. + * + * @var array + */ +$config['auth/login'] = array( + array( + 'field' => 'username', + 'label' => _('Username'), + 'rules' => 'required|trim', + ), + array( + 'field' => 'password', + 'label' => _('Password'), + 'rules' => 'required|trim', + ), + array( + 'field' => 'remember', + 'label' => _('Remember me on this computer'), + 'rules' => 'integer', + ), +); + +/** + * Rules for forgotten password page. + * + * @var array + */ +$config['auth/forgot_password'] = array( + array( + 'field' => 'email', + 'label' => _('Email address'), + 'rules' => 'required|valid_email|trim', + ), +); + +/** +* Rules for the settings page. +* +* @var array +*/ +$config['auth/settings'] = array( + array( + 'field' => 'firstname', + 'label' => _('First name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'lastname', + 'label' => _('Last name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'email', + 'label' => _('Email address'), + 'rules' => 'required|valid_email|trim', + ), + array( + 'field' => 'institution', + 'label' => _('Institution'), + 'rules' => 'max_length[100]|trim', + ), + array( + 'field' => 'phone', + 'label' => _('Phone number'), + 'rules' => 'regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]|trim', + ), + array( + 'field' => 'new_password', + 'label' => _('New password'), + 'rules' => 'min_length[6]|matches[new_password_confirm]', + ), +); + +/** + * Rules for creating users. + * + * @var array + */ +$config['users/create'] = array( + array( + 'field' => 'username', + 'label' => _('Username'), + 'rules' => 'required|min_length[4]|max_length[20]|unique[users.username]|trim', + ), + array( + 'field' => 'email', + 'label' => _('Email address'), + 'rules' => 'required|valid_email|trim', + ), + array( + 'field' => 'password', + 'label' => _('Password'), + 'rules' => 'required|min_length[6]|matches[password_confirm]', + ), + array( + 'field' => 'password_confirm', + 'label' => _('Confirm password'), + 'rules' => 'required', + ), + array( + 'field' => 'firstname', + 'label' => _('First name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'lastname', + 'label' => _('Last name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'institution', + 'label' => _('Institution'), + 'rules' => 'max_length[100]|trim', + ), + array( + 'field' => 'phone', + 'label' => _('Phone number'), + 'rules' => 'regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]|trim', + ), +); + +/** + * Rules for editing users. + * + * @var array + */ +$config['users/edit'] = array( + array( + 'field' => 'firstname', + 'label' => _('First name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'lastname', + 'label' => _('Last name'), + 'rules' => 'required|max_length[50]|trim', + ), + array( + 'field' => 'email', + 'label' => _('Email address'), + 'rules' => 'required|valid_email|trim', + ), + array( + 'field' => 'institution', + 'label' => _('Institution'), + 'rules' => 'max_length[100]|trim', + ), + array( + 'field' => 'phone', + 'label' => _('Phone number'), + 'rules' => 'regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]|trim', + ), +); + +/** + * Rules for editing programs. + * + * @var array + */ +$config['programs/edit'] = array( + array( + 'field' => 'name', + 'label' => _('Name of the program'), + 'rules' => 'required|max_length[100]|trim', + ), +); + +/** + * Rules for creating parameters. + * + * @var array + */ +$config['parameters/create'] = array( + array( + 'field' => 'name', + 'label' => _('Name'), + 'rules' => 'required|max_length[255]|trim', + ), + array( + 'field' => 'readable', + 'label' => _('Human-readable name'), + 'rules' => 'required|max_length[100]|trim', + ), + array( + 'field' => 'unit', + 'label' => _('Name'), + 'rules' => 'max_length[20]|trim', + ), + array( + 'field' => 'default_value', + 'label' => _('Default value'), + 'rules' => 'max_length[255]|trim', + ), + array( + 'field' => 'type', + 'label' => _('Type'), + 'rules' => 'required|max_length[20]|trim', + ), +); + +/* End of file form_validation.php */ +/* Location: ./application/config/form_validation.php */ + diff --git a/application/controllers/admin/parameters.php b/application/controllers/admin/parameters.php new file mode 100644 index 0000000..ca4289f --- /dev/null +++ b/application/controllers/admin/parameters.php @@ -0,0 +1,133 @@ + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +require_once APPPATH . 'core/Admin_Controller.php'; + +/** + * + * @author Eike Foken + */ +class Parameters extends Admin_Controller { + + /** + * Calls the parent constructor. + */ + public function __construct() { + parent::__construct(); + $this->load->model('parameter'); + $this->load->model('program'); + } + + /** + * Allows admins to create a new parameter. + * + * @param string $programId + */ + public function create($programId = '') { + $program = $this->program->getByID($programId); + + if (empty($programId) || !isset($program['id'])) { + show_404(); + } + + if ($this->form_validation->run('parameters/create') === true) { + $paramName = $this->input->post('name'); + + $data = array( + 'program_id' => $program['id'], + 'name' => $paramName, + 'readable' => $this->input->post('readable'), + 'unit' => $this->input->post('unit'), + 'description' => $this->input->post('description'), + 'type' => $this->input->post('type'), + 'default_value' => $this->input->post('default_value'), + ); + + if ($this->parameter->create($data)) { + $this->messages->add(sprintf(_("The parameter '%s' has been successfully created."), $paramName), 'success'); + redirect('admin/programs/edit/' . $program['id'], 303); + } + } + + $data = array(); // empty the data array + $data['types'] = $this->parameter->getTypes(); + $data['program'] = $program; + + $this->load->view('admin/parameters/create', $data); + } + + /** + * Allows admins to edit a parameter. + * + * @param string $id + */ + public function edit($id = '') { + $parameter = $this->parameter->getByID($id); + + if (empty($id) || !isset($parameter['id'])){ + show_404(); + } + + if ($this->form_validation->run('parameters/create') === true) { + $data = array( + 'name' => $this->input->post('name'), + 'readable' => $this->input->post('readable'), + 'unit' => $this->input->post('unit'), + 'description' => $this->input->post('description'), + 'type' => $this->input->post('type'), + 'default_value' => $this->input->post('default_value'), + ); + + if ($this->parameter->update($data, $id)) { + $this->messages->add(sprintf(_("The parameter '%s' has been successfully updated."), $parameter['name']), 'success'); + redirect('admin/programs/edit/' . $parameter['program_id'], 303); + } + } + + $data = array(); // empty the data array + $data['types'] = $this->parameter->getTypes(); + $data['parameter'] = $parameter; + + $this->load->view('admin/parameters/edit', $data); + } + + /** + * Allows admins to delete a parameter. + * + * @param string $id + */ + public function delete($id = '') { + $parameter = $this->parameter->getByID($id); + + if (empty($id) || !isset($parameter['id'])) { + show_404(); + } else { + if ($this->parameter->delete($parameter['id'])) { + $this->messages->add(_('The selected parameter has been successfully deleted.'), 'success'); + } + redirect('admin/programs/edit/' . $parameter['program_id'], 303); + } + } +} + +/* End of file parameters.php */ +/* Location: ./application/controllers/admin/parameters.php */ diff --git a/application/controllers/admin/programs.php b/application/controllers/admin/programs.php new file mode 100644 index 0000000..f613959 --- /dev/null +++ b/application/controllers/admin/programs.php @@ -0,0 +1,52 @@ + + */ +class Programs extends CI_Controller { + + /** + * Calls the parent constructor. + */ + public function __construct() { + parent::__construct(); + $this->load->library('form_validation'); + $this->load->model('program'); + $this->load->model('parameter'); + } + + /** + * Shows a list of all available programs. + */ + public function index() { + $data['programs'] = $this->program->getAll(); + $this->load->view('admin/programs/list', $data); + } + + /** + * Allows admins to edit a program. + * + * @param string $id + */ + public function edit($id = '') { + $program = $this->program->getByID($id); + + if (!isset($program) || !is_array($program)){ + show_404(); + } + + if ($this->form_validation->run('programs/edit') === true) { + if ($this->program->update($this->input->post('name'), $id)) { + $this->messages->add(sprintf(_("The program '%s' has been updated successfully"), $this->input->post('name')), 'success'); + redirect('admin/programs', 303); + } + } + + $data['program'] = $program; + $data['parameters'] = $this->parameter->getAll($program['id']); + + $this->load->view('admin/programs/edit', $data); + } + +} \ No newline at end of file diff --git a/application/controllers/admin/users.php b/application/controllers/admin/users.php index 2f63c9f..43e568e 100644 --- a/application/controllers/admin/users.php +++ b/application/controllers/admin/users.php @@ -22,56 +22,13 @@ class Users extends CI_Controller { */ public function index() { $data['users'] = $this->user->getAll(); - $this->load->view('admin/users/index', $data); + $this->load->view('admin/users/list', $data); } /** * Allows admins to create a new user. */ public function create() { - $config = array( - array( - 'field' => 'username', - 'label' => _('Username'), - 'rules' => 'trim|required|min_length[4]|max_length[20]|unique[users.username]', - ), - array( - 'field' => 'password', - 'label' => _('Password'), - 'rules' => 'required|min_length[6]|matches[password_confirm]', - ), - array( - 'field' => 'password_confirm', - 'label' => _('Confirm password'), - ), - array( - 'field' => 'firstname', - 'label' => _('First name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'lastname', - 'label' => _('Last name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'email', - 'label' => _('Email address'), - 'rules' => 'trim|required|valid_email', - ), - array( - 'field' => 'institution', - 'label' => _('Institution'), - 'rules' => 'trim|max_length[100]', - ), - array( - 'field' => 'phone', - 'label' => _('Phone number'), - 'rules' => 'trim|regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]', - ) - ); - $this->form_validation->set_rules($config); - if ($this->form_validation->run() === true) { $username = $this->input->post('username'); @@ -83,7 +40,7 @@ class Users extends CI_Controller { ); if ($this->user->register($username, $this->input->post('password'), $this->input->post('email'), $data)) { - $this->messages->add(sprintf(_("The user '%s' was created"), $username), 'success'); + $this->messages->add(sprintf(_("The user '%s' has been created successfully"), $username), 'success'); redirect('admin/users', 303); } } @@ -103,36 +60,7 @@ class Users extends CI_Controller { show_404(); } - $config = array( - array( - 'field' => 'firstname', - 'label' => _('First name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'lastname', - 'label' => _('Last name'), - 'rules' => 'trim|required|max_length[50]', - ), - array( - 'field' => 'email', - 'label' => _('Email address'), - 'rules' => 'trim|required|valid_email', - ), - array( - 'field' => 'institution', - 'label' => _('Institution'), - 'rules' => 'trim|max_length[100]', - ), - array( - 'field' => 'phone', - 'label' => _('Phone number'), - 'rules' => 'trim|regex_match[/^\+\d{2,4}\s\d{2,4}\s\d{3,10}+$/i]', - ) - ); - $this->form_validation->set_rules($config); - - if ($this->form_validation->run() === true) { + if ($this->form_validation->run('users/edit') === true) { $data = array( 'email' => $this->input->post('email'), 'firstname' => $this->input->post('firstname'), @@ -142,7 +70,7 @@ class Users extends CI_Controller { ); if ($this->user->update($user['id'], $data)) { - $this->messages->add(sprintf(_("The user '%s' was updated"), $user['username']), 'success'); + $this->messages->add(sprintf(_("The user '%s' has been updated successfully"), $user['username']), 'success'); redirect('admin/users', 303); } } @@ -162,7 +90,7 @@ class Users extends CI_Controller { show_404(); } else { $this->user->delete($user['id']); - $this->messages->add(_("The selected user was deleted"), 'success'); + $this->messages->add(_("The selected user has been deleted successfully"), 'success'); redirect('admin/users', 303); } } diff --git a/application/controllers/ajax.php b/application/controllers/ajax.php index 307bf0a..c89a3d3 100644 --- a/application/controllers/ajax.php +++ b/application/controllers/ajax.php @@ -55,4 +55,13 @@ class Ajax extends CI_Controller { $data['description'] = $this->input->post('content'); $this->project->update($this->session->userdata('active_project'), $data); } + + /** + * Sorts a programs parameters. + */ + public function sort_parameters() { + $this->load->model('parameter'); + $this->parameter->sort($this->input->post('parameters')); + } + } \ No newline at end of file diff --git a/application/controllers/auth.php b/application/controllers/auth.php index 500e9f2..fce9b7c 100644 --- a/application/controllers/auth.php +++ b/application/controllers/auth.php @@ -33,30 +33,23 @@ class Auth extends CI_Controller { */ public function login() { if ($this->access->loggedIn()) { - redirect(); + redirect('dashboard'); } - // validate form input - $this->form_validation->set_rules('username', _('Username'), 'required'); - $this->form_validation->set_rules('password', _('Password'), 'required'); + $data['messages'] = $this->messages->get('success'); - if ($this->form_validation->run() == true) { + if ($this->form_validation->run() === true) { // check for "remember me" $remember = (boolean) $this->input->post('remember'); if ($this->access->login($this->input->post('username'), $this->input->post('password'), $remember)) { - $this->data['success'] = true; - redirect('dashboard', 'refresh'); + redirect('dashboard', 303); } else { // if the login was un-successful - $this->data['success'] = false; - $this->data['message'] = $this->access->errors(); + $data['errors'] = $this->messages->get('error'); } - } else { - $this->data['message'] = validation_errors() ? validation_errors() : null; - $this->data['username'] = $this->form_validation->set_value('username'); - - $this->load->view('auth/login', $this->data); } + + $this->load->view('auth/login', $data); } /** @@ -64,8 +57,7 @@ class Auth extends CI_Controller { */ public function logout() { $logout = $this->access->logout(); - - redirect(base_url(), 'refresh'); + redirect('auth/login'); } /** @@ -114,85 +106,66 @@ class Auth extends CI_Controller { * Allows users to edit their settings. */ public function settings() { - if (!$this->access->loggedIn()) { - redirect('auth/login', 'refresh'); - } + $user = $this->access->getCurrentUser(); - // validate the form - $this->form_validation->set_rules('new_password', _('New password'), 'min_length[' . $this->config->item('min_password_length', 'auth') . ']|max_length[' . $this->config->item('max_password_length', 'access') . ']|matches[new_password_confirm]'); - - if ($this->form_validation->run() == true) { + if ($this->form_validation->run() === true) { // change password if needed if ($this->input->post('new_password') != '') { $username = $this->session->userdata('username'); $change = $this->access->changePassword($username, $this->input->post('old_password'), $this->input->post('new_password')); - - if ($change) { - $this->logout(); - } +// if ($change) { +// $this->logout(); +// } } - // update user - $updateData = array( - 'firstname' => $this->input->post('firstname'), - 'lastname' => $this->input->post('lastname'), - 'institution' => $this->input->post('institution'), - 'phone' => $this->input->post('phone'), - 'email' => $this->input->post('email'), + // update users table + $data = array( + 'email' => $this->input->post('email'), + 'firstname' => $this->input->post('firstname'), + 'lastname' => $this->input->post('lastname'), + 'institution' => $this->input->post('institution'), + 'phone' => $this->input->post('phone') ); - $this->access->updateUser($this->session->userdata('user_id'), $updateData); - // output JSON data - $this->output->set_content_type('application/json') - ->set_output(json_encode(array('success' => true))); - } else { - $data['success'] = true; - $data['data'] = $this->access->getCurrentUser(); - - // output JSON data - $this->output->set_content_type('application/json') - ->set_output(json_encode($data)); + if ($this->user->update($user['id'], $data)) { + $this->messages->add(_("Settings saved successfully"), 'success'); + redirect('auth/settings', 303); + } } + + $this->load->view('auth/settings', $user); } /** * Allows users to request a new password. */ public function forgot_password() { - $this->form_validation->set_rules('email', _('eMail address'), 'required'); - if ($this->form_validation->run() == false) { - //setup the input - $this->data['email'] = array('name' => 'email', - 'id' => 'email', - ); - //set any errors and display the form - $this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message'); - $this->load->view('auth/forgot_password', $this->data); - } else { - //run the forgotten password method to email an activation code to the user - $forgotten = $this->access->forgotten_password($this->input->post('email')); + if ($this->form_validation->run() === true) { + // run the forgotten password method to email an activation code to the user + $forgotten = $this->access->forgottenPassword($this->input->post('email')); - if ($forgotten) { //if there were no errors - $this->session->set_flashdata('message', $this->access->messages()); - redirect("auth/login", 'refresh'); //we should display a confirmation page here instead of the login page + if ($forgotten) { // if there were no errors + redirect('auth/login'); // TODO Display a confirmation page here instead of the login page } else { - $this->session->set_flashdata('message', $this->access->errors()); - redirect("auth/forgot_password", 'refresh'); + redirect('auth/forgot_password'); } } + + $data['messages'] = $this->messages->get('success'); + $data['errors'] = $this->messages->get('error'); + + $this->load->view('auth/forgot_password', $data); } /** * Final step for forgotten password. */ public function reset_password($code) { - $reset = $this->access->forgotten_password_complete($code); + $reset = $this->access->forgottenPasswordComplete($code); - if ($reset) { //if the reset worked then send them to the login page - $this->session->set_flashdata('message', $this->access->messages()); + if ($reset) { // if the reset worked then send them to the login page redirect('auth/login'); - } else { //if the reset didnt work then send them back to the forgot password page - $this->session->set_flashdata('message', $this->access->errors()); + } else { // if the reset didn't work then send them back to the forgot password page redirect('auth/forgot_password'); } } diff --git a/application/controllers/settings.php b/application/controllers/settings.php deleted file mode 100644 index d694efa..0000000 --- a/application/controllers/settings.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @author Karsten Heiken - */ -class Settings extends CI_Controller { - - /** - * Constructor. - */ - public function __construct() { - parent::__construct(); - $this->load->model('program'); - } - - /** - * Show a list of all available programs. - */ - public function index() { - $profile = $this->user->profile(); - $profile_fields = array( - array('firstname', _('First name'), 'text'), - array('lastname', _('Last name'), 'text'), - array('intitution', _('Institution'), 'text'), - ); - $tpl['profile'] = $profile; - $tpl['profile_fields'] = $profile_fields; - $this->load->view('user/settings', $tpl); - } -} diff --git a/application/core/Admin_Controller.php b/application/core/Admin_Controller.php new file mode 100644 index 0000000..48b34ce --- /dev/null +++ b/application/core/Admin_Controller.php @@ -0,0 +1,44 @@ + +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +/** + * Simple controller for admin pages. + * + * @author Eike Foken + */ +class Admin_Controller extends CI_Controller { + + /** + * Calls the parent constructor. + */ + public function __construct() { + parent::__construct(); + + if (!$this->access->isAdmin()) { + show_error(_('Shove off, this is for admins.'), 403); + } + } +} + +/* End of file Admin_Controller.php */ +/* Location: ./application/core/Admin_Controller.php */ diff --git a/application/core/MY_Controller.php b/application/core/MY_Controller.php deleted file mode 100644 index e425238..0000000 --- a/application/core/MY_Controller.php +++ /dev/null @@ -1,20 +0,0 @@ - -*/ -class MY_Controller extends CI_Controller { - - /** - * Calls the parent constructor and loads the relevant language file. - */ - public function __construct() { - parent::__construct(); - - // load relevant language file - $this->lang->load(strtolower($this->router->class)); - } - -} \ No newline at end of file diff --git a/application/language/german/auth_lang.php b/application/language/de_DE/auth_lang.php similarity index 100% rename from application/language/german/auth_lang.php rename to application/language/de_DE/auth_lang.php diff --git a/application/language/german/datamapper_lang.php b/application/language/de_DE/datamapper_lang.php similarity index 100% rename from application/language/german/datamapper_lang.php rename to application/language/de_DE/datamapper_lang.php diff --git a/application/language/german/form_validation_lang.php b/application/language/de_DE/form_validation_lang.php similarity index 100% rename from application/language/german/form_validation_lang.php rename to application/language/de_DE/form_validation_lang.php diff --git a/application/language/english/index.html b/application/language/de_DE/index.html similarity index 100% rename from application/language/english/index.html rename to application/language/de_DE/index.html diff --git a/application/language/german/jobs_lang.php b/application/language/de_DE/jobs_lang.php similarity index 100% rename from application/language/german/jobs_lang.php rename to application/language/de_DE/jobs_lang.php diff --git a/application/language/german/projects_lang.php b/application/language/de_DE/projects_lang.php similarity index 100% rename from application/language/german/projects_lang.php rename to application/language/de_DE/projects_lang.php diff --git a/application/language/german/settings_lang.php b/application/language/de_DE/settings_lang.php similarity index 100% rename from application/language/german/settings_lang.php rename to application/language/de_DE/settings_lang.php diff --git a/application/language/english/auth_lang.php b/application/language/en_US/auth_lang.php similarity index 100% rename from application/language/english/auth_lang.php rename to application/language/en_US/auth_lang.php diff --git a/application/language/english/datamapper_lang.php b/application/language/en_US/datamapper_lang.php similarity index 100% rename from application/language/english/datamapper_lang.php rename to application/language/en_US/datamapper_lang.php diff --git a/application/language/english/form_validation_lang.php b/application/language/en_US/form_validation_lang.php similarity index 100% rename from application/language/english/form_validation_lang.php rename to application/language/en_US/form_validation_lang.php diff --git a/application/language/german/index.html b/application/language/en_US/index.html similarity index 100% rename from application/language/german/index.html rename to application/language/en_US/index.html diff --git a/application/language/english/jobs_lang.php b/application/language/en_US/jobs_lang.php similarity index 100% rename from application/language/english/jobs_lang.php rename to application/language/en_US/jobs_lang.php diff --git a/application/language/english/projects_lang.php b/application/language/en_US/projects_lang.php similarity index 100% rename from application/language/english/projects_lang.php rename to application/language/en_US/projects_lang.php diff --git a/application/language/english/settings_lang.php b/application/language/en_US/settings_lang.php similarity index 100% rename from application/language/english/settings_lang.php rename to application/language/en_US/settings_lang.php diff --git a/application/language/english/admin/servers_lang.php b/application/language/english/admin/servers_lang.php deleted file mode 100644 index a470790..0000000 --- a/application/language/english/admin/servers_lang.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* - * Headings - */ -$lang['location'] = 'Location'; -$lang['owner'] = 'Owner'; -$lang['actions'] = 'Actions'; -$lang['technical_info'] = 'Technical information'; -$lang['hardware_os'] = 'Hardware & OS'; -$lang['scattport_stats'] = 'ScattPort statistics'; - -/* - * server status - */ -$lang['busy'] = 'busy'; -$lang['offline'] = 'offline'; -$lang['available'] = 'available'; - -$lang['workload'] = 'Workload'; -$lang['completed_jobs'] = 'Completed jobs'; \ No newline at end of file diff --git a/application/language/locale/de_DE/LC_MESSAGES/lang.po b/application/language/locale/de_DE/LC_MESSAGES/lang.po deleted file mode 100644 index 6584152..0000000 --- a/application/language/locale/de_DE/LC_MESSAGES/lang.po +++ /dev/null @@ -1,74 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-08-10 21:25+0200\n" -"PO-Revision-Date: 2011-08-10 22:00+0200\n" -"Last-Translator: Karsten Heiken \n" -"Language-Team: German <>\n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" - -msgid "Users" -msgstr "Benutzer" - -msgid "Available users" -msgstr "Alle verfügbaren Benutzer" - -msgid "Username" -msgstr "Benutzername" - -msgid "Full name" -msgstr "Vollständiger Name" - -msgid "Actions" -msgstr "Aktionen" - -msgid "Edit" -msgstr "Bearbeiten" - -msgid "Delete" -msgstr "Löschen" - -msgid "Create new user" -msgstr "Neuen Benutzer erstellen" - -msgid "Edit user '%s'" -msgstr "Benutzer »%s« bearbeiten" - -msgid "Required information" -msgstr "Erforderliche Angaben" - -msgid "Optional information" -msgstr "Optionale Angaben" - -msgid "Email address" -msgstr "E-Mail-Adresse" - -msgid "First name" -msgstr "Vorname" - -msgid "Last name" -msgstr "Nachname" - -msgid "Institution" -msgstr "Institution" - -msgid "Phone number" -msgstr "Telefonnummer" - -msgid "Language" -msgstr "Sprache" - -msgid "Example" -msgstr "Beispiel" - -msgid "Save" -msgstr "Speichern" - -msgid "Cancel" -msgstr "Abbrechen" - diff --git a/application/language/locale/en_US/LC_MESSAGES/lang.po b/application/language/locale/en_US/LC_MESSAGES/lang.po deleted file mode 100644 index cba01f1..0000000 --- a/application/language/locale/en_US/LC_MESSAGES/lang.po +++ /dev/null @@ -1,67 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-08-10 21:25+0200\n" -"PO-Revision-Date: 2011-08-10 22:00+0200\n" -"Last-Translator: Karsten Heiken \n" -"Language-Team: English <>\n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" - -msgid "users" -msgstr "Users" - -msgid "available_users" -msgstr "Available users" - -msgid "username" -msgstr "Username" - -msgid "realname" -msgstr "Name" - -msgid "options" -msgstr "Options" - -msgid "user_edit" -msgstr "Edit" - -msgid "user_create" -msgstr "Create new user" - -msgid "user_delete" -msgstr "Delete" - -msgid "create_user" -msgstr "Create a new user" - -msgid "edit_user" -msgstr "Edit user" - -msgid "field_username" -msgstr "Username" - -msgid "field_password" -msgstr "Password" - -msgid "field_password_confirm" -msgstr "Confirm password" - -msgid "field_firstname" -msgstr "First name" - -msgid "field_lastname" -msgstr "Last name" - -msgid "field_email" -msgstr "Email address" - -msgid "field_institution" -msgstr "Institution" - -msgid "field_phone" -msgstr "Phone number" diff --git a/application/libraries/Access.php b/application/libraries/Access.php index 2f5dfee..8068696 100644 --- a/application/libraries/Access.php +++ b/application/libraries/Access.php @@ -7,279 +7,240 @@ */ class Access { - /** - * Contains the CI instance. - */ - protected $ci; + /** + * Contains the CI instance. + */ + protected $ci; - /** - * Contains occured messages (using the language file). - * - * @var string - */ - protected $messages = array(); + /** + * Contains occured messages (using the language file). + * + * @var string + */ + protected $messages = array(); - /** - * Contains occured errors (using the language file). - * - * @var string - */ - protected $errors = array(); + /** + * Contains occured errors (using the language file). + * + * @var string + */ + protected $errors = array(); - /** - * Constructor. - */ - public function __construct() { - $this->ci =& get_instance(); - $this->ci->load->config('auth', true); - $this->ci->load->library('email'); - $this->ci->lang->load('auth'); - $this->ci->load->model('user'); - $this->ci->load->model('group'); - $this->ci->load->helper('cookie'); + /** + * Constructor. + */ + public function __construct() { + $this->ci =& get_instance(); + $this->ci->load->config('auth', true); + $this->ci->load->library('email'); + $this->ci->lang->load('auth'); + $this->ci->load->model('user'); + $this->ci->load->model('group'); + $this->ci->load->helper('cookie'); - // auto-login the user if they are remembered - if (!$this->loggedIn() && get_cookie('username') && get_cookie('remember_code')) { - $this->ci->access = $this; - $this->ci->user->loginRememberedUser(); - } - } + // auto-login the user if they are remembered + if (!$this->loggedIn() && get_cookie('username') && get_cookie('remember_code')) { + $this->ci->access = $this; + $this->ci->user->loginRememberedUser(); + } + } - /** - * Changes a users password. - * - * @return boolean - */ - public function changePassword($username, $old, $new) { - if ($this->ci->user->changePassword($username, $old, $new)) { - $this->setMessage(_('Password successfully changed')); - return true; - } + /** + * Changes a users password. + * + * @param string $username + * @param string $old + * @param string $new + * @return boolean + */ + public function changePassword($username, $old, $new) { + if ($this->ci->user->changePassword($username, $old, $new)) { + $this->ci->messages->add(_('Password successfully changed'), 'success'); + return true; + } - $this->setError(_('Unable to change password')); - return false; - } + $this->ci->messages->add(_('Unable to change password'), 'error'); + return false; + } - /** - * forgotten password feature - * - * @return void - */ - public function forgottenPassword($username) { - if ($this->ci->user->forgottenPassword($username)) { - // get user information - $user = $this->getUserByUsername($username); + /** + * forgotten password feature + * + * @param string $email + * @return void + */ + public function forgottenPassword($email) { + if ($this->ci->user->forgottenPassword($email)) { + // get user information + $user = $this->ci->user->getUserByEmail($email); - $data = array( + $data = array( 'username' => $user['username'], - 'forgotten_password_code' => $user['forgotten_password_code'] - ); + 'forgotten_password_code' => $user['forgotten_password_code'], + ); - $message = $this->ci->load->view($this->ci->config->item('email_templates', 'auth') . $this->ci->config->item('email_forgot_password', 'auth'), $data, true); - $this->ci->email->clear(); - $config['mailtype'] = $this->ci->config->item('email_type', 'auth'); - $this->ci->email->initialize($config); - $this->ci->email->set_newline("\r\n"); - $this->ci->email->from($this->ci->config->item('admin_email', 'auth'), 'Scattport'); - $this->ci->email->to($user['email']); - $this->ci->email->subject('Scattport - Forgotten Password Verification'); - $this->ci->email->message($message); + $message = $this->ci->load->view('auth/email/forgot_password', $data, true); + $this->ci->email->clear(); + $config['mailtype'] = $this->ci->config->item('email_type', 'auth'); + $this->ci->email->initialize($config); + $this->ci->email->set_newline("\r\n"); + $this->ci->email->from($this->ci->config->item('admin_email', 'auth'), 'Scattport'); + $this->ci->email->to($user['email']); + $this->ci->email->subject('ScattPort - Forgotten Password Verification'); + $this->ci->email->message($message); - if ($this->ci->email->send()) { - $this->setMessage(_('Password reset email sent')); - return true; - } else { - $this->setError(_('Unable to reset password')); - return false; - } - } else { - $this->setError(_('Unable to reset password')); - return false; - } - } + if ($this->ci->email->send()) { + $this->ci->messages->add(_('Password reset email sent'), 'success'); + return true; + } else { + $this->ci->messages->add(_('Unable to send password reset email'), 'error'); + return false; + } + } else { + $this->ci->messages->add(_('This email address is not registered'), 'error'); + return false; + } + } - /** - * forgotten_password_complete - * - * @return void - */ - public function forgottenPasswordComplete($code) { - $profile = $this->ci->user->profile($code, true); // pass the code to profile + /** + * forgotten_password_complete + * + * @param string $code + * @return void + */ + public function forgottenPasswordComplete($code) { + $profile = $this->ci->user->profile($code, true); // pass the code to profile - if (!is_object($profile)) { - $this->setError(_('Unable to change password')); - return false; - } + if (!is_object($profile)) { + $this->ci->messages->add(_('Unable to change password'), 'error'); + return false; + } - $new_password = $this->ci->user->forgottenPasswordComplete($code, $profile->salt); + $new_password = $this->ci->user->forgottenPasswordComplete($code, $profile->salt); - if ($new_password) { - $data = array( + if ($new_password) { + $data = array( 'username' => $profile->username, 'new_password' => $new_password - ); + ); - $message = $this->ci->load->view($this->ci->config->item('email_templates', 'ion_auth').$this->ci->config->item('email_forgot_password_complete', 'ion_auth'), $data, true); + $message = $this->ci->load->view('auth/email/forgot_password_complete', $data, true); - $this->ci->email->clear(); - $config['mailtype'] = $this->ci->config->item('email_type', 'ion_auth'); - $this->ci->email->initialize($config); - $this->ci->email->set_newline("\r\n"); - $this->ci->email->from($this->ci->config->item('admin_email', 'ion_auth'), $this->ci->config->item('site_title', 'ion_auth')); - $this->ci->email->to($profile->email); - $this->ci->email->subject($this->ci->config->item('site_title', 'ion_auth') . ' - New Password'); - $this->ci->email->message($message); + $this->ci->email->clear(); + $config['mailtype'] = $this->ci->config->item('email_type', 'auth'); + $this->ci->email->initialize($config); + $this->ci->email->set_newline("\r\n"); + $this->ci->email->from($this->ci->config->item('admin_email', 'auth'), $this->ci->config->item('site_title', 'auth')); + $this->ci->email->to($profile->email); + $this->ci->email->subject('ScattPort - New Password'); + $this->ci->email->message($message); - if ($this->ci->email->send()) { - $this->setMessage(_('Password successfully changed')); - return true; - } else { - $this->setError(_('Unable to change password')); - return false; - } - } + if ($this->ci->email->send()) { + $this->ci->messages->add(_('Password successfully changed'), 'success'); + return true; + } else { + $this->ci->messages->add(_('Unable to change password'), 'error'); + return false; + } + } - $this->setError(_('Unable to change password')); - return false; - } + $this->ci->messages->add(_('Unable to change password'), 'error'); + return false; + } - /** - * Logs the user in. - * - * @return boolean - */ - public function login($username, $password, $remember = false) { - if ($this->ci->user->login($username, $password, $remember)) { - $this->setMessage(_('Logged in successfully')); - return true; - } else { - $this->setError(_('Incorrect username or password')); - return false; - } - } + /** + * Logs the user in. + * + * @param string $username + * @param string $password + * @param boolean $remember + * @return boolean + */ + public function login($username, $password, $remember = false) { + if ($this->ci->user->login($username, $password, $remember)) { + $this->ci->messages->add(_('Logged in successfully'), 'success'); + return true; + } else { + $this->ci->messages->add(_('Incorrect username or password'), 'error'); + return false; + } + } - /** - * Logs the user out. - * - * @return boolean - */ - public function logout() { - $this->ci->session->unset_userdata('username'); - $this->ci->session->unset_userdata('group'); - $this->ci->session->unset_userdata('user_id'); + /** + * Logs the user out. + * + * @return boolean + */ + public function logout() { + $this->ci->session->unset_userdata('username'); + $this->ci->session->unset_userdata('group'); + $this->ci->session->unset_userdata('user_id'); - // delete the remember cookies if they exist - if (get_cookie('username')) { - delete_cookie('username'); - } if (get_cookie('remember_code')) { - delete_cookie('remember_code'); - } + // delete the remember cookies if they exist + if (get_cookie('username')) { + delete_cookie('username'); + } if (get_cookie('remember_code')) { + delete_cookie('remember_code'); + } - $this->ci->session->sess_destroy(); + $this->ci->session->sess_destroy(); - $this->setMessage(_('Logged out successfully')); - return true; - } + $this->ci->messages->add(_('Logged out successfully'), 'success'); + return true; + } - /** - * Checks if the user is logged in. - * - * @return boolean - */ - public function loggedIn() { - return (boolean) $this->ci->session->userdata('username'); - } + /** + * Checks if the user is logged in. + * + * @return boolean + */ + public function loggedIn() { + return (boolean) $this->ci->session->userdata('username'); + } - /** - * Checks if the user is an admin. - * - * @return boolean - */ - public function isAdmin() { - $adminGroup = 'admins'; - $userGroup = $this->ci->session->userdata('group'); - return $userGroup == $adminGroup; - } + /** + * Checks if the user is an admin. + * + * @return boolean + */ + public function isAdmin() { + $adminGroup = 'admins'; + $userGroup = $this->ci->session->userdata('group'); + return $userGroup == $adminGroup; + } - /** - * Checks if the current user is assigned to the specified group. - * - * @return boolean - */ - public function isGroup($checkGroup) { - $userGroup = $this->ci->session->userdata('group'); + /** + * Checks if the current user is assigned to the specified group. + * + * @param string $checkGroup + * @return boolean + */ + public function isGroup($checkGroup) { + $userGroup = $this->ci->session->userdata('group'); - if (is_array($checkGroup)) { - return in_array($userGroup, $checkGroup); - } - return $userGroup == $checkGroup; - } + if (is_array($checkGroup)) { + return in_array($userGroup, $checkGroup); + } + return $userGroup == $checkGroup; + } - /** - * Gets the current logged in user. - * - * @return object - */ - public function getCurrentUser() { - return $this->ci->user->getUserByID($this->ci->session->userdata('user_id')); - } + /** + * Gets the current logged in user. + * + * @return object + */ + public function getCurrentUser() { + return $this->ci->user->getUserByID($this->ci->session->userdata('user_id')); + } - /** - * Gets the profile of the current user. - * - * @return array - */ - public function profile() { - return $this->ci->user->profile($this->ci->session->userdata('username')); - } - - /** - * Sets a message. - * - * @return string - */ - public function setMessage($message) { - $this->messages[] = $message; - return $message; - } - - /** - * Gets all messages. - * - * @return void - */ - public function messages() { - $output = ''; - foreach ($this->messages as $message) { - $output .= $message . '
'; - } - - return $output; - } - - /** - * Sets an error message. - * - * @return void - */ - public function setError($error) { - $this->errors[] = $error; - return $error; - } - - /** - * Gets all error messages. - * - * @return void - */ - public function errors() { - $output = ''; - foreach ($this->errors as $error) { - $output .= $error . '
'; - } - - return $output; - } + /** + * Gets the profile of the current user. + * + * @return array + */ + public function profile() { + return $this->ci->user->profile($this->ci->session->userdata('username')); + } } diff --git a/application/libraries/MY_Session.php b/application/libraries/MY_Session.php index 9beff5c..90fd5d6 100644 --- a/application/libraries/MY_Session.php +++ b/application/libraries/MY_Session.php @@ -23,6 +23,44 @@ class MY_Session extends CI_Session { return sha1(uniqid(microtime() . $this->CI->input->ip_address(), true)); } + /** + * Writes the session data. + * + * @see CI_Session::sess_write() + */ + public function sess_write() { + // are we saving custom data to the DB? If not, all we do is update the cookie + if ($this->sess_use_database === false) { + $this->_set_cookie(); + return; + } + + // set the custom userdata, the session data we will set in a second + $customUserdata = $this->userdata; + $cookieUserdata = array(); + + // before continuing, we need to determine if there is any custom data to deal with. + foreach (array('session_id', 'user_id', 'ip_address', 'user_agent', 'last_activity') as $val) { + unset($customUserdata[$val]); + $cookieUserdata[$val] = $this->userdata[$val]; + } + + // did we find any custom data? If not, we turn the empty array into a string + if (count($customUserdata) === 0) { + $customUserdata = ''; + } else { + // serialize the custom data array so we can store it + $customUserdata = $this->_serialize($customUserdata); + } + + // run the update query + $this->CI->db->where('session_id', $this->userdata['session_id']); + $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_id' => $this->userdata['user_id'], 'user_data' => $customUserdata)); + + // write the cookie. + $this->_set_cookie($cookieUserdata); + } + /** * Creates a new session. * @@ -33,7 +71,8 @@ class MY_Session extends CI_Session { 'session_id' => $this->generateHash(), 'ip_address' => $this->CI->input->ip_address(), 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), - 'last_activity' => $this->now + 'last_activity' => $this->now, + 'user_id' => null, ); // save data to the DB if needed @@ -61,6 +100,7 @@ class MY_Session extends CI_Session { $this->userdata['session_id'] = $newSessionID; $this->userdata['last_activity'] = $this->now; + $this->userdata['user_id'] = array_key_exists('user_id', $this->userdata) ? $this->userdata['user_id'] : null; $cookieData = null; @@ -75,7 +115,7 @@ class MY_Session extends CI_Session { $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->now, 'user_id' => $this->userdata['user_id'], 'session_id' => $newSessionID), array('session_id' => $oldSessionID)); // update users table if user is logged in - if (array_key_exists('user_id', $this->userdata) && $this->userdata['user_id'] > 0) { + if (array_key_exists('user_id', $this->userdata) && !is_null($this->userdata['user_id'])) { $this->CI->db->update('users', array('last_activity' => $this->now), array('id' => $this->userdata['user_id'])); } } diff --git a/application/models/group.php b/application/models/group.php index ba0d4e5..433bc0e 100644 --- a/application/models/group.php +++ b/application/models/group.php @@ -8,41 +8,40 @@ class Group extends CI_Model { /** - * Constructor. + * Calls the parent constructor. */ public function __construct() { parent::__construct(); } /** - * get + * Gets all groups. * - * @return object + * @return array */ public function get() { return $this->db->get('groups')->result_array(); } /** - * getGroupByID + * Gets a specific group. * - * @return object + * @param string $id + * @return array */ - public function getGroupByID($id) { - $this->db->where('id', $id); - return $this->db->get('groups')->row_array(); + public function getByID($id) { + return $this->db->get_where('groups', array('id' => $id))->row_array(); } /** - * getGroupByName + * Gets a specific group by it's name. * - * @return object + * @param string $name + * @return array */ - public function getGroupByName($name) { - $this->db->where('name', $name); - return $this->db->get('groups')->row_array(); + public function getByName($name) { + return $this->db->get_where('groups', array('name' => $name))->row_array(); } - } /* End of file group.php */ diff --git a/application/models/parameter.php b/application/models/parameter.php new file mode 100644 index 0000000..ac519c9 --- /dev/null +++ b/application/models/parameter.php @@ -0,0 +1,140 @@ + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Model for parameters. + * + * Each program has many parameters used for configuration of trials. + * + * @author Eike Foken + */ +class Parameter extends CI_Model { + + /** + * Contains the possible types for parameters. + * + * @var array + */ + private $availableTypes = array('boolean', 'integer', 'float', 'string', 'array'); + + /** + * Calls the parent constructor. + */ + public function __construct() { + parent::__construct(); + } + + /** + * Gets all available parameters for a program. + * + * @param string $programId + * @return array + */ + public function getAll($programId) { + return $this->db->order_by('sort_number ASC') + ->get_where('parameters', array('program_id' => $programId))->result_array(); + } + + /** + * Gets a specific parameter. + * + * @param string $id + */ + public function getById($id) { + return $this->db->get_where('parameters', array('id' => $id))->row_array(); + } + + /** + * Gets the possible parameter types. + */ + public function getTypes() { + return $this->availableTypes; + } + + /** + * Creates a new parameter. + * + * @param array $data + * @return mixed Returns the ID of the created parameter, or FALSE if + * the insert was unsuccessful. + */ + public function create($data) { + $this->load->helper('hash'); + + if (!isset($data['program_id'])) { + return false; + } + + do { // generate unique hash + $data['id'] = random_hash('16'); + } while ($this->db->where('id', $data['id'])->from('parameters')->count_all_results() > 0); + + // put new parameter to the end + $data['sort_number'] = $this->db->select_max('sort_number') + ->get_where('parameters', array('program_id' => $data['program_id'])) + ->row()->sort_number + 1; + + $this->db->insert('parameters', $data); + return $this->db->affected_rows() > 0 ? $data['id'] : false; + } + + /** + * Updates a parameter. + * + * @param array $data + * @param string $id + * @return boolean Returns TRUE if the update was successful. + */ + public function update($data, $id) { + $this->db->update('parameters', $data, array('id' => $id)); + return $this->db->affected_rows() == 1; + } + + /** + * Deletes a specified parameter. + * + * @param string $id + * @return boolean Returns TRUE if the deletion was successful. + */ + public function delete($id) { + $this->db->delete('parameters', array('id' => $id)); + return $this->db->affected_rows() == 1; + } + + /** + * Saves the order of an array of parameters. + * + * @param array $parameters + * @return boolean Returns TRUE if the new order was successfully saved. + */ + public function sort($parameters) { + foreach ($parameters as $number => $id) { + $this->db->update('parameters', array('sort_number' => $number), array('id' => $id)); + } + + return $this->db->affected_rows() > 0; + } +} + +/* End of file parameter.php */ +/* Location: ./application/models/parameter.php */ diff --git a/application/models/program.php b/application/models/program.php index 324a012..905979e 100644 --- a/application/models/program.php +++ b/application/models/program.php @@ -1,5 +1,4 @@ * @@ -24,29 +23,58 @@ /** * Programs are used to do the actual calculation of a trial. - * + * * @author Karsten Heiken + * @author Eike Foken */ class Program extends CI_Model { /** - * Create a new program. - * - * @param array $data the data of the new program - * @return bool was the insert successful + * Calls the parent constructor. */ - public function create($data) { - // TODO: stub - return FALSE; + public function __construct() { + parent::__construct(); } /** - * Delete a program. - * @param string the program id to delete - * @return bool was the deletion successful + * Creates a new program. + * + * @param string $name The name of the new program + * @return string|boolean Returns the ID of the new program, or FALSE if + * the insert was unsuccessful. */ - public function delete($program_id) { - return $this->db->delete('programs', array('id' => $program_id)); + public function create($name) { + $this->load->helper('hash'); + + do { // generate unique hash + $id = random_hash('16'); + } while ($this->db->where('id', $id)->from('programs')->count_all_results() > 0); + + $this->db->insert('programs', array('id' => $id, 'name' => $name)); + + return $this->db->affected_rows() > 0 ? $id : false; + } + + /** + * Updates a program. + * + * @param string $name The new name of the program + * @param string $id The ID of the program to update + * @return boolean Returns TRUE if the update was successful + */ + public function update($name, $id) { + $this->db->update('programs', array('name' => $name), array('id' => $id)); + return $this->db->affected_rows() > 0; + } + + /** + * Deletes a program. + * + * @param string $programId The program ID to delete + * @return boolean Returns TRUE if the deletion was successful + */ + public function delete($programId) { + return $this->db->delete('programs', array('id' => $programId)); } /** @@ -59,13 +87,13 @@ class Program extends CI_Model { } /** - * Get a specific program. + * Gets a specific program. * - * @param string $prg_id The id of the program to get from the database + * @param string $id The id of the program to get from the database * @return array Declarative array with all available information of the program. */ - public function getById($prg_id) { - return $this->db->get_where('programs', array('id' => $prg_id))->row_array(); + public function getById($id) { + return $this->db->get_where('programs', array('id' => $id))->row_array(); } /** @@ -87,13 +115,13 @@ class Program extends CI_Model { * ) * ) * - * @param type $program_id The program for which we want to get the parameters. + * @param string $id The program for which we want to get the parameters. * @return array The parameters */ - public function getParameters($program_id) { - $query = $this->db->select('id, fieldname, readable, unit, description, type') - ->get_where('configuration_fields', array('program_id' => $program_id)); + public function getParameters($id) { + $query = $this->db->order_by('sort_number ASC') + ->get_where('parameters', array('program_id' => $id)); return $query->result_array(); } -} \ No newline at end of file +} diff --git a/application/models/user.php b/application/models/user.php index 4462a19..8f75d11 100644 --- a/application/models/user.php +++ b/application/models/user.php @@ -1,4 +1,4 @@ -hashPassword($new, $result->salt); if ($dbPassword === $old) { - // store the new password and reset the remember code so all remembered instances have to re-login + // reset the remember code so all remembered instances have to re-login $data = array('password' => $new, 'remember_code' => ''); $this->db->update('users', $data, array('username' => $username)); @@ -117,6 +131,7 @@ class User extends CI_Model { /** * Checks entered usernames. * + * @param string $username * @return boolean */ public function checkUsername($username = '') { @@ -129,6 +144,7 @@ class User extends CI_Model { /** * Checks entered emails. * + * @param string $email * @return boolean */ public function checkEmail($email = '') { @@ -141,6 +157,7 @@ class User extends CI_Model { /** * Inserts a forgotten password key. * + * @param string $email * @return boolean */ public function forgottenPassword($email = '') { @@ -158,8 +175,10 @@ class User extends CI_Model { } /** - * Forgotten Password Complete + * Completes the forgotten password procedure. * + * @param string $code + * @param boolean $salt * @return string */ public function forgottenPasswordComplete($code, $salt = false) { @@ -174,7 +193,7 @@ class User extends CI_Model { $data = array( 'password' => $this->hashPassword($password, $salt), - 'forgotten_password_code' => null + 'forgotten_password_code' => null, ); $this->db->update('users', $data, array('forgotten_password_code' => $code)); @@ -185,15 +204,18 @@ class User extends CI_Model { } /** - * profile + * Gets a users profile. * - * @return boolean|object + * @param string $username + * @param boolean $isCode + * @return mixed */ public function profile($username = '', $isCode = false) { if (empty($username)) { @$username = $this->session->userdata('username'); - if(empty($username)) - return FALSE; + if (empty($username)) { + return false; + } } $this->db->select('users.*, groups.name AS `group`, groups.description AS `group_description`'); @@ -207,7 +229,7 @@ class User extends CI_Model { $query = $this->db->limit(1)->get('users'); - return $query->num_rows > 0 ? $query->row() : false; + return $query->num_rows() > 0 ? $query->row_array() : false; } /** @@ -251,7 +273,6 @@ class User extends CI_Model { if ($this->storeSalt) { $data['salt'] = $salt; } - print_r($data); $this->db->insert('users', array_merge($data, $additionalData)); @@ -259,8 +280,11 @@ class User extends CI_Model { } /** - * login + * Validates the given password against the username. * + * @param string $username + * @param string $password + * @param boolean $remember * @return boolean */ public function login($username, $password, $remember = false) { @@ -300,8 +324,11 @@ class User extends CI_Model { } /** - * get + * Gets users. * + * @param mixed $group + * @param integer $limit + * @param integer $offset * @return object */ public function get($group = false, $limit = null, $offset = null) { @@ -332,6 +359,7 @@ class User extends CI_Model { /** * Returns the number of users. * + * @param mixed $group * @return integer The number of users */ public function count($group = false) { @@ -346,6 +374,7 @@ class User extends CI_Model { /** * Gets a user by ID. * + * @param string $id * @return array */ public function getUserByID($id = false) { @@ -353,74 +382,72 @@ class User extends CI_Model { return false; } - $this->db->where('users.id', $id); - $this->db->limit(1); + $this->db->where('users.id', $id)->limit(1); return $this->get()->row_array(); } /** - * getUserByEmail + * Gets a user by email. * - * @return object + * @param string $email + * @return array */ public function getUserByEmail($email) { - $this->db->where('users.email', $email); - $this->db->limit(1); - return $this->get(); + $this->db->where('users.email', $email)->limit(1); + return $this->get()->row_array(); } /** - * getUserByUsername + * Gets a user by username. * - * @return object + * @param string $username + * @return array */ public function getUserByUsername($username) { - $this->db->where('users.username', $username); - $this->db->limit(1); - return $this->get(); + $this->db->where('users.username', $username)->limit(1); + return $this->get()->row_array(); } /** - * getNewestUsers + * Gets a specified number of new users. * - * @return object + * @param integer $limit + * @return array */ public function getNewestUsers($limit = 10) { - $this->db->order_by('users.created_on DESC'); - $this->db->limit($limit); - return $this->get(); + $this->db->order_by('users.created_on DESC')->limit($limit); + return $this->get()->result_array(); } /** - * getUsersGroup + * Gets a users group. * - * @return object + * @param string $id + * @return array */ public function getUsersGroup($id = false) { // if no ID was passed use the current users ID $id || $id = $this->session->userdata('user_id'); - $user = $this->db->select('group_id')->where('id', $id)->get('users') - ->row(); + $user = $this->db->select('group_id')->where('id', $id)->get('users')->row(); return $this->db->select('name, description') - ->where('id', $user->group_id)->get('groups')->row(); + ->where('id', $user->group_id)->get('groups')->row_array(); } /** - * update + * Updates a user. * - * @return boolean + * @param string $id + * @param array $data + * @return boolean Returns TRUE if the update was successful. */ public function update($id, $data) { $user = $this->getUserByID($id); - $this->db->trans_begin(); - if (array_key_exists('username', $data) && $this->checkUsername($data['username']) && $user['username'] !== $data['username']) { - $this->db->trans_rollback(); - $this->access->setError('account_creation_duplicate_username'); + $this->messages->add(_('The entered username is already in use.'), 'error'); return false; } @@ -432,38 +459,25 @@ class User extends CI_Model { $this->db->update('users', $data, array('id' => $id)); } - if ($this->db->trans_status() === false) { - $this->db->trans_rollback(); - return false; - } - - $this->db->trans_commit(); - return true; + return $this->db->affected_rows() > 0; } /** - * Deletes the specified user. + * Deletes a specified user. * - * @return boolean + * @param string $id + * @return boolean Returns TRUE if the deletion was successful. */ public function delete($id) { - $this->db->trans_begin(); - $this->db->delete('users', array('id' => $id)); - - if ($this->db->trans_status() === false) { - $this->db->trans_rollback(); - return false; - } - - $this->db->trans_commit(); - return true; + return $this->db->affected_rows() > 0; } /** - * updateLastLogin + * Updates a users last login time. * - * @return boolean + * @param string $id + * @return boolean Returns TRUE if the update was successful. */ public function updateLastLogin($id) { $this->db->update('users', array('last_login' => now()), array('id' => $id)); @@ -471,7 +485,7 @@ class User extends CI_Model { } /** - * loginRemembedUser + * Logs a remembed user in. * * @return boolean */ @@ -512,8 +526,9 @@ class User extends CI_Model { } /** - * rememberUser + * Remembers a user. * + * @param string $id * @return boolean */ private function rememberUser($id) { @@ -542,7 +557,6 @@ class User extends CI_Model { } return false; } - } /* End of file user.php */ diff --git a/application/views/admin/parameters/create.php b/application/views/admin/parameters/create.php new file mode 100644 index 0000000..2aca436 --- /dev/null +++ b/application/views/admin/parameters/create.php @@ -0,0 +1,73 @@ +load->view('header');?> + +
+ +
+

+
+ +
+
+
    +
  • + + * +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
+

+ +

+
+
+
+ +load->view('footer');?> \ No newline at end of file diff --git a/application/views/admin/parameters/edit.php b/application/views/admin/parameters/edit.php new file mode 100644 index 0000000..1c233b4 --- /dev/null +++ b/application/views/admin/parameters/edit.php @@ -0,0 +1,74 @@ +load->view('header');?> + +
+ +
+

+
+ +
+
+
    +
  • + + * +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
+

+ + +

+
+
+
+ +load->view('footer');?> \ No newline at end of file diff --git a/application/views/admin/programs/edit.php b/application/views/admin/programs/edit.php new file mode 100644 index 0000000..825665b --- /dev/null +++ b/application/views/admin/programs/edit.php @@ -0,0 +1,74 @@ +load->view('header');?> + + + +
+ +
+ +
+

+
+ +
+
+

+
    +
  • + + * +
    + + +
    +
  • +
+

+ + +

+ +

+ + + + + + + + + + + + + + + + + + + + + +
 
|
+

+ +

+
+
+
+ +load->view('footer');?> \ No newline at end of file diff --git a/application/views/admin/programs/list.php b/application/views/admin/programs/list.php new file mode 100644 index 0000000..19f9e1f --- /dev/null +++ b/application/views/admin/programs/list.php @@ -0,0 +1,36 @@ +load->view('header');?> + +
+ +
+

+
+ +
+

+ + + + + + + + + + + + + + + +
|
+ +

+

+
+ +load->view('footer');?> diff --git a/application/views/admin/users/create.php b/application/views/admin/users/create.php index 9b88113..24bf724 100644 --- a/application/views/admin/users/create.php +++ b/application/views/admin/users/create.php @@ -12,6 +12,7 @@
  • + *
    @@ -20,6 +21,7 @@
  • + *
    @@ -27,6 +29,7 @@
  • + *
    @@ -34,6 +37,7 @@
  • + *
    @@ -41,6 +45,7 @@
  • + *
    @@ -48,6 +53,7 @@
  • + *
    @@ -71,13 +77,6 @@
  • -
  • - -
    - - -
    -

diff --git a/application/views/admin/users/edit.php b/application/views/admin/users/edit.php index 5e02f10..9e4ed0b 100644 --- a/application/views/admin/users/edit.php +++ b/application/views/admin/users/edit.php @@ -12,6 +12,7 @@

  • + *
    @@ -19,6 +20,7 @@
  • + *
    @@ -26,6 +28,7 @@
  • + *
    @@ -49,13 +52,6 @@
  • -
  • - -
    - - -
    -

diff --git a/application/views/admin/users/index.php b/application/views/admin/users/list.php similarity index 100% rename from application/views/admin/users/index.php rename to application/views/admin/users/list.php index 814dd39..3b73738 100644 --- a/application/views/admin/users/index.php +++ b/application/views/admin/users/list.php @@ -16,6 +16,7 @@ + @@ -27,7 +28,6 @@ - diff --git a/application/views/auth/email/forgot_password.php b/application/views/auth/email/forgot_password.php new file mode 100644 index 0000000..de0215b --- /dev/null +++ b/application/views/auth/email/forgot_password.php @@ -0,0 +1,11 @@ +, + +To reset your password, please go to the following page: + +{unwrap}{/unwrap} + +Your password will be automatically reset, and a new password will be emailed to you. + +If you do not wish to reset your password, ignore this message. It will expire in 24 hours. + +Thank you! diff --git a/application/views/auth/email/forgot_password_complete.php b/application/views/auth/email/forgot_password_complete.php new file mode 100644 index 0000000..3de3615 --- /dev/null +++ b/application/views/auth/email/forgot_password_complete.php @@ -0,0 +1,8 @@ +, + +Here is your new login information: + +Username: +Password: + +Thank you! diff --git a/application/views/auth/forgot_password.php b/application/views/auth/forgot_password.php new file mode 100644 index 0000000..64c5f69 --- /dev/null +++ b/application/views/auth/forgot_password.php @@ -0,0 +1,57 @@ + + + + + + +ScattPort | <?=_('Login');?> + + + + + + + + + + + +

+ +
+

Scattport

+ +" . _('Error') . ": " . $e . "

"; + } + } else if (isset($messages) && is_array($messages)) { + foreach ($messages as $m) { + echo "

" . _('Success') . ": " . $m . "

"; + } + } +?> +
+
    +
  • + +
    + + +
    +
  • +
  • +
    + +
    +
  • +
+
+ +

+
+
\ No newline at end of file diff --git a/application/views/auth/login.php b/application/views/auth/login.php index fef9817..6cf1ebb 100644 --- a/application/views/auth/login.php +++ b/application/views/auth/login.php @@ -1,60 +1,72 @@ - - + + - + - ScattPort | Login +ScattPort | <?=_('Login');?> - - - - - - + + + + + + -
+
-
-

Scattport Login

+
+

Scattport

-

- " . $e . "

"; - if (isset($notice)) - foreach ($notice as $n) - echo "
" . $n . "
"; - if (isset($success)) - foreach ($success as $s) - echo "
" . $s . "
"; - ?> -

+" . _('Error') . ": " . $e . "

"; + } + } else if (isset($messages) && is_array($messages)) { + foreach ($messages as $m) { + echo "

" . _('Success') . ": " . $m . "

"; + } + } +?> +
+
    +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • +
    + /> + +
    +
  • +
  • +
    + +
    +
  • +
+
-
-
    -
  • - -
    -
  • -
  • - -
    -
  • -
  • -
    - -
    -
  • -
-
- -

Passwort vergessen?

-
+

+
+ diff --git a/application/views/auth/settings.php b/application/views/auth/settings.php new file mode 100644 index 0000000..dcfb390 --- /dev/null +++ b/application/views/auth/settings.php @@ -0,0 +1,100 @@ +load->view('header');?> + +
+
+
+

+
+
    +
  • +
  • +
  • +
+ +
+
+
    +
  • + + * +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + + * +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
+
+
+
    +
  • + +
    + +
  • +
+
+
+
    +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
  • + +
    + + +
    +
  • +
+
+
+

+ +

+
+
+
+
+ +load->view('footer'); ?> diff --git a/application/views/dashboard.php b/application/views/dashboard.php index 13258f0..37ad1e1 100644 --- a/application/views/dashboard.php +++ b/application/views/dashboard.php @@ -21,7 +21,7 @@

- +

diff --git a/application/views/footer.php b/application/views/footer.php index 82678ca..0687b6c 100644 --- a/application/views/footer.php +++ b/application/views/footer.php @@ -1,12 +1,12 @@
diff --git a/application/views/user/index.html b/application/views/user/index.html deleted file mode 100755 index c942a79..0000000 --- a/application/views/user/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - \ No newline at end of file diff --git a/application/views/user/settings.php b/application/views/user/settings.php deleted file mode 100644 index 3914891..0000000 --- a/application/views/user/settings.php +++ /dev/null @@ -1,48 +0,0 @@ -load->view('header');?> - -
-
-
-

-
-
    -
  • -
  • -
- -
-
-
    - -
  • - -
    - -
    -
  • - -
-
-
-
    -
  • - -
    - -
    -
  • -
  • - -
    - -
  • -
-
-
-
-
- -load->view('footer'); ?> diff --git a/assets/css/form.css b/assets/css/form.css index 83aab14..4ab4f73 100644 --- a/assets/css/form.css +++ b/assets/css/form.css @@ -1,4 +1,5 @@ -/* Form Style */ +@CHARSET "UTF-8"; +/* Form styles */ form ul li { margin: 0 0 15px; @@ -50,16 +51,35 @@ select.drop { border: 1px solid #d2d2d2; } -input.short { width: 20%;} -input.medium { width: 45%;} -input.long { width:70%;} -input.max { width: 95%;} +input.short { + width: 20%; +} + +input.medium { + width: 45%; +} + +input.long { + width: 70%; +} + +input.max { + width: 95%; +} + +table input { + margin: 0 !important; +} p.success { color: #008000; } -p.error, p.req { +p.error, span.req { color: #d8122d; font-weight: normal; -} \ No newline at end of file +} + +p.success strong, p.error strong, p.req strong { + text-transform: uppercase; +} diff --git a/assets/css/login.css b/assets/css/login.css index 40c0895..3950461 100644 --- a/assets/css/login.css +++ b/assets/css/login.css @@ -12,11 +12,23 @@ body { background: #404040; } -a { color: #0088cc; text-decoration: none;} -a:hover { text-decoration: underline;} -a img { border: none;} +a { + color: #08c; + text-decoration: none; +} -p { margin: 0px 0px 20px 0px; line-height: 18px;} +a:hover { + text-decoration: underline; +} + +a img { + border: none; +} + +p { + margin: 0 0 20px 0; + line-height: 18px; +} #box { margin: 40px auto; @@ -36,4 +48,4 @@ p { margin: 0px 0px 20px 0px; line-height: 18px;} .light { color: #ccc; text-transform: none; -} \ No newline at end of file +} diff --git a/assets/css/style.css b/assets/css/style.css index 99d1102..e770c31 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -1,3 +1,5 @@ +@CHARSET "UTF-8"; + * { margin: 0; padding: 0; @@ -12,47 +14,75 @@ body { /* Styles */ -a { color: #0088cc; text-decoration: none;} -a:hover { text-decoration: underline;} -a img { border: none;} - -p { margin: 0px 0px 20px 0px; line-height: 18px;} - -ul { margin: 5px 0px 15px 0px; padding: 0px;} -li { margin-left: 20px;} - -div.notice { - margin: 0 0 15px; - padding: 0 10px; - background: #fffbcc; - border: 1px solid #e6db55; - line-height: 25px; - color: #222; +a { + color: #0088cc; + text-decoration: none; } -div.success { - margin: 0 0 15px; - padding: 0 10px; - background: #d1ecb8; - border: 1px solid #81c445; - line-height: 25px; - color: #222; +a:hover { + text-decoration: underline; } -div.error { - margin: 0 0 15px; - padding: 0 10px; - background: #ffebe8; - border: 1px solid #f0baa2; - line-height: 25px; - color: #222; +a img { + border: none; +} + +p { + margin: 0 0 20px 0; + line-height: 18px; +} + +ul { + margin: 5px 0 15px 0; + padding: 0; +} + +li { + margin-left: 20px; } .editable { background: #fffbcc; } -.clear { clear:both;} +.clear { + clear: both; +} + +/* Notifications */ + +#notifications div { + margin: 0 0 15px; + padding: 0 10px; + line-height: 25px; + color: #222; +} + +#notifications div a.cross { + float: right; + background: url(../images/icons/cross-small.png) right center no-repeat; + width: 16px; + height: 25px; +} + +#notifications div a.cross span { + display: none; +} + +div.notice { + background: #fffbcc; + border: 1px solid #e6db55; +} + +div.success { + background: #d1ecb8; + border: 1px solid #81c445; +} + +div.error { + background: #ffebe8; + border: 1px solid #f0baa2; +} /* Header */ @@ -78,7 +108,6 @@ div.error { #header .status { float: left; line-height: 45px; - padding: 12px 20px; } #header .menu { @@ -285,15 +314,22 @@ div.error { clear: both; } -#footer .left { float: left;} -#footer .right { float: right;} +#footer .left { + float: left; +} + +#footer .right { + float: right; +} /* Buttons */ + .buttons { float: left; padding-bottom: 20px; clear: both; } + a.button { color: #6e6e6e; font: bold 12px Helvetica, Arial, sans-serif; @@ -315,22 +351,28 @@ a.button { -moz-border-radius: 2px; margin-right: 10px; } + a.button.locked { color: #333; border-color: #999; - -moz-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2) -webkit-box-shadow:0 2px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); } + a.button:hover { color: #333; border-color: #999; - -moz-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2) -webkit-box-shadow:0 2px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); } + a.button:active { color: #000; border-color: #444; } + a.left { -webkit-border-top-right-radius: 0; -moz-border-radius-topright: 0; @@ -340,6 +382,7 @@ a.left { border-bottom-right-radius: 0; margin: 0; } + a.middle { border-radius: 0; -webkit-border-radius: 0; @@ -348,8 +391,12 @@ a.middle { margin: 0; border-left: solid 1px rgba(255, 255, 255, 0); } + a.middle:hover, -a.right:hover { border-left: solid 1px #999 } +a.right:hover { + border-left: solid 1px #999; +} + a.right { -webkit-border-top-left-radius: 0; -moz-border-radius-topleft: 0; @@ -360,68 +407,83 @@ a.right { border-left: solid 1px #f3f3f3; border-left: solid 1px rgba(255, 255, 255, 0); } + a.big { font-size: 16px; padding: 10px 15px; } + a.supersize { font-size: 20px; padding: 15px 20px; } + a.save { background: url(../images/icons/tick.png) 10px center no-repeat #f3f3f3; padding-left: 30px; } + a.add { background: url(../images/icons/plus-circle.png) 10px center no-repeat #f3f3f3; padding-left: 30px; } + a.delete { background: url(../images/button-sprite.png) 10px -59px no-repeat #f3f3f3; padding-left: 30px; } + a.flag { background: url(../images/button-sprite.png) 10px -94px no-repeat #f3f3f3; padding-left: 30px; } + a.cancel { background: url(../images/icons/slash.png) 10px center no-repeat #f3f3f3; padding-left: 30px; } + a.up { background: url(../images/button-sprite.png) 13px -131px no-repeat #f3f3f3; width: 18px; } + a.down { background: url(../images/button-sprite.png) 13px -166px no-repeat #f3f3f3; width: 18px; } + a.save-big { background: url(../images/button-sprite.png) 15px 13px no-repeat #f3f3f3; font-size: 16px; padding: 10px 15px 10px 35px; } + a.add-big { background: url(../images/button-sprite.png) 15px -21px no-repeat #f3f3f3; font-size: 16px; padding: 10px 15px 10px 35px; } + a.delete-big { background: url(../images/button-sprite.png) 15px -55px no-repeat #f3f3f3; font-size: 16px; padding: 10px 15px 10px 35px; } + a.flag-big { background: url(../images/button-sprite.png) 15px -90px no-repeat #f3f3f3; font-size: 16px; padding: 10px 15px 10px 35px; } + a.up-big { background: url(../images/button-sprite.png) 15px -126px no-repeat #f3f3f3; width: 18px; font-size: 16px; padding: 10px 15px; } + a.down-big { background: url(../images/button-sprite.png) 15px -161px no-repeat #f3f3f3; width: 18px; @@ -436,24 +498,26 @@ ul.tabs { padding: 0; float: left; list-style: none; - height: 27px; /*--Set height of tabs--*/ + height: 27px; /* Set height of tabs */ border-bottom: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8; width: 100%; } + ul.tabs li { float: left; margin: 0; padding: 0; - height: 26px; /*--Subtract 1px from the height of the unordered list--*/ - line-height: 26px; /*--Vertically aligns the text within the tab--*/ + height: 26px; /* Subtract 1px from the height of the unordered list */ + line-height: 26px; /* Vertically aligns the text within the tab */ border: 1px solid #e8e8e8; border-left: none; - margin-bottom: -1px; /*--Pull the list item down 1px--*/ + margin-bottom: -1px; /* Pull the list item down 1px */ overflow: hidden; position: relative; background: #e0e0e0 url('../images/navigation-off.gif'); } + ul.tabs li a { text-decoration: none; color: #000; @@ -461,20 +525,121 @@ ul.tabs li a { padding: 1px 21px; outline: none; } + ul.tabs li a:hover { background: #f0f0f0; } -html ul.tabs li.active, html ul.tabs li.active a:hover { /*--Makes sure that the active tab does not listen to the hover properties--*/ + +html ul.tabs li.active, +html ul.tabs li.active a:hover { background: #fff; - border-bottom: 1px solid #fff; /*--Makes the active tab look like it's connected with its content--*/ + border-bottom: 1px solid #fff; /* Makes the active tab look like it's connected with its content */ } .tab_container { + margin: 0 0 20px; + padding: 15px 15px 0 15px; border: 1px solid #e8e8e8; border-top: none; overflow: hidden; background: #fff; } + .tab_content { - padding: 20px; + padding: 0; +} + +.tab_buttons { + padding: 0; +} + +/* JTip styles */ + +.form_info a, +.form_info a:active, +.form_info a:visited { + background-color: #d2d2d2; + font-size: 12px; + font-weight: bold; + margin-left: -3px; + padding: 4px; + color: #fff; + text-decoration: none; +} + +.form_info a:hover { + color: #000; + text-decoration: none; +} + +#JT_arrow_left { + background: url(../images/arrow-left.gif) left top no-repeat; + position: absolute; + z-index: 101; + left: -11px; + height: 23px; + width: 10px; + top: -3px; +} + +#JT_arrow_right { + background: url(../images/arrow-right.gif) left top no-repeat; + position: absolute; + z-index: 101; + height: 23px; + width: 11px; + top: -2px; +} + +#JT { + position: absolute; + z-index: 100; + border: 1px solid #ccc; + background-color: #fff; + margin-top: 5px; + font-size: 85%; +} + +#JT_copy { + padding: 5px; + color: #666; +} + +.JT_loader { + background: url(../images/ajax-loader.gif) center center no-repeat; + width: 100%; + height: 12px; +} + +#JT_close_left { + background-color: #ccc; + text-align: left; + padding-left: 4px; + padding-bottom: 2px; + padding-top: 1px; + font-weight: bold; + color: #000; +} + +#JT_close_right { + background-color: #ccc; + text-align: left; + padding-left: 4px; + padding-bottom: 2px; + padding-top: 1px; + font-weight: bold; + color: #000; +} + +#JT_copy p { + margin: 3px 0; +} + +#JT_copy img { + padding: 1px; + border: 1px solid #ccc; +} + +.jTip { + cursor: help; } diff --git a/assets/css/table.css b/assets/css/table.css index d948c4d..5010dc6 100644 --- a/assets/css/table.css +++ b/assets/css/table.css @@ -1,4 +1,5 @@ -/* Table Style */ +@CHARSET "UTF-8"; +/* Table styles */ table { width: 99%; @@ -26,9 +27,17 @@ table td { border-bottom: 1px solid #d2d2d2; } -table td span.active { color: #55a34a;} -table td span.pending { color: #c5a059;} -table td span.closed { color: #a02b2b;} +table td span.active { + color: #55a34a; +} + +table td span.pending { + color: #c5a059; +} + +table td span.closed { + color: #a02b2b; +} table .odd { background: #f6f6f6; @@ -45,6 +54,16 @@ table .hover { table tbody tr:nth-child(even) { background: #fff; } + table tbody tr:nth-child(odd) { background: #f6f6f6; } + +td.drag_handle { + width: 16px; +} + +td.drag_handle-show { + background: url(../images/icons/arrow-resize-090.png) center center no-repeat; + cursor: move; +} diff --git a/assets/images/ajax-loader.gif b/assets/images/ajax-loader.gif new file mode 100644 index 0000000..b5ed0ce Binary files /dev/null and b/assets/images/ajax-loader.gif differ diff --git a/assets/images/arrow-left.gif b/assets/images/arrow-left.gif new file mode 100644 index 0000000..4c9e5c6 Binary files /dev/null and b/assets/images/arrow-left.gif differ diff --git a/assets/images/arrow-right.gif b/assets/images/arrow-right.gif new file mode 100644 index 0000000..3252c35 Binary files /dev/null and b/assets/images/arrow-right.gif differ diff --git a/assets/js/jtip.js b/assets/js/jtip.js new file mode 100644 index 0000000..d023e8f --- /dev/null +++ b/assets/js/jtip.js @@ -0,0 +1,158 @@ +/* + * JTip + * By Cody Lindley (http://www.codylindley.com) + * Under an Attribution, Share Alike License + * JTip is built on top of the very light weight jquery library. + */ + +/** + * On page load (as soon as it's ready) call JT_init + */ +$(document).ready(JT_init); + +/** + * Initializes JTip. + */ +function JT_init() { + $('a.jTip').hover(function() { + JT_show(this.href, this.id, this.name); + }, function() { + $('#JT').remove(); + }).click(function() { + return false; + }); +} + +/** + * Shows a tooltip. + * + * @param url + * @param linkId + * @param title + */ +function JT_show(url, linkId, title) { + if (title == false) title = ' '; + + var de = document.documentElement; + var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; + var hasArea = w - getAbsoluteLeft(linkId); + + var clickElementY = getAbsoluteTop(linkId) - 3; // set y position + var clickElementX = 0; + + var queryString = url.replace(/^[^\?]+\??/,''); + var params = parseQuery(queryString); + + if (params['width'] === undefined) { + params['width'] = 250; + } + if (params['link'] !== undefined) { + $('#' + linkId).bind('click', function() { + window.location = params['link']; + }); + $('#' + linkId).css('cursor','pointer'); + } + + if (hasArea > (params['width'] * 1) + 75) { + $('body').append('
' + title + '
'); // right side + var arrowOffset = getElementWidth(linkId) + 11; + clickElementX = getAbsoluteLeft(linkId) + arrowOffset; // set x position + } else { + $('body').append('
' + title + '
'); // left side + clickElementX = getAbsoluteLeft(linkId) - ((params['width']*1) + 15); //set x position + } + + $('#JT').css({ left: clickElementX + 'px', top: clickElementY + 'px' }); + $('#JT').show(); + $('#JT_copy').load(url); +} + +/** + * Gets the width of the tooltip. + * + * @param objectId + * @returns + */ +function getElementWidth(objectId) { + x = document.getElementById(objectId); + return x.offsetWidth; +} + +/** + * No description yet. + * + * @param objectId + * @returns + */ +function getAbsoluteLeft(objectId) { + // get an object left position from the upper left viewport corner + o = document.getElementById(objectId); + // get left position from the parent object + oLeft = o.offsetLeft; + // parse the parent hierarchy up to the document element + while (o.offsetParent != null) { + oParent = o.offsetParent; // get parent object reference + oLeft += oParent.offsetLeft; // add parent left position + o = oParent; + } + return oLeft; +} + +/** + * No description yet. + * + * @param objectId + * @returns + */ +function getAbsoluteTop(objectId) { + // get an object top position from the upper left viewport corner + o = document.getElementById(objectId); + // get top position from the parent object + oTop = o.offsetTop; + // parse the parent hierarchy up to the document element + while (o.offsetParent != null) { + oParent = o.offsetParent; // get parent object reference + oTop += oParent.offsetTop; // add parent top position + o = oParent; + } + return oTop; +} + +/** + * No description yet. + * + * @param query + */ +function parseQuery(query) { + var params = new Object(); + if (!query) { + return params; // return empty object + } + var pairs = query.split(/[;&]/); + + for (var i = 0; i < pairs.length; i++) { + var keyValue = pairs[i].split('='); + if (!keyValue || keyValue.length != 2) { + continue; + } + var key = unescape(keyValue[0]); + var val = unescape(keyValue[1]); + + val = val.replace(/\+/g, ' '); + params[key] = val; + } + return params; +} + +/** + * No description yet. + * + * @param event + */ +function blockEvents(event) { + if (event.target) { + event.preventDefault(); + } else { + event.returnValue = false; + } +} diff --git a/assets/js/scattport.js b/assets/js/scattport.js index 9b09d82..113aef8 100644 --- a/assets/js/scattport.js +++ b/assets/js/scattport.js @@ -67,35 +67,35 @@ $.fn.nl2br = function() { return $(this).html().replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2'); }; -/* - * Tabs - */ -$(document).ready(function() { - $(".tab_content").hide(); // hide all content - $("ul.tabs li:first").addClass("active").show(); // activate first tab - $(".tab_content:first").show(); // show first tab content - - // onClick event - $("ul.tabs li").click(function() { - - $("ul.tabs li").removeClass("active"); // remove any "active" class - $(this).addClass("active"); // add "active" class to selected tab - $(".tab_content").hide(); // hide all tab content - - var activeTab = $(this).find("a").attr("href"); - $(activeTab).fadeIn(); // fade in the active tab content - return false; - }); - - $('#notifications').hide(); - getNotifications(); - setInterval('getNotifications()', '5000'); -}); - /** * Do some stuff if document is ready. */ $(document).ready(function() { + /* + * Tabs + */ + $('.tab_content').hide(); // hide all content + $('ul.tabs li:first').addClass('active').show(); // activate first tab + $('.tab_content:first').show(); // show first tab content + + // onClick event + $('ul.tabs li').click(function() { + $('ul.tabs li').removeClass('active'); // remove any 'active' class + $(this).addClass('active'); // add 'active' class to selected tab + $('.tab_content').hide(); // hide all tab content + + var activeTab = $(this).find('a').attr('href'); + $(activeTab).fadeIn(); // fade in the active tab content + return false; + }); + + /* + * Notification stuff + */ + $('#notifications').hide(); + getNotifications(); + setInterval('getNotifications()', '5000'); + /* * Tables */ @@ -103,14 +103,14 @@ $(document).ready(function() { table_class : 'tableList' }; - // add or delete "hover" class on mouseOver event + // add or delete 'hover' class on mouseOver event $('.' + settings.table_class + ' tbody tr').hover(function() { - $(this).addClass("hover"); + $(this).addClass('hover'); }, function() { - $(this).removeClass("hover"); + $(this).removeClass('hover'); }); - // add or delete "selected" class if a row is selected via checkbox + // add or delete 'selected' class if a row is selected via checkbox $('.' + settings.table_class + ' tbody input:checkbox').click(function() { if ($(this).attr('checked') == true) { $(this).parent().parent().addClass('selected'); @@ -163,7 +163,18 @@ $(document).ready(function() { table.trigger('repaginate'); }); - $('.sortable').tableDnD(); + /* + * Sortable tables + */ + $('.sortable').tableDnD({ + dragHandle: 'drag_handle' + }); + + $('.sortable tr').hover(function() { + $(this).find('td.drag_handle').addClass('drag_handle-show'); + }, function() { + $(this).find('td.drag_handle').removeClass('drag_handle-show'); + }); /* * In-place editor @@ -187,6 +198,9 @@ $(document).ready(function() { $(this).removeClass('editable'); }); + /* + * Active project selection + */ $('select[name="activeProject"]').bind('change', function () { var url = $(this).val(); if (url) { diff --git a/assets/js/tablednd.jquery.js b/assets/js/tablednd.jquery.js index d4c9fec..df31193 100644 --- a/assets/js/tablednd.jquery.js +++ b/assets/js/tablednd.jquery.js @@ -5,7 +5,7 @@ * Licensed like jQuery, see http://docs.jquery.com/License. * * Configuration options: - * + * * onDragStyle * This is the style that is assigned to the row during drag. There are limitations to the styles that can be * associated with a row (such as you can't assign a border--well you can, but it won't be @@ -28,7 +28,7 @@ * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the * table and the row which the user has started to drag. * onAllowDrop - * Pass a function that will be called as a row is over another row. If the function returns true, allow + * Pass a function that will be called as a row is over another row. If the function returns true, allow * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. * scrollAmount @@ -40,7 +40,7 @@ * specify this class, then you are responsible for setting cursor: move in the CSS and only these cells * will have the drag behaviour. If you do not specify a dragHandle, then you get the old behaviour where * the whole row is draggable. - * + * * Other ways to control behaviour: * * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows @@ -52,7 +52,7 @@ * * Other methods: * - * $("...").tableDnDUpdate() + * $("...").tableDnDUpdate() * Will update all the matching tables, that is it will reapply the mousedown method to the rows (or handle cells). * This is useful if you have updated the table rows using Ajax and you want to make the table draggable again. * The table maintains the original configuration (so you don't have to specify it again). @@ -63,7 +63,7 @@ * * Known problems: * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 - * + * * Version 0.2: 2008-02-20 First public version * Version 0.3: 2008-02-07 Added onDragStart option * Made the scroll amount configurable (default is 5 as before) @@ -136,7 +136,7 @@ jQuery.tableDnD = { } return false; }); - }) + }); } else { // For backwards compatibility, we add the event to the whole row var rows = jQuery("tr", table); // get all the rows as a wrapped set @@ -167,7 +167,7 @@ jQuery.tableDnD = { if (this.tableDnDConfig) { jQuery.tableDnD.makeDraggable(this); } - }) + }); }, /** Get the mouse coordinates from the event (allowing for browser differences) */ @@ -241,7 +241,7 @@ jQuery.tableDnD = { } } - + if (mousePos.y-yOffset < config.scrollAmount) { window.scrollBy(0, -config.scrollAmount); } else { @@ -371,12 +371,10 @@ jQuery.tableDnD = { return result; } -} +}; -jQuery.fn.extend( - { - tableDnD : jQuery.tableDnD.build, - tableDnDUpdate : jQuery.tableDnD.updateTables, - tableDnDSerialize: jQuery.tableDnD.serializeTables - } -); \ No newline at end of file +jQuery.fn.extend({ + tableDnD : jQuery.tableDnD.build, + tableDnDUpdate : jQuery.tableDnD.updateTables, + tableDnDSerialize: jQuery.tableDnD.serializeTables +});