* Completed backend users (admins, providers, secretaries) management.

This commit is contained in:
alextselegidis@gmail.com 2013-09-03 18:58:56 +00:00
parent b5e771339c
commit 500ad49c23
14 changed files with 2014 additions and 112 deletions

View file

@ -371,7 +371,7 @@ class Appointments extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array( exceptionToJavascript($exc) )
'exceptions' => array( exceptionToJavaScript($exc) )
));
}
}
@ -422,7 +422,7 @@ class Appointments extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}

View file

@ -109,9 +109,9 @@ class Backend extends CI_Controller {
$view['base_url'] = $this->config->item('base_url');
$view['company_name'] = $this->settings_model->get_setting('company_name');
$view['admins'] = $this->admins_model->get_batch();
$view['providers'] = $this->providers_model->get_batch();
$view['secretaries'] = $this->secretaries_model->get_batch();
$view['admins'] = $this->admins_model->get_batch();
$view['services'] = $this->services_model->get_batch();
$this->load->view('backend/header', $view);

View file

@ -60,7 +60,7 @@ class Backend_api extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -135,7 +135,7 @@ class Backend_api extends CI_Controller {
}
}
} catch(Exception $exc) {
$warnings[] = exceptionToJavascript($exc);
$warnings[] = exceptionToJavaScript($exc);
}
// :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER
@ -176,7 +176,7 @@ class Backend_api extends CI_Controller {
$provider_message, $provider_link, $provider['email']);
} catch(Exception $exc) {
$warnings[] = exceptionToJavascript($exc);
$warnings[] = exceptionToJavaScript($exc);
}
if (!isset($warnings)) {
@ -188,7 +188,7 @@ class Backend_api extends CI_Controller {
}
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -243,7 +243,7 @@ class Backend_api extends CI_Controller {
$this->google_sync->delete_appointment($appointment['id_google_calendar']);
}
} catch(Exception $exc) {
$warnings[] = exceptionToJavascript($exc);
$warnings[] = exceptionToJavaScript($exc);
}
}
@ -257,7 +257,7 @@ class Backend_api extends CI_Controller {
$service, $customer, $company_settings, $customer['email'],
$_POST['delete_reason']);
} catch(Exception $exc) {
$warnings[] = exceptionToJavascript($exc);
$warnings[] = exceptionToJavaScript($exc);
}
// :: SEND RESPONSE TO CLIENT BROWSER
@ -270,7 +270,7 @@ class Backend_api extends CI_Controller {
}
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -298,7 +298,7 @@ class Backend_api extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -347,7 +347,7 @@ class Backend_api extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -402,7 +402,7 @@ class Backend_api extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -446,7 +446,7 @@ class Backend_api extends CI_Controller {
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -464,7 +464,7 @@ class Backend_api extends CI_Controller {
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -481,7 +481,7 @@ class Backend_api extends CI_Controller {
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -499,7 +499,7 @@ class Backend_api extends CI_Controller {
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -516,7 +516,7 @@ class Backend_api extends CI_Controller {
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -539,7 +539,7 @@ class Backend_api extends CI_Controller {
echo json_encode($services);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -558,7 +558,7 @@ class Backend_api extends CI_Controller {
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -575,7 +575,7 @@ class Backend_api extends CI_Controller {
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
@ -595,7 +595,199 @@ class Backend_api extends CI_Controller {
echo json_encode($categories);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavascript($exc))
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Filter admin records with string key.
*
* @param string $_POST['key'] The key string used to filter the records.
* @return array Returns a json encoded array back to client with the admin records.
*/
public function ajax_filter_admins() {
try {
$this->load->model('admins_model');
$key = $_POST['key']; // @task sql injection
$where =
'(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' .
'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' .
'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' .
'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' .
'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")';
$admins = $this->admins_model->get_batch($where);
echo json_encode($admins);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Save (insert or update) admin record into database.
*
* @param array $_POST['admin'] A json encoded array that contains the admin data. If an 'id'
* value is provided then the record is going to be updated.
* @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that
* everything completed successfully.
*/
public function ajax_save_admin() {
try {
$this->load->model('admins_model');
$admin = json_decode($_POST['admin'], true);
$this->admins_model->add($admin);
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Delete an admin record from the database.
*
* @param numeric $_POST['admin_id'] The id of the record to be deleted.
* @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE).
*/
public function ajax_delete_admin() {
try {
$this->load->model('admins_model');
$result = $this->admins_model->delete($_POST['admin_id']);
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Filter provider records with string key.
*
* @param string $_POST['key'] The key string used to filter the records.
* @return array Returns a json encoded array back to client with the provider records.
*/
public function ajax_filter_providers() {
try {
$this->load->model('providers_model');
$key = $_POST['key']; // @task sql injection
$where =
'(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' .
'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' .
'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' .
'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' .
'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")';
$providers = $this->providers_model->get_batch($where);
echo json_encode($providers);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Save (insert or update) a provider record into database.
*
* @param array $_POST['provider'] A json encoded array that contains the provider data. If an 'id'
* value is provided then the record is going to be updated.
* @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that
* everything completed successfully.
*/
public function ajax_save_provider() {
try {
$this->load->model('providers_model');
$provider = json_decode($_POST['provider'], true);
$this->providers_model->add($provider);
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Delete a provider record from the database.
*
* @param numeric $_POST['provider_id'] The id of the record to be deleted.
* @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE).
*/
public function ajax_delete_provider() {
try {
$this->load->model('providers_model');
$result = $this->providers_model->delete($_POST['provider_id']);
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Filter secretary records with string key.
*
* @param string $_POST['key'] The key string used to filter the records.
* @return array Returns a json encoded array back to client with the secretary records.
*/
public function ajax_filter_secretaries() {
try {
$this->load->model('secretaries_model');
$key = $_POST['key']; // @task sql injection
$where =
'(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' .
'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' .
'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' .
'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' .
'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")';
$secretaries = $this->secretaries_model->get_batch($where);
echo json_encode($secretaries);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Save (insert or update) a secretary record into database.
*
* @param array $_POST['secretary'] A json encoded array that contains the secretary data.
* If an 'id' value is provided then the record is going to be updated.
* @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that
* everything completed successfully.
*/
public function ajax_save_secretary() {
try {
$this->load->model('secretaries_model');
$secretary = json_decode($_POST['secretary'], true);
$this->secretaries_model->add($secretary);
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
/**
* [AJAX] Delete a secretary record from the database.
*
* @param numeric $_POST['secretary_id'] The id of the record to be deleted.
* @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE).
*/
public function ajax_delete_secretary() {
try {
$this->load->model('secretaries_model');
$result = $this->secretaries_model->delete($_POST['secretary_id']);
echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}

View file

@ -60,7 +60,7 @@ function exceptionToHtml($exc) {
* @param Exception $exception The given exception object.
* @return string Returns the json encoded object of the exception.
*/
function exceptionToJavascript($exception) {
function exceptionToJavaScript($exception) {
return json_encode(array(
'code' => $exception->getCode(),
'file' => $exception->getFile(),

View file

@ -55,12 +55,12 @@ class Unit_tests extends CI_Driver_Library {
*/
public function run_model_tests($output_report = true) {
// @task Reenable all model tests.
// $this->appointments_model->run_all();
// $this->customers_model->run_all();
// $this->settings_model->run_all();
// $this->providers_model->run_all();
// $this->services_model->run_all();
// $this->admins_model->run_all();
$this->appointments_model->run_all();
$this->customers_model->run_all();
$this->settings_model->run_all();
$this->providers_model->run_all();
$this->services_model->run_all();
$this->admins_model->run_all();
$this->secretaries_model->run_all();
if ($output_report) {

View file

@ -4,6 +4,7 @@ class Unit_tests_admins_model extends CI_Driver {
private $ci;
private $admin_role_id;
private $default_admin; // does not contain an 'id' value
private $default_settings; // does not contain 'id_users' value
/**
* Class Constructor
@ -29,6 +30,17 @@ class Unit_tests_admins_model extends CI_Driver {
'notes' => 'This is a test admin user.',
'id_roles' => $this->admin_role_id
);
$this->default_settings = array(
'username' => 'test_admin',
'password' => 'test_pswd',
'working_plan' => NULL,
'notifications' => FALSE,
'google_sync' => FALSE,
'google_token' => NULL,
'sync_past_days' => NULL,
'sync_future_days' => NULL
);
}
/**

View file

@ -59,6 +59,7 @@ class Unit_tests_secretaries_model extends CI_Driver {
. 'has returned and integer value.');
$db_secretary = $this->ci->db->get_where('ea_users', array('id' => $secretary['id']))->row_array();
$db_secretary['providers'] = array();
$this->ci->unit->run($secretary, $db_secretary, 'Test if add() - insert operation - '
. 'has successfully inserted a new record.');
@ -88,6 +89,7 @@ class Unit_tests_secretaries_model extends CI_Driver {
. 'returned an integer value.');
$db_secretary = $this->ci->db->get_where('ea_users', array('id' => $secretary['id']))->row_array();
$db_secretary['providers'] = array();
$this->ci->unit->run($secretary, $db_secretary, 'Test if add() - update operation - has '
. 'successfully updated the secretary record.');
@ -125,6 +127,7 @@ class Unit_tests_secretaries_model extends CI_Driver {
. 'returned and integer value.');
$db_secretary = $this->ci->db->get_where('ea_users', array('id' => $secretary_id))->row_array();
$db_secretary['providers'] = array();
unset($db_secretary['id']);
$this->ci->unit->run($secretary, $db_secretary, 'Test if add() - update operation - has '
. 'successfully updated the secretary record using find_record_id() method '
@ -323,9 +326,14 @@ class Unit_tests_secretaries_model extends CI_Driver {
private function test_get_row_record_does_not_exist() {
$random_id = 2309203923; // no record exists with this id.
$model_secretary = $this->ci->secretaries_model->get_row($random_id);
$this->ci->unit->run($model_secretary, array(), 'Test if get_row() has returned an empty '
. 'array on record that does not exist.');
$has_thrown_exc = FALSE;
try {
$this->ci->secretaries_model->get_row($random_id);
} catch (Exception $exc) {
$has_thrown_exc = TRUE;
}
$this->ci->unit->run($has_thrown_exc, TRUE, 'Test if get_row() has thrown an exception '
. 'when trying to get a record that does not exist in the database.');
}
// TEST GET VALUE METHOD --------------------------------------------------

View file

@ -17,6 +17,7 @@
* 'zip_code'
* 'notes'
* 'id_roles'
* 'settings' >>> array that contains user settings (username, password etc)
*/
class Admins_Model extends CI_Model {
/**
@ -85,12 +86,27 @@ class Admins_Model extends CI_Model {
*/
public function insert($admin) {
$admin['id_roles'] = $this->get_admin_role_id();
$settings = $admin['settings'];
unset($admin['settings']);
$this->db->trans_begin();
if (!$this->db->insert('ea_users', $admin)) {
throw new Exception('Could not insert admin into the database.');
}
return intval($this->db->insert_id());
$admin['id'] = intval($this->db->insert_id());
$settings['id_users'] = $admin['id'];
// Insert admin settings.
if (!$this->db->insert('ea_user_settings', $settings)) {
$this->db->trans_rollback();
throw new Exception('Could not insert admin settings into the database.');
}
$this->db->trans_complete();
return $admin['id'];
}
/**
@ -101,11 +117,20 @@ class Admins_Model extends CI_Model {
* @throws Exception When the update operation fails.
*/
public function update($admin) {
$settings = $admin['settings'];
unset($admin['settings']);
$settings['id_users'] = $admin['id'];
$this->db->where('id', $admin['id']);
if (!$this->db->update('ea_users', $admin)){
if (!$this->db->update('ea_users', $admin)) {
throw new Exception('Could not update admin record.');
}
$this->db->where('id_users', $settings['id_users']);
if (!$this->db->update('ea_user_settings', $settings)) {
throw new Exception('Could not update admin settings.');
}
return intval($admin['id']);
}
@ -218,6 +243,10 @@ class Admins_Model extends CI_Model {
}
$admin = $this->db->get_where('ea_users', array('id' => $admin_id))->row_array();
$admin['settings'] = $this->db->get_where('ea_user_settings',
array('id_users' => $admin_id))->row_array();
unset($admin['settings']['id_users']);
return $admin;
}
@ -272,8 +301,14 @@ class Admins_Model extends CI_Model {
$this->db->where($where_clause);
}
$this->db->where('id_roles', $role_id);
$batch = $this->db->get('ea_users')->result_array();
$batch = $this->db->get_where('ea_users', array('id_roles' => $role_id))->result_array();
// Get every admin settings.
foreach ($batch as &$admin) {
$admin['settings'] = $this->db->get_where('ea_user_settings',
array('id_users' => $admin['id']))->row_array();
unset($admin['settings']['id_users']);
}
return $batch;
}

View file

@ -17,7 +17,7 @@
* 'zip_code'
* 'notes'
* 'id_roles'
* 'provders' >> array with provider ids that the secretary handles
* 'providers' >> array with provider ids that the secretary handles
*/
class Secretaries_Model extends CI_Model {
/**
@ -38,7 +38,7 @@ class Secretaries_Model extends CI_Model {
if (!$this->validate($secretary)) {
throw new Exception('Secretary data are invalid: ' . print_r($secretary, TRUE));
}
if ($this->exists($secretary) && !isset($secretary['id'])) {
$secretary['id'] = $this->find_record_id($secretary);
}
@ -87,7 +87,9 @@ class Secretaries_Model extends CI_Model {
public function insert($secretary) {
$providers = $secretary['providers'];
unset($secretary['providers']);
$settings = $secretary['settings'];
unset($secretary['settings']);
$secretary['id_roles'] = $this->get_secretary_role_id();
if (!$this->db->insert('ea_users', $secretary)) {
@ -96,7 +98,8 @@ class Secretaries_Model extends CI_Model {
$secretary['id'] = intval($this->db->insert_id());
$this->save_providers($providers,$secretary['id']);
$this->save_providers($providers, $secretary['id']);
$this->save_settings($settings, $secretary['id']);
return $secretary['id'];
}
@ -111,6 +114,8 @@ class Secretaries_Model extends CI_Model {
public function update($secretary) {
$providers = $secretary['providers'];
unset($secretary['providers']);
$settings = $secretary['settings'];
unset($secretary['settings']);
$this->db->where('id', $secretary['id']);
if (!$this->db->update('ea_users', $secretary)){
@ -118,6 +123,7 @@ class Secretaries_Model extends CI_Model {
}
$this->save_providers($providers, $secretary['id']);
$this->save_settings($settings, $secretary['id']);
return intval($secretary['id']);
}
@ -170,7 +176,7 @@ class Secretaries_Model extends CI_Model {
}
// Validate 'providers' value datatype (must be array)
if (isset($secretary['provders']) && !is_array($secretary['providers'])) {
if (isset($secretary['providers']) && !is_array($secretary['providers'])) {
throw new Exception('Secretary providers value is not an array.');
}
@ -218,15 +224,30 @@ class Secretaries_Model extends CI_Model {
* @param numeric $secretary_id The id of the record to be returned.
* @return array Returns an array with the secretary user data.
* @throws Exception When the $secretary_id is not a valid numeric value.
* @throws Exception When given record id does not exist in the database.
*/
public function get_row($secretary_id) {
if (!is_numeric($secretary_id)) {
throw new Exception('$secretary_id argument is not a valid numeric value: ' . $secretary_id);
}
// Check if record exists
if ($this->db->get_where('ea_users', array('id' => $secretary_id))->num_rows() == 0) {
throw new Exception('The given secretary id does not match a record in the database.');
}
$secretary = $this->db->get_where('ea_users', array('id' => $secretary_id))->row_array();
$secretary['providers'] = $this->db->get_where('ea_secretaries_providers',
array('id_users_secretary' => $secretary_id))->result_array();
$secretary_providers = $this->db->get_where('ea_secretaries_providers',
array('id_users_secretary' => $secretary['id']))->result_array();
$secretary['providers'] = array();
foreach($secretary_providers as $secretary_provider) {
$secretary['providers'][] = $secretary_provider['id_users_provider'];
}
$secretary['settings'] = $this->db->get_where('ea_user_settings',
array('id_users' => $secretary['id']))->row_array();
return $secretary;
}
@ -285,10 +306,18 @@ class Secretaries_Model extends CI_Model {
$this->db->where('id_roles', $role_id);
$batch = $this->db->get('ea_users')->result_array();
// Include every secretary handling users.
// Include every secretary providers.
foreach ($batch as &$secretary) {
$secretary['providers'] = $this->db->get_where('ea_secretaries_providers',
$secretary_providers = $this->db->get_where('ea_secretaries_providers',
array('id_users_secretary' => $secretary['id']))->result_array();
$secretary['providers'] = array();
foreach($secretary_providers as $secretary_provider) {
$secretary['providers'][] = $secretary_provider['id_users_provider'];
}
$secretary['settings'] = $this->db->get_where('ea_user_settings',
array('id_users' => $secretary['id']))->row_array();
}
return $batch;
@ -313,6 +342,9 @@ class Secretaries_Model extends CI_Model {
throw new Exception('Invalid argument given $providers: ' . print_r($providers, TRUE));
}
// Delete old connections
$this->db->delete('ea_secretaries_providers', array('id_users_secretary' => $secretary_id));
if (count($providers) > 0) {
foreach ($providers as $provider_id) {
$this->db->insert('ea_secretaries_providers', array(
@ -322,6 +354,60 @@ class Secretaries_Model extends CI_Model {
}
}
}
/**
* Save the secretary settings (used from insert or update operation).
*
* @param array $settings Contains the setting values.
* @param numeric $secretary_id Record id of the secretary.
*/
private function save_settings($settings, $secretary_id) {
if (!is_numeric($secretary_id)) {
throw new Exception('Invalid $provider_id argument given :' . $secretary_id);
}
if (count($settings) == 0 || !is_array($settings)) {
throw new Exception('Invalid $settings argument given:' . print_r($settings, TRUE));
}
// Check if the setting record exists in db.
if ($this->db->get_where('ea_user_settings', array('id_users' => $secretary_id))
->num_rows() == 0) {
$this->db->insert('ea_user_settings', array('id_users' => $secretary_id));
}
foreach($settings as $name=>$value) {
$this->set_setting($name, $value, $secretary_id);
}
}
/**
* Get a providers setting from the database.
*
* @param string $setting_name The setting name that is going to be
* returned.
* @param int $secretary_id The selected provider id.
* @return string Returs the value of the selected user setting.
*/
public function get_setting($setting_name, $secretary_id) {
$provider_settings = $this->db->get_where('ea_user_settings',
array('id_users' => $secretary_id))->row_array();
return $provider_settings[$setting_name];
}
/**
* Set a provider's setting value in the database.
*
* The provider and settings record must already exist.
*
* @param string $setting_name The setting's name.
* @param string $value The setting's value.
* @param numeric $secretary_id The selected provider id.
*/
public function set_setting($setting_name, $value, $secretary_id) {
$this->db->where(array('id_users' => $secretary_id));
return $this->db->update('ea_user_settings', array($setting_name => $value));
}
}
/* End of file secretaries_model.php */

View file

@ -1,4 +1,312 @@
<h1>Please Implement This Page!</h1>
<p>
This is something totally random.
</p>
<script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/backend_users.js"></script>
<script type="text/javascript">
var GlobalVariables = {
'baseUrl': <?php echo '"' . $base_url . '"'; ?>,
'admins': <?php echo json_encode($admins); ?>,
'providers': <?php echo json_encode($providers); ?>,
'secretaries': <?php echo json_encode($secretaries); ?>,
'services': <?php echo json_encode($services); ?>
};
$(document).ready(function() {
BackendUsers.initialize(true);
});
</script>
<div id="users-page" class="row-fluid">
<?php // Page Tabs ?>
<ul class="nav nav-tabs">
<li class="admins-tab tab active"><a>Admins</a></li>
<li class="providers-tab tab"><a>Providers</a></li>
<li class="secretaries-tab tab"><a>Secretaries</a></li>
</ul>
<?php // Admin Tab ?>
<div id="admins" class="tab-content">
<div class="filter span4">
<div class="input-append">
<input class="filter-key span12" type="text" />
<button class="filter-admins btn" type="button">Filter</button>
</div>
<h2>Admins</h2>
<div class="filter-results"></div>
</div>
<div class="details span7">
<div class="btn-toolbar">
<div class="add-edit-delete-group btn-group">
<button id="add-admin" class="btn">
<i class="icon-plus"></i>
Add</button>
<button id="edit-admin" class="btn" disabled="disabled">
<i class="icon-pencil"></i>
Edit</button>
<button id="delete-admin" class="btn" disabled="disabled">
<i class="icon-remove"></i>
Delete</button>
</div>
<div class="save-cancel-group btn-group" style="display:none;">
<button id="save-admin" class="btn">
<i class="icon-ok"></i>
Save</button>
<button id="cancel-admin" class="btn">
<i class="icon-ban-circle"></i>
Cancel</button>
</div>
</div>
<h2>Details</h2>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="admin-id" />
<div class="row-fluid">
<div class="admin-details span6">
<label for="first-name">First Name</label>
<input type="text" id="admin-first-name" class="span11" />
<label for="admin-last-name">Last Name *</label>
<input type="text" id="admin-last-name" class="span11 required" />
<label for="admin-email">Email *</label>
<input type="text" id="admin-email" class="span11 required" />
<label for="admin-mobile-number">Mobile Number</label>
<input type="text" id="admin-mobile-number" class="span11" />
<label for="admin-phone-number">Phone Number *</label>
<input type="text" id="admin-phone-number" class="span11 required" />
<label for="admin-address">Address</label>
<input type="text" id="admin-address" class="span11" />
<label for="admin-city">City</label>
<input type="text" id="admin-city" class="span11" />
<label for="admin-state">State</label>
<input type="text" id="admin-state" class="span11" />
<label for="admin-zip-code">Zip Code</label>
<input type="text" id="admin-zip-code" class="span11" />
<label for="admin-notes">Notes</label>
<textarea id="admin-notes" class="span11"></textarea>
</div>
<div class="admin-settings span6">
<label for="admin-username">Username *</label>
<input type="text" id="admin-username" class="span7 required" />
<label for="admin-password">Password *</label>
<input type="password" id="admin-password" class="span7 required"/>
<label for="admin-password-confirm">Retype Password *</label>
<input type="password" id="admin-password-confirm" class="span7 required" />
<button type="button" id="admin-notifications" class="btn" data-toggle="button">
<i class="icon-asterisk"></i>
<span>Receive Notifications</span>
</button>
</div>
</div>
</div>
</div>
<?php // Providers Tab ?>
<div id="providers" class="tab-content" style="display:none;">
<div class="filter span4">
<div class="input-append">
<input class="filter-key span12" type="text" />
<button class="filter-providers btn" type="button">Filter</button>
</div>
<h2>Providers</h2>
<div class="filter-results"></div>
</div>
<div class="details span7">
<div class="btn-toolbar">
<div class="add-edit-delete-group btn-group">
<button id="add-provider" class="btn">
<i class="icon-plus"></i>
Add</button>
<button id="edit-provider" class="btn" disabled="disabled">
<i class="icon-pencil"></i>
Edit</button>
<button id="delete-provider" class="btn" disabled="disabled">
<i class="icon-remove"></i>
Delete</button>
</div>
<div class="save-cancel-group btn-group" style="display:none;">
<button id="save-provider" class="btn">
<i class="icon-ok"></i>
Save</button>
<button id="cancel-provider" class="btn">
<i class="icon-ban-circle"></i>
Cancel</button>
</div>
</div>
<h2>Details</h2>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="provider-id" />
<div class="row-fluid">
<div class="provider-details span6">
<label for="provider-first-name">First Name</label>
<input type="text" id="provider-first-name" class="span11" />
<label for="provider-last-name">Last Name *</label>
<input type="text" id="provider-last-name" class="span11 required" />
<label for="provider-email">Email *</label>
<input type="text" id="provider-email" class="span11 required" />
<label for="provider-mobile-number">Mobile Number</label>
<input type="text" id="provider-mobile-number" class="span11" />
<label for="provider-phone-number">Phone Number *</label>
<input type="text" id="provider-phone-number" class="span11 required" />
<label for="provider-address">Address</label>
<input type="text" id="provider-address" class="span11" />
<label for="provider-city">City</label>
<input type="text" id="provider-city" class="span11" />
<label for="provider-state">State</label>
<input type="text" id="provider-state" class="span11" />
<label for="provider-zip-code">Zip Code</label>
<input type="text" id="provider-zip-code" class="span11" />
<label for="provider-notes">Notes</label>
<textarea id="provider-notes" class="span11"></textarea>
</div>
<div class="provider-settings span6">
<label for="provider-username">Username *</label>
<input type="text" id="provider-username" class="span7 required" />
<label for="provider-password">Password *</label>
<input type="password" id="provider-password" class="span7 required"/>
<label for="provider-password-confirm">Retype Password *</label>
<input type="password" id="provider-password-confirm" class="span7 required" />
<button type="button" id="provider-notifications" class="btn" data-toggle="button">
<i class="icon-asterisk"></i>
<span>Receive Notifications</span>
</button>
<br><br>
<h4>Services</h4>
<div id="provider-services"></div>
</div>
</div>
</div>
</div>
<?php // Secretaries Tab ?>
<div id="secretaries" class="tab-content" style="display:none;">
<div class="filter span4">
<div class="input-append">
<input class="filter-key span12" type="text" />
<button class="filter-secretaries btn" type="button">Filter</button>
</div>
<h2>Secretaries</h2>
<div class="filter-results"></div>
</div>
<div class="details span7">
<div class="btn-toolbar">
<div class="add-edit-delete-group btn-group">
<button id="add-secretary" class="btn">
<i class="icon-plus"></i>
Add</button>
<button id="edit-secretary" class="btn" disabled="disabled">
<i class="icon-pencil"></i>
Edit</button>
<button id="delete-secretary" class="btn" disabled="disabled">
<i class="icon-remove"></i>
Delete</button>
</div>
<div class="save-cancel-group btn-group" style="display:none;">
<button id="save-secretary" class="btn">
<i class="icon-ok"></i>
Save</button>
<button id="cancel-secretary" class="btn">
<i class="icon-ban-circle"></i>
Cancel</button>
</div>
</div>
<h2>Details</h2>
<div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="secretary-id" />
<div class="row-fluid">
<div class="secretary-details span6">
<label for="secretary-first-name">First Name</label>
<input type="text" id="secretary-first-name" class="span11" />
<label for="secretary-last-name">Last Name *</label>
<input type="text" id="secretary-last-name" class="span11 required" />
<label for="secretary-email">Email *</label>
<input type="text" id="secretary-email" class="span11 required" />
<label for="secretary-mobile-number">Mobile Number</label>
<input type="text" id="secretary-mobile-number" class="span11" />
<label for="secretary-phone-number">Phone Number *</label>
<input type="text" id="secretary-phone-number" class="span11 required" />
<label for="secretary-address">Address</label>
<input type="text" id="secretary-address" class="span11" />
<label for="secretary-city">City</label>
<input type="text" id="secretary-city" class="span11" />
<label for="secretary-state">State</label>
<input type="text" id="secretary-state" class="span11" />
<label for="secretary-zip-code">Zip Code</label>
<input type="text" id="secretary-zip-code" class="span11" />
<label for="secretary-notes">Notes</label>
<textarea id="secretary-notes" class="span11"></textarea>
</div>
<div class="secretary-settings span6">
<label for="secretary-username">Username *</label>
<input type="text" id="secretary-username" class="span7 required" />
<label for="secretary-password">Password *</label>
<input type="password" id="secretary-password" class="span7 required"/>
<label for="secretary-password-confirm">Retype Password *</label>
<input type="password" id="secretary-password-confirm" class="span7 required" />
<button type="button" id="secretary-notifications" class="btn" data-toggle="button">
<i class="icon-asterisk"></i>
<span>Receive Notifications</span>
</button>
<br><br>
<h4>Services</h4>
<div id="secretary-providers"></div>
</div>
</div>
</div>
</div>
</div>

View file

@ -13,92 +13,309 @@ root {
background-color: #35B66F;
border-bottom: 6px solid #247A4B;
}
#header #header-logo { display: inline-block; height: 60px; margin: 10px 15px 0px 15px; }
#header #header-logo img { float: left; width: 50px; height: 50px; margin-right: 6px; }
#header #header-logo span { float: left; font-size: 20px; color: white; margin-top: 16px; }
#header #header-menu { display: inline-block; float: right; height: 100%; }
#header #header-menu .menu-item { float: left; margin-right: 8px; margin-top: 10px;
padding: 15px 12px; min-width: 68px; text-align: center;
font-weight: bold; color: #FFF; text-decoration: none;
font-size: 16px; }
#header #header-menu .menu-item:hover { background-color: #247A4B; }
#header #header-logo {
display: inline-block;
height: 60px;
margin: 10px 15px 0px 15px;
}
#header #header-logo img {
float: left;
width: 50px;
height: 50px;
margin-right: 6px;
}
#header #header-logo span {
float: left;
font-size: 20px;
color: white;
margin-top: 16px;
}
#header #header-menu {
display: inline-block;
float: right;
height: 100%;
}
#header #header-menu .menu-item {
float: left;
margin-right: 8px;
margin-top: 10px;
padding: 15px 12px;
min-width: 68px;
text-align: center;
font-weight: bold;
color: #FFF;
text-decoration: none;
font-size: 16px;
}
#header #header-menu .menu-item:hover {
background-color: #247A4B;
}
#footer {
background-color: #F7F7F7;
border-top: 1px solid #DDD;
}
#footer #footer-content { padding: 15px; }
#footer #footer-content {
padding: 15px;
}
#notification strong { margin-right: 15px; }
#loading { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 999999;
background: rgba(255, 255, 255, 0.75);}
#loading img { margin: auto; display: block; }
#notification strong {
margin-right: 15px;
}
#modal-message { margin: 10px 0px; }
#loading {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 999999;
background: rgba(255, 255, 255, 0.75);
}
#loading img {
margin: auto;
display: block;
}
#modal-message {
margin: 10px 0px;
}
/* BACKEND CALENDAR PAGE
-------------------------------------------------------------------- */
#calendar-page #calendar-toolbar { margin: 15px 10px 20px 10px; padding-bottom: 10px;
overflow: auto; border-bottom: 1px solid #D6D6D6; }
#calendar-page #calendar-filter { display: inline-block; float: left; }
#calendar-page #calendar-filter label { display: inline-block; margin-right: 7px;
font-weight: bold; font-size: 18px; }
#calendar-page #calendar-filter select { margin-top: 5px; }
#calendar-page #calendar-actions { display: inline-block; float: right; margin-top: 4px; }
#calendar-page #calendar { margin: 12px; }
#calendar-page #calendar .fc-unavailable { background-image: url('../images/unavailable.jpg');
font-size: 24px; border-radius: 0; font-weight: bold; color: #333;
text-shadow: 0px 1px 0px #FFF;}
#calendar-page #calendar .fc-break { background-image: url('../images/break.jpg'); }
#calendar-page #calendar .fc-custom { background-image: url('../images/custom.jpg'); }
#calendar-page #calendar-toolbar {
margin: 15px 10px 20px 10px;
padding-bottom: 10px;
overflow: auto;
border-bottom: 1px solid #D6D6D6;
}
#calendar-page #calendar-filter {
display: inline-block;
float: left;
}
#calendar-page #calendar-filter label {
display: inline-block;
margin-right: 7px;
font-weight: bold;
font-size: 18px;
}
#calendar-page #calendar-filter select {
margin-top: 5px;
}
#calendar-page #calendar-actions {
display: inline-block;
float: right;
margin-top: 4px;
}
#calendar-page #calendar {
margin: 12px;
}
#calendar-page #calendar .fc-unavailable {
background-image: url('../images/unavailable.jpg');
font-size: 24px;
border-radius: 0;
font-weight: bold;
color: #333;
text-shadow: 0px 1px 0px #FFF;
}
#calendar-page #calendar .fc-break {
background-image: url('../images/break.jpg');
}
#calendar-page #calendar .fc-custom {
background-image: url('../images/custom.jpg');
}
/* BACKEND CUSTOMERS PAGE
-------------------------------------------------------------------- */
#customers-page #filter { margin: 15px 0px 15px 15px; }
#customers-page #filter-results { overflow-y: auto; }
#customers-page #filter-results .customer-row { padding: 10px 7px; border-radius: 3px; }
#customers-page #filter-results .customer-row:hover { background-color: #C6E7D5; cursor: pointer; }
#customers-page #filter-results hr { margin: 5px 0; }
#customers-page #filter {
margin: 15px 0px 15px 15px;
}
#customers-page #details { margin: 15px 0 15px 15px; }
#customers-page #details .btn-toolbar { margin-top: 0px; }
#customers-page #details div.span5 { margin-left: 0; }
#customers-page #filter-results {
overflow-y: auto;
}
#customers-page #customer-appointments { height: 250px; border: 1px solid #CCC; border-radius: 3px;
margin-bottom: 20px; overflow-y: auto; }
#customers-page #customer-appointments .appointment-row { padding: 7px; border-bottom: 1px solid #CCC; }
#customers-page #customer-appointments .appointment-row:hover { background-color: #C6E7D5; cursor: pointer; }
#customers-page #filter-results .customer-row {
padding: 10px 7px; border-radius: 3px;
}
#customers-page #filter-results .customer-row:hover {
background-color: #C6E7D5;
cursor: pointer;
}
#customers-page #filter-results hr {
margin: 5px 0;
}
#customers-page #details {
margin: 15px 0 15px 15px;
}
#customers-page #details .btn-toolbar {
margin-top: 0px;
}
#customers-page #details div.span5 {
margin-left: 0;
}
#customers-page #customer-appointments {
height: 250px;
border: 1px solid #CCC;
border-radius: 3px;
margin-bottom: 20px;
overflow-y: auto;
}
#customers-page #customer-appointments .appointment-row {
padding: 7px;
border-bottom: 1px solid #CCC;
}
#customers-page #customer-appointments .appointment-row:hover {
background-color: #C6E7D5;
cursor: pointer;
}
#customers-page #details input,
#customers-page #details textarea { background-color: white; cursor: default; }
#customers-page #details textarea {
background-color: white;
cursor: default;
}
#customers-page .selected-row { background-color: #EFFDF7; }
#customers-page .selected-row {
background-color: #EFFDF7;
}
/* BACKEND SERVICES PAGE
-------------------------------------------------------------------- */
#services-page .tab-content { margin: 15px; }
#services-page .nav { margin: 15px; }
#services-page .nav li { cursor: pointer; }
#services-page .service-row { padding: 10px 7px; border-radius: 3px; }
#services-page .service-row:hover { cursor: pointer; background-color: #C6E7D5; }
#services-page .selected-row { background-color: #EFFDF7; }
#services-page .details .ui-spinner { border: none; margin-bottom: 10px; }
#services-page #service-duration { margin: 0px; }
#services-page .details .ui-spinner a { cursor: pointer; }
#services-page .tab-content {
margin: 15px;
}
#services-page .nav {
margin: 15px;
}
#services-page .nav li {
cursor: pointer;
}
#services-page .service-row {
padding: 10px 7px;
border-radius: 3px;
}
#services-page .service-row:hover {
cursor: pointer;
background-color: #C6E7D5;
}
#services-page .selected-row {
background-color: #EFFDF7;
}
#services-page .details .ui-spinner {
border: none;
margin-bottom: 10px;
}
#services-page #service-duration {
margin: 0px;
}
#services-page .details .ui-spinner a {
cursor: pointer;
}
#services-page .details input,
#services-page .details select,
#services-page .details textarea { background-color: white; cursor: pointer; }
#services-page .details textarea {
background-color: white;
cursor: pointer;
}
#services-page #categories .category-row { padding: 10px 7px; border-radius: 3px; }
#services-page #categories .category-row:hover { background-color: #C6E7D5; cursor: pointer; }
#services-page #categories .category-row {
padding: 10px 7px;
border-radius: 3px;
}
#services-page #categories .category-row:hover {
background-color: #C6E7D5;
cursor: pointer;
}
/* BACKEND PROVIDERS PAGE
/* BACKEND USERS PAGE
-------------------------------------------------------------------- */
#users-page .tab-content {
margin: 15px;
}
#users-page .nav {
margin: 15px;
}
#users-page .nav li {
cursor: pointer;
}
#users-page .secretary-row,
#users-page .provider-row,
#users-page .admin-row {
padding: 10px 7px;
border-radius: 3px;
}
#users-page .secretary-row:hover,
#users-page .provider-row:hover,
#users-page .admin-row:hover {
cursor: pointer;
background-color: #C6E7D5;
}
#users-page .selected-row {
background-color: #EFFDF7;
}
#users-page .details input,
#users-page .details select,
#users-page .details textarea {
background-color: white;
cursor: pointer;
}
#users-page #secretary-notifications.active,
#users-page #provider-notifications.active,
#users-page #admin-notifications.active {
background: #FFFF91;
}
#users-page #secretary-providers,
#users-page #provider-services {
border: 2px solid #ccc;
width: 300px;
height: 100px;
overflow-y: scroll;
}
/* BACKEND SETTINGS PAGE

View file

@ -44,8 +44,6 @@ var BackendServices = {
/**
* Binds the default event handlers of the backend services page. Do not use this method
* if you include the "BackendServices" namespace on another page.
*
* @returns {undefined}
*/
bindEventHandlers: function() {
/**

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long