From a5155636dd86009c5eaa554ba3c06d00f331d3bf Mon Sep 17 00:00:00 2001 From: nuxsmin Date: Wed, 5 Feb 2014 01:21:44 +0100 Subject: [PATCH] * New customers management. * Improved categories management by removing 'select' by 'table' style layout. * New permissions added for customers and categories management menu (needs DB update). * Some methods have been refactored and made a bit of code cleanup --- ajax/ajax_accountsave.php | 19 +- ...jax_usersMgmt.php => ajax_appMgmtData.php} | 16 + ...jax_usersSave.php => ajax_appMgmtSave.php} | 181 +++++++++-- ajax/ajax_categorymgmt.php | 111 ------- ajax/ajax_getcontent.php | 116 +++++-- imgs/appmgmt.png | Bin 0 -> 3668 bytes inc/acl.class.php | 6 +- inc/category.class.php | 252 ++++++++++---- inc/customer.class.php | 307 +++++++++++++----- inc/db.class.php | 203 +++++++----- inc/dbstructure.sql | 26 +- inc/groups.class.php | 28 +- inc/html.class.php | 140 ++++++-- inc/import.class.php | 13 +- inc/init.php | 2 +- inc/locales/en_US/LC_MESSAGES/messages.mo | Bin 42273 -> 43156 bytes inc/migrate.class.php | 11 +- inc/profiles.class.php | 43 ++- inc/tpl/accounts.php | 16 +- inc/tpl/categories.php | 121 +++---- inc/tpl/customers.php | 66 ++++ inc/tpl/groups.php | 2 +- inc/tpl/main.php | 1 + inc/tpl/profiles.php | 11 +- inc/tpl/search.php | 4 +- inc/tpl/users.php | 6 +- inc/upgrade.class.php | 6 +- inc/users.class.php | 151 --------- inc/util.class.php | 11 +- js/functions.js | 103 +++--- 30 files changed, 1150 insertions(+), 822 deletions(-) rename ajax/{ajax_usersMgmt.php => ajax_appMgmtData.php} (82%) rename ajax/{ajax_usersSave.php => ajax_appMgmtSave.php} (71%) delete mode 100644 ajax/ajax_categorymgmt.php create mode 100644 imgs/appmgmt.png create mode 100644 inc/tpl/customers.php diff --git a/ajax/ajax_accountsave.php b/ajax/ajax_accountsave.php index 8f9937a5..19c18353 100644 --- a/ajax/ajax_accountsave.php +++ b/ajax/ajax_accountsave.php @@ -132,24 +132,22 @@ if ($frmSaveType == 1 || $frmSaveType == 4) { } $account = new SP_Account; -$customer = new SP_Customer; switch ($frmSaveType) { case 1: - $customer->customerId = $frmSelCustomer; - $customer->customerName = $frmNewCustomer; + SP_Customer::$customerName = $frmNewCustomer; // Comprobar si se ha introducido un nuevo cliente if ($frmNewCustomer) { - if (!$customer->chekDupCustomer()) { + if (!SP_Customer::checkDupCustomer()) { SP_Common::printJSON(_('Cliente duplicado')); } - if (!$customer->customerAdd()) { + if (!SP_Customer::addCustomer()) { SP_Common::printJSON(_('Error al crear cliente')); } - $account->accountCustomerId = $customer->customerLastId; + $account->accountCustomerId = SP_Customer::$customerLastId; } else { $account->accountCustomerId = $frmSelCustomer; } @@ -175,8 +173,7 @@ switch ($frmSaveType) { SP_Common::printJSON(_('Error al crear la cuenta'), 0); break; case 2: - $customer->customerId = $frmSelCustomer; - $customer->customerName = $frmNewCustomer; + SP_Customer::$customerName = $frmNewCustomer; $account->accountId = $frmAccountId; $account->accountName = $frmName; $account->accountCategoryId = $frmCategoryId; @@ -191,15 +188,15 @@ switch ($frmSaveType) { // Comprobar si se ha introducido un nuevo cliente if ($frmNewCustomer) { - if (!$customer->chekDupCustomer()) { + if (!SP_Customer::checkDupCustomer()) { SP_Common::printJSON(_('Cliente duplicado')); } - if (!$customer->customerAdd()) { + if (!SP_Customer::addCustomer()) { SP_Common::printJSON(_('Error al crear cliente')); } - $account->accountCustomerId = $customer->customerLastId; + $account->accountCustomerId = SP_Customer::$customerLastId; } else { $account->accountCustomerId = $frmSelCustomer; } diff --git a/ajax/ajax_usersMgmt.php b/ajax/ajax_appMgmtData.php similarity index 82% rename from ajax/ajax_usersMgmt.php rename to ajax/ajax_appMgmtData.php index 9190cbfa..4a8a57b9 100644 --- a/ajax/ajax_usersMgmt.php +++ b/ajax/ajax_appMgmtData.php @@ -66,6 +66,22 @@ switch ($itemType) { $tplvars['header'] = _('Nuevo Perfil'); $template = 'profiles'; break; + case 7: + $tplvars['header'] = _('Editar Cliente'); + $template = 'customers'; + break; + case 8: + $tplvars['header'] = _('Nuevo Cliente'); + $template = 'customers'; + break; + case 9: + $tplvars['header'] = _('Editar Categoría'); + $template = 'categories'; + break; + case 10: + $tplvars['header'] = _('Nueva Categoría'); + $template = 'categories'; + break; default : break; } diff --git a/ajax/ajax_usersSave.php b/ajax/ajax_appMgmtSave.php similarity index 71% rename from ajax/ajax_usersSave.php rename to ajax/ajax_appMgmtSave.php index b54e23b1..0859d6d6 100644 --- a/ajax/ajax_usersSave.php +++ b/ajax/ajax_appMgmtSave.php @@ -44,9 +44,9 @@ $frmSaveType = SP_Common::parseParams('p', 'type', 0); $frmAction = SP_Common::parseParams('p', 'action', 0); $frmItemId = SP_Common::parseParams('p', 'id', 0); -$objUser = new SP_Users; - if ($frmSaveType == 1 || $frmSaveType == 2) { + $objUser = new SP_Users; + // Variables POST del formulario $frmLdap = SP_Common::parseParams('p', 'ldap', 0); $frmUsrName = SP_Common::parseParams('p', 'name'); @@ -121,8 +121,8 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::sendEmail($message); SP_Common::printJSON(_('Usuario creado'), 0); - } - + } + SP_Common::printJSON(_('Error al crear el usuario')); } elseif ($frmAction == 2) { if ($objUser->updateUser()) { @@ -134,17 +134,17 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Usuario actualizado'), 0); } - + SP_Common::printJSON(_('Error al actualizar el usuario')); } - // Cambio de clave + // Cambio de clave } elseif ($frmAction == 3) { $userLogin = $objUser->getUserLoginById($frmItemId); - - if ( SP_Config::getValue('demoenabled', 0) && $userLogin == 'demo'){ - SP_Common::printJSON(_('Acción Inválida').'(DEMO)'); + + if (SP_Config::getValue('demoenabled', 0) && $userLogin == 'demo') { + SP_Common::printJSON(_('Acción Inválida') . '(DEMO)'); } - + if (!$frmUsrPass || !$frmUsrPassV) { SP_Common::printJSON(_('La clave no puede estar en blanco'), 2); } @@ -165,17 +165,17 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Clave actualizada'), 0); } - + SP_Common::printJSON(_('Error al modificar la clave')); - // Eliminar usuario + // Eliminar usuario } elseif ($frmAction == 4) { $userLogin = $objUser->getUserLoginById($frmItemId); - - if ( SP_Config::getValue('demoenabled', 0) && $userLogin == 'demo' ){ - SP_Common::printJSON(_('Acción Inválida').'(DEMO)'); + + if (SP_Config::getValue('demoenabled', 0) && $userLogin == 'demo') { + SP_Common::printJSON(_('Acción Inválida') . '(DEMO)'); } - + $objUser->userId = $frmItemId; if ($frmItemId == $_SESSION["uid"]) { @@ -191,10 +191,10 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Usuario eliminado'), 0); } - + SP_Common::printJSON(_('Error al eliminar el usuario')); - } - + } + SP_Common::printJSON(_('Acción Inválida')); } elseif ($frmSaveType == 3 || $frmSaveType == 4) { // Variables POST del formulario @@ -210,7 +210,7 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Groups::$groupId = $frmItemId; SP_Groups::$groupName = $frmGrpName; SP_Groups::$groupDescription = $frmGrpDesc; - + if (!SP_Groups::checkGroupExist()) { SP_Common::printJSON(_('Nombre de grupo duplicado'), 2); } @@ -237,21 +237,29 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Grupo actualizado'), 0); } - + SP_Common::printJSON(_('Error al actualizar el grupo')); } - // Eliminar grupo + // Eliminar grupo } elseif ($frmAction == 4) { SP_Groups::$groupId = $frmItemId; $resGroupUse = SP_Groups::checkGroupInUse(); - if ( $resGroupUse !== TRUE ) { - SP_Common::printJSON(_('No es posible eliminar:Grupo en uso por') . ' ' . $resGroupUse); + if ($resGroupUse['users'] > 0 || $resGroupUse['accounts'] > 0) { + if ($resGroupUse['users'] > 0) { + $uses[] = _('Usuarios') . " (" . $resGroupUse['users'] . ")"; + } + + if ($resGroupUse['accounts'] > 0) { + $uses[] = _('Cuentas') . " (" . $resGroupUse['accounts'] . ")"; + } + + SP_Common::printJSON(_('No es posible eliminar') . ';;' . _('Grupo en uso por:') . ';;' . implode(';;', $uses)); } else { $groupName = SP_Groups::getGroupNameById($frmItemId); - + if (SP_Groups::deleteGroup()) { $message['action'] = _('Eliminar Grupo'); $message['text'][] = _('Nombre') . ': ' . $groupName; @@ -261,7 +269,7 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Grupo eliminado'), 0); } - + SP_Common::printJSON(_('Error al eliminar el grupo')); } } @@ -284,7 +292,8 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { $profileProp["pAccDel"] = SP_Common::parseParams('p', 'profile_accdel', 0, FALSE, 1); $profileProp["pAccFiles"] = SP_Common::parseParams('p', 'profile_accfiles', 0, FALSE, 1); $profileProp["pConfig"] = SP_Common::parseParams('p', 'profile_config', 0, FALSE, 1); - $profileProp["pConfigCat"] = SP_Common::parseParams('p', 'profile_configcat', 0, FALSE, 1); + $profileProp["pAppMgmtCat"] = SP_Common::parseParams('p', 'profile_categories', 0, FALSE, 1); + $profileProp["pAppMgmtCust"] = SP_Common::parseParams('p', 'profile_customers', 0, FALSE, 1); $profileProp["pConfigMpw"] = SP_Common::parseParams('p', 'profile_configmpw', 0, FALSE, 1); $profileProp["pConfigBack"] = SP_Common::parseParams('p', 'profile_configback', 0, FALSE, 1); $profileProp["pUsers"] = SP_Common::parseParams('p', 'profile_users', 0, FALSE, 1); @@ -314,7 +323,7 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Perfil creado'), 0); } - + SP_Common::printJSON(_('Error al crear el perfil')); } else if ($frmAction == 2) { if (SP_Profiles::updateProfile($profileProp)) { @@ -326,19 +335,21 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Perfil actualizado'), 0); } - + SP_Common::printJSON(_('Error al actualizar el perfil')); } - // Eliminar perfil + // Eliminar perfil } elseif ($frmAction == 4) { $resProfileUse = SP_Profiles::checkProfileInUse(); - if (is_string($resProfileUse)) { - SP_Common::printJSON(_('No es posible eliminar: Perfil en uso por') . ' ' . $resProfileUse); + if ($resProfileUse['users'] > 0) { + $uses[] = _('Usuarios') . " (" . $resProfileUse['users'] . ")"; + + SP_Common::printJSON(_('No es posible eliminar') . ';;' . _('Perfil en uso por:') . ';;' . implode(';;', $uses)); } else { $profileName = SP_Profiles::getProfileNameById($frmItemId); - + if (SP_Profiles::deleteProfile()) { $message['action'] = _('Eliminar Perfil'); $message['text'][] = _('Nombre') . ': ' . $profileName; @@ -348,10 +359,110 @@ if ($frmSaveType == 1 || $frmSaveType == 2) { SP_Common::printJSON(_('Perfil eliminado'), 0); } - + SP_Common::printJSON(_('Error al eliminar el perfil')); } } - + + SP_Common::printJSON(_('Acción Inválida')); +} elseif ($frmSaveType == 7 || $frmSaveType == 8) { + // Variables POST del formulario + $frmCustomerName = SP_Common::parseParams('p', 'name'); + $frmCustomerDesc = SP_Common::parseParams('p', 'description'); + + // Nuevo cliente o editar + if ($frmAction == 1 OR $frmAction == 2) { + if (!$frmCustomerName) { + SP_Common::printJSON(_('Es necesario un nombre de cliente'), 2); + } + + SP_Customer::$customerName = $frmCustomerName; + SP_Customer::$customerDescription = $frmCustomerDesc; + + if (!SP_Customer::checkDupCustomer($frmItemId)) { + SP_Common::printJSON(_('Nombre de cliente duplicado'), 2); + } + + if ($frmAction == 1) { + if (SP_Customer::addCustomer()) { + SP_Common::printJSON(_('Cliente creado'), 0); + } else { + SP_Common::printJSON(_('Error al crear el cliente')); + } + } else if ($frmAction == 2) { + if (SP_Customer::updateCustomer($frmItemId)) { + SP_Common::printJSON(_('Cliente actualizado'), 0); + } + + SP_Common::printJSON(_('Error al actualizar el cliente')); + } + + // Eliminar cliente + } elseif ($frmAction == 4) { + $resCustomerUse = SP_Customer::checkCustomerInUse($frmItemId); + + if ($resCustomerUse['accounts'] > 0) { + $uses[] = _('Cuentas') . " (" . $resCustomerUse['accounts'] . ")"; + + SP_Common::printJSON(_('No es posible eliminar') . ';;' . _('Cliente en uso por:') . ';;' . implode(';;', $uses)); + } else { + + if (SP_Customer::delCustomer($frmItemId)) { + SP_Common::printJSON(_('Cliente eliminado'), 0); + } + + SP_Common::printJSON(_('Error al eliminar el cliente')); + } + } + + SP_Common::printJSON(_('Acción Inválida')); +} elseif ($frmSaveType == 9 || $frmSaveType == 10) { + // Variables POST del formulario + $frmCategoryName = SP_Common::parseParams('p', 'name'); + $frmCategoryDesc = SP_Common::parseParams('p', 'description'); + + // Nueva categoría o editar + if ($frmAction == 1 OR $frmAction == 2) { + if (!$frmCategoryName) { + SP_Common::printJSON(_('Es necesario un nombre de categoría'), 2); + } + + SP_Category::$categoryName = $frmCategoryName; + SP_Category::$categoryDescription = $frmCategoryDesc; + + if (!SP_Category::checkDupCategory($frmItemId)) { + SP_Common::printJSON(_('Nombre de categoría duplicado'), 2); + } + + if ($frmAction == 1) { + if (SP_Category::addCategory()) { + SP_Common::printJSON(_('Categpría creada'), 0); + } else { + SP_Common::printJSON(_('Error al crear la categoría')); + } + } else if ($frmAction == 2) { + if (SP_Category::updateCategory($frmItemId)) { + SP_Common::printJSON(_('Categoría actualizada'), 0); + } + + SP_Common::printJSON(_('Error al actualizar la categoría')); + } + + // Eliminar categoría + } elseif ($frmAction == 4) { + $resCategoryUse = SP_Category::checkCategoryInUse($frmItemId); + + if ($resCategoryUse !== TRUE) { + SP_Common::printJSON(_('No es posible eliminar') . ';;' . _('Categoría en uso por:') . ';;' . $resCategoryUse); + } else { + + if (SP_Category::delCategory($frmItemId)) { + SP_Common::printJSON(_('Categoría eliminada'), 0); + } + + SP_Common::printJSON(_('Error al eliminar la categoría')); + } + } + SP_Common::printJSON(_('Acción Inválida')); } \ No newline at end of file diff --git a/ajax/ajax_categorymgmt.php b/ajax/ajax_categorymgmt.php deleted file mode 100644 index e7dbf0c9..00000000 --- a/ajax/ajax_categorymgmt.php +++ /dev/null @@ -1,111 +0,0 @@ -. - * - */ -define('APP_ROOT', '..'); -include_once (APP_ROOT . "/inc/init.php"); - -SP_Util::checkReferer('POST'); - -if ( ! SP_Init::isLoggedIn() ) { - SP_Common::printJSON(_('La sesión no se ha iniciado o ha caducado'),10); -} - -$sk = SP_Common::parseParams('p', 'sk', FALSE); - -if (!$sk || !SP_Common::checkSessionKey($sk)) { - SP_Common::printJSON(_('CONSULTA INVÁLIDA')); -} - -$intCategoryFunction = SP_Common::parseParams('p', 'categoryFunction', 0); -$categoryName = SP_Common::parseParams('p', 'categoryName'); -$categoryNameNew = SP_Common::parseParams('p', 'categoryNameNew'); -$categoryId = SP_Common::parseParams('p', 'categoryId', 0); - -switch ($intCategoryFunction) { - case 1: - if ($categoryName == "") { - SP_Common::printJSON(_('Nombre de categoría necesario')); - } else { - // Comprobamos si la categoría existe - if (SP_Category::getCategoryIdByName($categoryName) === 0) { - if (SP_Category::categoryAdd($categoryName)) { - SP_Common::printJSON(_('Categoría añadida'), 0); - } - SP_Common::printJSON(_('Error al añadir la categoría')); - } - SP_Common::printJSON(_('Ya existe una categoría con ese nombre')); - } - break; - case 2: - if ($categoryNameNew == "" || !$categoryId) { - SP_Common::printJSON(_('Nombre de categoría necesario')); - } else { - // Comprobamos si la categoría existe - if (SP_Category::getCategoryIdByName($categoryNameNew) !== 0) { - SP_Common::printJSON(_('Ya existe una categoría con ese nombre')); - } else { - // Obtenemos el nombre de la categoría por el Id - $oldCategoryName = SP_Category::getCategoryNameById($categoryId); - - if (SP_Category::editCategoryById($categoryId, $categoryNameNew)) { - $message['action'] = _('Modificar Categoría'); - $message['text'][] = _('Nombre') . ': ' . $oldCategoryName.' > '.$categoryNameNew; - - SP_Common::wrLogInfo($message); - SP_Common::sendEmail($message); - - SP_Common::printJSON(_('Categoría modificada'), 0); - } - SP_Common::printJSON(_('Error al modificar la categoría')); - } - } - break; - case 3: - if (!$categoryId) { - SP_Common::printJSON(_('Nombre de categoría necesario')); - } else { - // Comprobamos si la categoría está en uso por una cuenta - if (SP_Category::isCategoryInUse($categoryId)) { - SP_Common::printJSON(_('Categoría en uso, no es posible eliminar')); - } else { - // Obtenemos el nombre de la categoría por el Id - $oldCategoryName = SP_Category::getCategoryNameById($categoryId); - - if (SP_Category::categoryDel($categoryId)) { - $message['action'] = _('Eliminar Categoría'); - $message['text'][] = _('Nombre') . ': ' .$oldCategoryName.' ('. $categoryId.')'; - - SP_Common::wrLogInfo($message); - SP_Common::sendEmail($message); - - SP_Common::printJSON(_('Categoría eliminada')); - } - SP_Common::printJSON(_('Error al eliminar la categoría')); - } - } - break; - default: - SP_Common::printJSON(_('Acción Inválida')); -} \ No newline at end of file diff --git a/ajax/ajax_getcontent.php b/ajax/ajax_getcontent.php index 069566af..5ef0a1fe 100644 --- a/ajax/ajax_getcontent.php +++ b/ajax/ajax_getcontent.php @@ -127,17 +127,18 @@ switch ($action) { ), 'tblRowSrcId' => 'user_id', 'frmId' => 'frm_tblusers', + 'nextaction' => $action, 'actionId' => 1, 'newActionId' => 2, 'active' => $tplvars['active'] ++, - 'actions' => array('view', 'edit', 'del', 'pass')); + 'actions' => array('view' => 'appMgmtData', 'edit' => 'appMgmtData', 'del' => 'appMgmtSave', 'pass' => 'usrUpdPass')); echo '
'; $startTime = microtime(); $users = SP_Users::getUsers(); if ($users) { - SP_Users::getUsrGrpTable($arrUsersTableProp, $users); + SP_Html::getQueryTable($arrUsersTableProp, $users); SP_Html::printQueryInfoBar(count($users), $startTime); } echo '
'; @@ -152,10 +153,11 @@ switch ($action) { 'tblRowSrc' => array('usergroup_name', 'usergroup_description'), 'tblRowSrcId' => 'usergroup_id', 'frmId' => 'frm_tblgroups', + 'nextaction' => $action, 'actionId' => 3, 'newActionId' => 4, 'active' => $tplvars['active'] ++, - 'actions' => array('edit', 'del')); + 'actions' => array('edit' => 'appMgmtData', 'del' => 'appMgmtSave')); echo '
'; @@ -163,7 +165,7 @@ switch ($action) { $groups = SP_Groups::getGroups(); if ($groups) { - SP_Users::getUsrGrpTable($arrGroupsTableProp, $groups); + SP_Html::getQueryTable($arrGroupsTableProp, $groups); SP_Html::printQueryInfoBar(count($groups), $startTime); } @@ -179,10 +181,11 @@ switch ($action) { 'tblRowSrc' => array('userprofile_name'), 'tblRowSrcId' => 'userprofile_id', 'frmId' => 'frm_tblprofiles', + 'nextaction' => $action, 'actionId' => 5, 'newActionId' => 6, 'active' => $tplvars['active'] ++, - 'actions' => array('edit', 'del')); + 'actions' => array('edit' => 'appMgmtData', 'del' => 'appMgmtSave')); echo '
'; @@ -190,7 +193,7 @@ switch ($action) { $profiles = SP_Profiles::getProfiles(); if ($profiles) { - SP_Users::getUsrGrpTable($arrProfilesTableProp, $profiles); + SP_Html::getQueryTable($arrProfilesTableProp, $profiles); SP_Html::printQueryInfoBar(count($profiles), $startTime); } @@ -209,14 +212,93 @@ switch ($action) { }); '; break; + case "appmgmtmenu": + echo '
'; + echo ''; + + $tplvars['active'] = 0; + + if (SP_ACL::checkUserAccess("categories")) { + $arrCategoriesTableProp = array( + 'itemName' => _('Categoría'), + 'tblId' => 'tblCategories', + 'header' => '', + 'tblHeaders' => array(_('Nombre'),_('Descripción')), + 'tblRowSrc' => array('category_name','category_description'), + 'tblRowSrcId' => 'category_id', + 'frmId' => 'frm_tblcategories', + 'nextaction' => $action, + 'actionId' => 9, + 'newActionId' => 10, + 'active' => $tplvars['active'] ++, + 'actions' => array('edit' => 'appMgmtData', 'del' => 'appMgmtSave') + ); + + echo '
'; + + $startTime = microtime(); + $categories = SP_Category::getCategories(); + + if ($categories) { + SP_Html::getQueryTable($arrCategoriesTableProp, $categories); + SP_Html::printQueryInfoBar(count($categories), $startTime); + } + + echo '
'; + } + + if (SP_ACL::checkUserAccess("customers")) { + $arrCustomersTableProp = array( + 'itemName' => _('Cliente'), + 'tblId' => 'tblCustomers', + 'header' => '', + 'tblHeaders' => array(_('Nombre'),_('Descripción')), + 'tblRowSrc' => array('customer_name','customer_description'), + 'tblRowSrcId' => 'customer_id', + 'frmId' => 'frm_tblcustomers', + 'nextaction' => $action, + 'actionId' => 7, + 'newActionId' => 8, + 'active' => $tplvars['active'] ++, + 'actions' => array('edit' => 'appMgmtData', 'del' => 'appMgmtSave') + ); + + echo '
'; + + $startTime = microtime(); + $customers = SP_Customer::getCustomers(); + + if ($customers) { + SP_Html::getQueryTable($arrCustomersTableProp, $customers); + SP_Html::printQueryInfoBar(count($customers), $startTime); + } + + echo '
'; + } + + echo '
'; + + echo ''; + break; case "configmenu": echo '
'; echo ''; $tplvars['active'] = 0; @@ -229,18 +311,10 @@ switch ($action) { echo '
'; } - if (SP_ACL::checkUserAccess("categories")) { - $tplvars['active'] ++; - - echo '
'; - SP_Html::getTemplate('categories', $tplvars); - echo '
'; - } - if (SP_ACL::checkUserAccess("masterpass")) { $tplvars['active'] ++; - echo '
'; + echo '
'; SP_Html::getTemplate('masterpass', $tplvars); echo '
'; } @@ -248,7 +322,7 @@ switch ($action) { if (SP_ACL::checkUserAccess("backup")) { $tplvars['active'] ++; - echo '
'; + echo '
'; SP_Html::getTemplate('backup', $tplvars); echo '
'; } @@ -256,7 +330,7 @@ switch ($action) { if (SP_ACL::checkUserAccess("config")) { $tplvars['active'] ++; - echo '
'; + echo '
'; SP_Html::getTemplate('migrate', $tplvars); echo '
'; } diff --git a/imgs/appmgmt.png b/imgs/appmgmt.png new file mode 100644 index 0000000000000000000000000000000000000000..894d1485eaa94576c044ebafdca52d6bcd27c70f GIT binary patch literal 3668 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 ); case "accfiles": return ( $blnUIsAdminApp || $blnUIsAdminAcc || $profile->userProfile_pFiles ); + case "appmgmtmenu": + return ( $blnUIsAdminApp || $profile->userProfile_pAppMgmtMenu ); case "configmenu": return ( $blnUIsAdminApp || $profile->userProfile_pConfigMenu ); case "config": return ( $blnUIsAdminApp || $profile->userProfile_pConfig ); case "categories": - return ( $blnUIsAdminApp || $profile->userProfile_pConfigCategories ); + return ( $blnUIsAdminApp || $profile->userProfile_pAppMgmtCategories ); + case "customers": + return ( $blnUIsAdminApp || $profile->userProfile_pAppMgmtCustomers ); case "masterpass": return ( $blnUIsAdminApp || $profile->userProfile_pConfigMasterPass ); case "backup": diff --git a/inc/category.class.php b/inc/category.class.php index f22d771b..e5b8c5e7 100644 --- a/inc/category.class.php +++ b/inc/category.class.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link http://syspass.org - * @copyright 2012 Rubén Domínguez nuxsmin@syspass.org + * @copyright 2014 Rubén Domínguez nuxsmin@syspass.org * * This file is part of sysPass. * @@ -23,27 +23,28 @@ * along with sysPass. If not, see . * */ - defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); /** * Esta clase es la encargada de realizar las operaciones sobre las categorías de sysPass. */ class SP_Category { + public static $categoryName; + public static $categoryDescription; public static $categoryLastId; /** * @brief Obtener el id de una categoría por el nombre * @param string $categoryName con el nombre de la categoría * @return bool|int si la consulta es errónea devuelve bool. Si no hay registros o se obtiene el id, devuelve int - */ + */ public static function getCategoryIdByName($categoryName) { $query = "SELECT category_id " . "FROM categories " . "WHERE category_name = '" . DB::escape($categoryName) . "' LIMIT 1"; $queryRes = DB::getResults($query, __FUNCTION__); - if ( $queryRes === FALSE ) { + if ($queryRes === FALSE) { return FALSE; } @@ -58,19 +59,72 @@ class SP_Category { * @brief Crear una nueva categoría en la BBDD * @param string $categoryName con el nombre de la categoría * @return bool - */ - public static function categoryAdd($categoryName) { + */ + public static function addCategory() { $query = "INSERT INTO categories " - . "SET category_name = '" . DB::escape($categoryName) . "'"; + . "SET category_name = '" . DB::escape(self::$categoryName) . "'," + . "category_description = '" . DB::escape(self::$categoryDescription) . "'"; if (DB::doQuery($query, __FUNCTION__) === FALSE) { return FALSE; } self::$categoryLastId = DB::$lastId; - + $message['action'] = _('Nueva Categoría'); - $message['text'][] = _('Nombre') . ': ' . $categoryName; + $message['text'][] = _('Nombre') . ': ' . self::$categoryName; + + SP_Common::wrLogInfo($message); + SP_Common::sendEmail($message); + + return TRUE; + } + + /** + * @brief Comprobar si existe una categoría duplicada + * @param int $id con el Id de la categoría a consultar + * @return bool + */ + public static function checkDupCategory($id = NULL) { + + if ($id === NULL) { + $query = "SELECT category_id " + . "FROM categories " + . "WHERE category_name = '" . DB::escape(self::$categoryName) . "'"; + } else { + $query = "SELECT category_id " + . "FROM categories " + . "WHERE category_name = '" . DB::escape(self::$categoryName) . "' AND category_id <> " . $id; + } + + if (DB::doQuery($query, __FUNCTION__) === FALSE) { + return FALSE; + } + + if (count(DB::$last_result) >= 1) { + return FALSE; + } + + return TRUE; + } + + /** + * @brief Eliminar una categoría de la BBDD + * @param int $id con el id de la categoría + * @return bool + */ + public static function delCategory($id) { + $categoryName = self::getCategoryNameById($id); + + $query = "DELETE FROM categories " + . "WHERE category_id = " . (int) $id . " LIMIT 1"; + + if (DB::doQuery($query, __FUNCTION__) === FALSE) { + return FALSE; + } + + $message['action'] = _('Eliminar Categoría'); + $message['text'][] = _('Nombre') . ': ' .$categoryName.' ('. $id.')'; SP_Common::wrLogInfo($message); SP_Common::sendEmail($message); @@ -78,95 +132,153 @@ class SP_Category { return TRUE; } - /** - * @brief Comprobar si una categoría está en uso por alguna cuenta - * @param int $categoryId con el id de la categoría - * @return bool - */ - public static function isCategoryInUse($categoryId) { - $query = "SELECT account_categoryId " - . "FROM accounts " - . "WHERE account_categoryId = " . (int) $categoryId; - - if (DB::doQuery($query, __FUNCTION__) === FALSE) { - return FALSE; - } - - return ( count(DB::$last_result) > 0 ) ? TRUE : FALSE; - } - - /** - * @brief Eliminar una categoría de la BBDD - * @param int $categoryId con el id de la categoría - * @return bool - */ - public static function categoryDel($categoryId) { - $query = "DELETE FROM categories " - . "WHERE category_id = $categoryId LIMIT 1"; - - if (DB::doQuery($query, __FUNCTION__) === FALSE) { - return FALSE; - } - - return TRUE; - } - /** * @brief Actualizar una categoría en la BBDD con el id - * @param int $categoryId con el id de la categoría - * @param int $categoryNameNew con el nombre nuevo de la categoría + * @param int $id con el Id de la categoría a consultar * @return bool */ - public static function editCategoryById($categoryId, $categoryNameNew) { + public static function updateCategory($id) { + $categoryName = self::getCategoryNameById($id); + $query = "UPDATE categories " - . "SET category_name = '" . DB::escape($categoryNameNew) . "' " - . "WHERE category_id = " . (int) $categoryId . " LIMIT 1"; + . "SET category_name = '" . DB::escape(self::$categoryName) . "'," + . "category_description = '" . DB::escape(self::$categoryDescription) . "' " + . "WHERE category_id = " . (int) $id . " LIMIT 1"; if (DB::doQuery($query, __FUNCTION__) === FALSE) { return FALSE; } + $message['action'] = _('Modificar Categoría'); + $message['text'][] = _('Nombre') . ': ' . $categoryName.' > '.self::$categoryName; + + SP_Common::wrLogInfo($message); + SP_Common::sendEmail($message); + return TRUE; } /** * @brief Obtiene el listado de categorías + * @param int $id con el Id de la categoría + * @param bool $retAssocArray para devolver un array asociativo * @return array con en id de categorioa como clave y en nombre como valor - */ - public static function getCategories(){ + */ + public static function getCategories($id = NULL, $retAssocArray = FALSE) { $query = "SELECT category_id," - . "category_name " - . "FROM categories " - . "ORDER BY category_name"; + . "category_name," + . "category_description " + . "FROM categories "; + + if (!is_null($id)) { + $query .= "WHERE category_id = " . (int) $id . " LIMIT 1"; + } else { + $query .= "ORDER BY category_name"; + } + $queryRes = DB::getResults($query, __FUNCTION__, TRUE); - if ( $queryRes === FALSE ){ + if ($queryRes === FALSE) { return array(); } - - $resCategories = array(); - - foreach ( $queryRes as $category ){ - $resCategories[$category->category_id] = $category->category_name; + + if ($retAssocArray) { + $resCategories = array(); + + foreach ($queryRes as $category) { + $resCategories[$category->category_id] = $category->category_name; + } + + return $resCategories; } - return $resCategories; + return $queryRes; + } + + /** + * @brief Obtiene el nombre de la categoría a partir del Id + * @param int $id con el Id de la categoría a consultar + * @return string con el nombre de la categoría + */ + public static function getCategoryNameById($id) { + $query = "SELECT category_name " + . "FROM categories " + . "WHERE category_id = " . (int) $id; + $queryRes = DB::getResults($query, __FUNCTION__); + + if ($queryRes === FALSE) { + return FALSE; + } + + return $queryRes->category_name; + } + + /** + * @brief Obtener los datos de una categoría + * @param int $id con el Id de la categoría a consultar + * @return array con el nombre de la columna como clave y los datos como valor + */ + public static function getCategoryData($id = 0) { + $category = array('category_id' => 0, + 'category_name' => '', + 'category_description' => '', + 'action' => 1); + + if ($id > 0) { + $categories = self::getCategories($id); + + if ($categories) { + foreach ($categories[0] as $name => $value) { + $category[$name] = $value; + } + $category['action'] = 2; + } + } + + return $category; } /** - * @brief Obtiene el nombre de la categoría a partir del Id - * @return string con el nombre de la categoría - */ - public static function getCategoryNameById($id){ - $query = "SELECT category_name " - . "FROM categories " - . "WHERE category_id = ".(int)$id; + * @brief Comprobar si una categoría está en uso + * @param int $id con el Id de la categoría a consultar + * @return bool + * + * Esta función comprueba si una categoría está en uso por cuentas. + */ + public static function checkCategoryInUse($id) { + + $numAccounts = self::getCategoriesInAccounts($id); + + $out = ''; + + if ($numAccounts) { + $out[] = _('Cuentas') . " (" . $numAccounts . ")"; + } + + if (is_array($out)) { + return implode('
', $out); + } + + return TRUE; + } + + /** + * @brief Obtener el número de cuentas que usan una categoría + * @param int $id con el Id de la categoría a consultar + * @return integer con el número total de cuentas + */ + private static function getCategoriesInAccounts($id) { + $query = "SELECT COUNT(*) as uses " + . "FROM accounts " + . "WHERE account_categoryId = " . (int) $id; + $queryRes = DB::getResults($query, __FUNCTION__); - if ( $queryRes === FALSE ){ + if ($queryRes === FALSE) { return FALSE; } - - return $queryRes->category_name; + + return $queryRes->uses; } -} \ No newline at end of file + +} diff --git a/inc/customer.class.php b/inc/customer.class.php index 9eb11594..f0b011f0 100644 --- a/inc/customer.class.php +++ b/inc/customer.class.php @@ -1,151 +1,280 @@ . -* -*/ +/** + * sysPass + * + * @author nuxsmin + * @link http://syspass.org + * @copyright 2014 Rubén Domínguez nuxsmin@syspass.org + * + * This file is part of sysPass. + * + * sysPass is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * sysPass is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with sysPass. If not, see . + * + */ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); /** * Esta clase es la encargada de realizar las operaciones sobre los clientes de sysPass */ -class SP_Customer{ +class SP_Customer { - var $customerId; - var $customerName; - var $customerDescription; - var $customerLastId; - var $customerHash; + public static $customerName; + public static $customerDescription; + public static $customerLastId; + public static $customerHash; /** * @brief Obtener el listado de clientes + * @param int $customerId con el Id del cliente + * @param bool $retAssocArray para devolver un array asociativo * @return array con el id de cliente como clave y el nombre como valor - */ - public static function getCustomers(){ + */ + public static function getCustomers($customerId = NULL, $retAssocArray = FALSE) { $query = "SELECT customer_id," - . "customer_name " - . "FROM customers " - . "ORDER BY customer_name"; - $queryRes = DB::getResults($query, __FUNCTION__, TRUE); - - if ( $queryRes === FALSE ){ - return FALSE; - } - - $resCustomers = array(); - - foreach ( $queryRes as $customer ){ - $resCustomers[$customer->customer_id] = $customer->customer_name; + . "customer_name, " + . "customer_description " + . "FROM customers "; + + if (!is_null($customerId)) { + $query .= "WHERE customer_id = " . (int) $customerId . " LIMIT 1"; + } else { + $query .= "ORDER BY customer_name"; } - return $resCustomers; + $queryRes = DB::getResults($query, __FUNCTION__, TRUE); + + if ($queryRes === FALSE) { + return FALSE; + } + + if ($retAssocArray) { + $resCustomers = array(); + + foreach ($queryRes as $customer) { + $resCustomers[$customer->customer_id] = $customer->customer_name; + } + + return $resCustomers; + } + + return $queryRes; } - + /** * @brief Crear un nuevo cliente en la BBDD * @return bool - */ - public function customerAdd(){ + */ + public static function addCustomer() { $query = "INSERT INTO customers " - . "SET customer_name = '".DB::escape($this->customerName)."'," - . "customer_hash = '".$this->mkCustomerHash()."'"; - - if ( DB::doQuery($query, __FUNCTION__) === FALSE ){ + . "SET customer_name = '" . DB::escape(self::$customerName) . "'," + . "customer_hash = '" . self::mkCustomerHash() . "'"; + + if (DB::doQuery($query, __FUNCTION__) === FALSE) { return FALSE; } - - $this->customerLastId = DB::$lastId; - + + self::$customerLastId = DB::$lastId; + $message['action'] = _('Nuevo Cliente'); - $message['text'][] = _('Nombre').': '.$this->customerName; + $message['text'][] = _('Nombre') . ': ' . self::$customerName; + SP_Common::wrLogInfo($message); - + SP_Common::sendEmail($message); + + return TRUE; + } + + /** + * @brief Actualizar un cliente en la BBDD + * @return bool + */ + public static function updateCustomer($id) { + $query = "UPDATE customers " + . "SET customer_name = '" . DB::escape(self::$customerName) . "'," + . "customer_description = '" . DB::escape(self::$customerDescription) . "'," + . "customer_hash = '" . self::mkCustomerHash() . "' " + . "WHERE customer_id = " . (int) $id; + + if (DB::doQuery($query, __FUNCTION__) === FALSE) { + return FALSE; + } + + $message['action'] = _('Actualizar Cliente'); + $message['text'][] = _('Nombre') . ': ' . self::$customerName; + + SP_Common::wrLogInfo($message); + SP_Common::sendEmail($message); + return TRUE; } /** * @brief Eliminar un cliente de la BBDD + * @param int $id con el Id del cliente a eliminar * @return bool - */ - public function customerDel(){ - $query = "DELETE FROM customers" - . " WHERE customer_id = $this->customerId LIMIT 1"; - - if ( DB::doQuery($query, __FUNCTION__) === FALSE ){ + */ + public static function delCustomer($id) { + $customerName = self::getCustomerById($id); + + $query = "DELETE FROM customers " + . "WHERE customer_id = " . (int) $id . " LIMIT 1"; + + if (DB::doQuery($query, __FUNCTION__) === FALSE) { return FALSE; } - + + $message['action'] = _('Eliminar Cliente'); + $message['text'][] = _('Nombre') . ': ' . $customerName; + + SP_Common::wrLogInfo($message); + SP_Common::sendEmail($message); + return TRUE; } - + /** * @brief Crear un hash con el nombre del cliente * @return string con el hash generado * * Esta función crear un hash para detectar clientes duplicados mediante * la eliminación de carácteres especiales y capitalización - */ - private function mkCustomerHash(){ - $charsSrc = array("."," ","_",",","-",";","'","\"",":","(",")","|","/"); - $newValue = strtolower(str_replace($charsSrc, '', DB::escape($this->customerName))); + */ + private static function mkCustomerHash() { + $charsSrc = array( + ".", " ", "_", ", ", "-", "; + ", "'", "\"", ":", "(", ")", "|", "/"); + $newValue = strtolower(str_replace($charsSrc, '', DB::escape(self::$customerName))); $hashValue = md5($newValue); - - return $hashValue; + + return $hashValue; } - + /** * @brief Comprobar si existe un cliente duplicado comprobando el hash * @return bool - */ - public function chekDupCustomer(){ - $query = "SELECT customer_id " - . "FROM customers " - . "WHERE customer_hash = '".$this->mkCustomerHash()."'"; - - if ( DB::doQuery($query, __FUNCTION__) === FALSE ){ - return FALSE; + */ + public static function checkDupCustomer($id = NULL) { + if ($id === NULL) { + $query = "SELECT customer_id " + . "FROM customers " + . "WHERE customer_hash = '" . self::mkCustomerHash() . "'"; + } else { + $query = "SELECT customer_id " + . "FROM customers " + . "WHERE customer_hash = '" . self::mkCustomerHash() . "' AND customer_id <> " . $id; } - if ( count(DB::$last_result) >= 1 ){ + if (DB::doQuery($query, __FUNCTION__) === FALSE) { return FALSE; } - + + if (count(DB::$last_result) >= 1) { + return FALSE; + } + return TRUE; } - + /** * @brief Obtener el Id de un cliente por su nombre * @return int con el Id del cliente - */ - public function getCustomerByName(){ + */ + public static function getCustomerByName() { $query = "SELECT customer_id " . "FROM customers " - . "WHERE customer_hash = '".$this->mkCustomerHash()."' LIMIT 1"; + . "WHERE customer_hash = '" . self::mkCustomerHash() . "' LIMIT 1"; $queryRes = DB::getResults($query, __FUNCTION__); - - if ( $queryRes === FALSE ){ + + if ($queryRes === FALSE) { return FALSE; } - + return $queryRes->customer_id; } + + /** + * @brief Obtener el Nombre de un cliente por su Id + * @param int $id con el Id del cliente + * @return string con el nombre del cliente + */ + public static function getCustomerById($id) { + $query = "SELECT customer_name " + . "FROM customers " + . "WHERE customer_id = " . (int) $id . " LIMIT 1"; + $queryRes = DB::getResults($query, __FUNCTION__); + + if ($queryRes === FALSE) { + return FALSE; + } + + return $queryRes->customer_name; + } + + /** + * @brief Obtener los datos de un cliente + * @param int $id con el Id del cliente a consultar + * @return array con el nombre de la columna como clave y los datos como valor + */ + public static function getCustomerData($id = 0) { + $customer = array('customer_id' => 0, + 'customer_name' => '', + 'customer_description' => '', + 'action' => 1); + + if ($id > 0) { + $customers = self::getCustomers($id); + + if ($customers) { + foreach ($customers[0] as $name => $value) { + $customer[$name] = $value; + } + $customer['action'] = 2; + } + } + + return $customer; + } + + /** + * @brief Comprobar si un cliente está en uso + * @param int $id con el Id del cliente a consultar + * @return bool + * + * Esta función comprueba si un cliente está en uso por cuentas. + */ + public static function checkCustomerInUse($id) { + $count['accounts'] = self::getCustomerInAccounts($id); + return $count; + } + + /** + * @brief Obtener el número de cuentas que usan un cliente + * @param int $id con el Id del cliente a consultar + * @return integer con el número total de cuentas + */ + private static function getCustomerInAccounts($id) { + $query = "SELECT COUNT(*) as uses " + . "FROM accounts " + . "WHERE account_customerId = " . (int) $id; + + $queryRes = DB::getResults($query, __FUNCTION__); + + if ($queryRes === FALSE) { + return FALSE; + } + + return $queryRes->uses; + } } \ No newline at end of file diff --git a/inc/db.class.php b/inc/db.class.php index 6b27b752..8b72bf98 100644 --- a/inc/db.class.php +++ b/inc/db.class.php @@ -1,76 +1,78 @@ . -* -*/ +/** + * sysPass + * + * @author nuxsmin + * @link http://syspass.org + * @copyright 2012 Rubén Domínguez nuxsmin@syspass.org + * + * This file is part of sysPass. + * + * sysPass is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * sysPass is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with sysPass. If not, see . + * + */ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); /** * Esta clase es la encargada de realizar las operaciones con la BBDD de sysPass. */ class DB { + private static $_db; - static $last_result; static $affected_rows; static $lastId; static $txtError; static $numError; static $num_rows; - - function __construct(){ } - + + function __construct() { + + } + /** * @brief Realizar la conexión con la BBDD * @return bool * * Esta función utiliza mysqli para conectar con la base de datos. * Guarda el objeto creado en la variable $_db de la clase - */ - private static function connection(){ - if ( self::$_db ){ + */ + private static function connection() { + if (self::$_db) { return true; } - + $dbhost = SP_Config::getValue("dbhost"); $dbuser = SP_Config::getValue("dbuser"); $dbpass = SP_Config::getValue("dbpass"); $dbname = SP_Config::getValue("dbname"); - - self::$_db = @new mysqli($dbhost,$dbuser,$dbpass,$dbname); - - if ( self::$_db->connect_errno ){ - if ( SP_Config::getValue("installed") ){ - if ( self::$_db->connect_errno === 1049 ){ + + self::$_db = @new mysqli($dbhost, $dbuser, $dbpass, $dbname); + + if (self::$_db->connect_errno) { + if (SP_Config::getValue("installed")) { + if (self::$_db->connect_errno === 1049) { SP_Config::setValue('installed', '0'); } - - SP_Init::initError(_('No es posible conectar con la BD'),'Error '.self::$_db->connect_errno . ': '.self::$_db->connect_error); - } else{ + + SP_Init::initError(_('No es posible conectar con la BD'), 'Error ' . self::$_db->connect_errno . ': ' . self::$_db->connect_error); + } else { return false; } } - return true; + return true; } /** @@ -79,9 +81,9 @@ class DB { * @return string con la cadena escapada * * Esta función utiliza mysqli para escapar cadenas de texto. - */ + */ public static function escape($str) { - if ( self::connection() ){ + if (self::connection()) { return self::$_db->real_escape_string(trim($str)); } else { return $str; @@ -93,104 +95,137 @@ class DB { * @param string $query con la consulta a realizar * @param string $querySource con el nombre de la función que realiza la consulta * @return bool|int devuleve bool si hay un error. Devuelve int con el número de registros - */ - public static function doQuery($query,$querySource) { - if ( ! self::connection() ){ + */ + public static function doQuery($query, $querySource) { + if (!self::connection()) { return false; } - - $isSelect = preg_match("/^.*(select|show)\s/i",$query); + + $isSelect = preg_match("/^.*(select|show)\s/i", $query); // Limpiar valores de caché self::$last_result = array(); - + $queryRes = self::$_db->query($query); - if ( ! $queryRes ) { + if (!$queryRes) { self::$numError = self::$_db->errno; self::$txtError = self::$_db->error; - + $message['action'] = $querySource; - $message['text'][] = self::$_db->error.'('.self::$_db->errno.')'; - $message['text'][] = "SQL: ".self::escape($query); - + $message['text'][] = self::$_db->error . '(' . self::$_db->errno . ')'; + $message['text'][] = "SQL: " . self::escape($query); + SP_Common::wrLogInfo($message); return FALSE; } - if ( $isSelect ) { - if ( $queryRes->num_rows == 1 ){ + if ($isSelect) { + if ($queryRes->num_rows == 1) { self::$last_result = @$queryRes->fetch_object(); } else { $num_row = 0; - - while ( $row = @$queryRes->fetch_object() ) { + + while ($row = @$queryRes->fetch_object()) { self::$last_result[$num_row] = $row; $num_row++; } } - + self::$num_rows = $queryRes->num_rows; - + $queryRes->close(); } self::$lastId = self::$_db->insert_id; $numRows = self::$_db->affected_rows; - + return $numRows; } - + /** * @brief Obtener los resultados de una consulta * @param string $query con la consulta a realizar * @param string $querySource con el nombre de la función que realiza la consulta * @return bool|array devuelve bool si hay un error. Devuelve array con el array de registros devueltos - */ + */ public static function getResults($query, $querySource, $retArray = FALSE) { - if ( $query ){ - self::doQuery($query,$querySource); + if ($query) { + self::doQuery($query, $querySource); } - - if ( self::$numError || self::$num_rows === 0) { + + if (self::$numError || self::$num_rows === 0) { return FALSE; } - - if ( is_null(self::$numError) && count(self::$last_result) === 0 ){ + + if (is_null(self::$numError) && count(self::$last_result) === 0) { return TRUE; } - if ( $retArray === TRUE && is_object(self::$last_result) ){ + if ($retArray === TRUE && is_object(self::$last_result)) { return array(self::$last_result); } - + return self::$last_result; } /** * @brief Comprobar que la base de datos existe * @return bool - */ - public static function checkDatabaseExist(){ - if ( ! self::connection() ){ + */ + public static function checkDatabaseExist() { + if (!self::connection()) { return false; } - - $query='SELECT COUNT(*) ' + + $query = 'SELECT COUNT(*) ' . 'FROM information_schema.tables' - ." WHERE table_schema='".SP_Config::getValue("dbname")."' " + . " WHERE table_schema='" . SP_Config::getValue("dbname") . "' " . "AND table_name = 'usrData';"; - + $resquery = self::$_db->query($query); - - if( $resquery ) { + + if ($resquery) { $row = $resquery->fetch_row(); } - - if( ! $resquery || $row[0] == 0) { + + if (!$resquery || $row[0] == 0) { return false; } - + return true; } -} \ No newline at end of file + + /** + * @brief Obtener los datos para generar un select + * @param string $tblName con el nombre de la tabla a cunsultar + * @param string $tblColId con el nombre de la columna a mostrar + * @param array $arrFilter con las columnas a filtrar + * @param array $arrOrder con el orden de las columnas + * @return array con los valores del select con el Id como clave y el nombre como valor + */ + public static function getValuesForSelect($tblName, $tblColId, $tblColName, $arrFilter = '', $arrOrder = '') { + if (!$tblName || !$tblColId || !$tblColName) { + return; + } + + $strFilter = ( is_array($arrFilter) ) ? " WHERE " . implode(" OR ", $arrFilter) : ""; + $strOrder = ( is_array($arrOrder) ) ? " ORDER BY " . implode(",", $arrOrder) : 'ORDER BY ' . $tblColName . ' ASC'; + + $query = "SELECT $tblColId, $tblColName FROM $tblName $strFilter $strOrder"; + $queryRes = self::getResults($query, __FUNCTION__); + + if ($queryRes === FALSE) { + return FALSE; + } + + $arrValues = array(); + + foreach ($queryRes as $row) { + $arrValues[$row->$tblColId] = $row->$tblColName; + } + + return $arrValues; + } + +} diff --git a/inc/dbstructure.sql b/inc/dbstructure.sql index 63a4d6db..4b203957 100644 --- a/inc/dbstructure.sql +++ b/inc/dbstructure.sql @@ -26,7 +26,7 @@ CREATE TABLE `accFiles` ( `accfile_extension` varchar(10) NOT NULL, PRIMARY KEY (`accfile_id`), KEY `IDX_accountId` (`accfile_accountId`) -) ENGINE=MyISAM AUTO_INCREMENT=61 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=62 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -42,7 +42,7 @@ CREATE TABLE `accGroups` ( `accgroup_groupId` int(10) unsigned NOT NULL, PRIMARY KEY (`accgroup_id`), KEY `IDX_accountId` (`accgroup_accountId`) -) ENGINE=MyISAM AUTO_INCREMENT=68 DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci; +) ENGINE=MyISAM AUTO_INCREMENT=69 DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -77,7 +77,7 @@ CREATE TABLE `accHistory` ( `accHistory_otherGroupEdit` varchar(45) DEFAULT NULL, PRIMARY KEY (`acchistory_id`), KEY `IDX_accountId` (`acchistory_accountId`) -) ENGINE=MyISAM AUTO_INCREMENT=264 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=285 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -127,7 +127,7 @@ CREATE TABLE `accounts` ( KEY `IDX_userId` (`account_userGroupId`,`account_userId`), KEY `IDX_customerId` (`account_customerId`), FULLTEXT KEY `IDX_searchTxt` (`account_name`,`account_login`,`account_url`,`account_notes`) -) ENGINE=MyISAM AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=44 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -140,8 +140,9 @@ DROP TABLE IF EXISTS `categories`; CREATE TABLE `categories` ( `category_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `category_name` varchar(50) NOT NULL, + `category_description` varchar(255) DEFAULT NULL, PRIMARY KEY (`category_id`) -) ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf16; +) ENGINE=MyISAM AUTO_INCREMENT=20 DEFAULT CHARSET=utf16; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -172,7 +173,7 @@ CREATE TABLE `customers` ( `customer_description` varchar(255) DEFAULT NULL, PRIMARY KEY (`customer_id`), KEY `IDX_name` (`customer_name`,`customer_hash`) -) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -190,7 +191,7 @@ CREATE TABLE `log` ( `log_action` varchar(50) NOT NULL, `log_description` text NOT NULL, PRIMARY KEY (`log_id`) -) ENGINE=MyISAM AUTO_INCREMENT=79 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=640 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -225,7 +226,7 @@ CREATE TABLE `usrData` ( PRIMARY KEY (`user_id`), UNIQUE KEY `IDX_login` (`user_login`), KEY `IDX_pass` (`user_pass`) -) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -240,7 +241,7 @@ CREATE TABLE `usrGroups` ( `usergroup_name` varchar(50) NOT NULL, `usergroup_description` varchar(255) DEFAULT NULL, PRIMARY KEY (`usergroup_id`) -) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -257,7 +258,6 @@ CREATE TABLE `usrProfiles` ( `userProfile_pEdit` bit(1) DEFAULT b'0', `userProfile_pAdd` bit(1) DEFAULT b'0', `userProfile_pConfig` bit(1) DEFAULT b'0', - `userProfile_pConfigCategories` bit(1) DEFAULT b'0', `userProfile_pConfigMasterPass` bit(1) DEFAULT b'0', `userProfile_pConfigBackup` bit(1) DEFAULT b'0', `userProfile_pUsers` bit(1) DEFAULT b'0', @@ -271,8 +271,11 @@ CREATE TABLE `usrProfiles` ( `userProfile_pFiles` bit(1) DEFAULT b'0', `userProfile_pConfigMenu` bit(1) DEFAULT b'0', `userProfile_pUsersMenu` bit(1) DEFAULT b'0', + `userProfile_pAppMgmt` bit(1) DEFAULT b'0', + `userProfile_pAppMgmtCategories` bit(1) DEFAULT b'0', + `userProfile_pAppMgmtCustomers` bit(1) DEFAULT b'0', PRIMARY KEY (`userprofile_id`) -) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -282,5 +285,4 @@ CREATE TABLE `usrProfiles` ( /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; - /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/inc/groups.class.php b/inc/groups.class.php index 137209e2..4b11c3ef 100644 --- a/inc/groups.class.php +++ b/inc/groups.class.php @@ -179,35 +179,19 @@ class SP_Groups { self::$queryLastId = DB::$lastId; - return TRUE; +// return TRUE; } /** * @brief Comprobar si un grupo está en uso - * @return bool + * @return array con el número de usuarios/cuentas que usan el grupo * * Esta función comprueba si un grupo está en uso por usuarios o cuentas. */ public static function checkGroupInUse() { - - $numUsers = self::getGroupInUsers(); - $numAccounts = self::getGroupInAccounts() + self::getGroupInAccountsSec(); - - $out = ''; - - if ($numUsers) { - $out[] = _('Usuarios') . " (" . $numUsers . ")"; - } - - if ($numAccounts) { - $out[] = _('Cuentas') . " (" . $numAccounts . ")"; - } - - if (is_array($out)) { - return implode('
', $out); - } - - return TRUE; + $count['users'] = self::getGroupInUsers(); + $count['accounts'] = self::getGroupInAccounts() + self::getGroupInAccountsSec(); + return $count; } /** @@ -233,7 +217,7 @@ class SP_Groups { * @return integer con el número total de cuentas */ private static function getGroupInAccounts() { - $query = "SELECT COUNT(*) as uses" + $query = "SELECT COUNT(*) as uses " . "FROM accounts " . "WHERE account_userGroupId = " . (int) self::$groupId; diff --git a/inc/html.class.php b/inc/html.class.php index 4a4149c4..9d285e54 100644 --- a/inc/html.class.php +++ b/inc/html.class.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link http://syspass.org - * @copyright 2012 Rubén Domínguez nuxsmin@syspass.org + * @copyright 2014 Rubén Domínguez nuxsmin@syspass.org * * This file is part of sysPass. * @@ -91,7 +91,7 @@ class SP_Html { */ public static function render($page = "main", $err = NULL) { $data['showlogo'] = 1; - + // UTF8 Headers header("Content-Type: text/html; charset=UTF-8"); @@ -110,7 +110,7 @@ class SP_Html { foreach (self::$htmlPage as $html) { if (is_array($html) && array_key_exists('include', $html)) { - self::getTemplate($html['include'],$data); + self::getTemplate($html['include'], $data); } else { echo $html . PHP_EOL; } @@ -146,9 +146,9 @@ class SP_Html { self::$htmlPage[] = '
'; self::$htmlPage[] = ''; self::$htmlPage[] = '
'; - + self::$htmlPage[] = array('include' => $page); - + self::$htmlPage[] = '
'; self::makeFooter($page); self::$htmlPage[] = '
'; @@ -254,7 +254,7 @@ class SP_Html { * @return string con los datos limpiados */ public static function sanitize(&$data) { - if (!$data){ + if (!$data) { return FALSE; } @@ -326,7 +326,7 @@ class SP_Html { $versionParameter = md5(implode(SP_Util::getVersion())); $js_files = self::getJs(); - + foreach ($js_files as $js) { self::$htmlPage[] = ''; } @@ -351,10 +351,10 @@ class SP_Html { array("src" => "js/jquery.tagsinput.js", "params" => ""), array("src" => "js/functions.php", "params" => "&l=" . SP_Init::$LANG . "&r=" . urlencode(base64_encode(SP_Init::$WEBROOT))) ); - + return $jsProp; } - + /** * @brief Devuelve información sobre la aplicación * @return array con las propiedades de la aplicación @@ -444,19 +444,19 @@ class SP_Html { exit(); } - private static function minifier($files){ - if ( !is_array($files) ){ + private static function minifier($files) { + if (!is_array($files)) { return FALSE; } - - foreach ($files as $file){ + + foreach ($files as $file) { //$output_min .= file_get_contents($file['src']); - include_once SP_Init::$SERVERROOT.'/'.$file['src']; + include_once SP_Init::$SERVERROOT . '/' . $file['src']; } - + //return $output_min; } - + /** * @brief Convertir un color RGB a HEX * @param array $rgb con color en RGB @@ -465,11 +465,105 @@ class SP_Html { * From: http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/ */ public static function rgb2hex($rgb) { - $hex = "#"; - $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT); - $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT); - $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT); + $hex = "#"; + $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT); + $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT); + $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT); - return $hex; // returns the hex value including the number sign (#) - } -} \ No newline at end of file + return $hex; // returns the hex value including the number sign (#) + } + + /** + * @brief Devolver una tabla con el resultado de una consulta y acciones + * @param array $arrTableProp con las propiedades de la tabla + * @return none + */ + public static function getQueryTable($arrTableProp, $queryItems) { + $sk = SP_Common::getSessionKey(TRUE); + + echo '
'; + echo '
    '; + echo '
  • '; + echo '
'; + echo '
'; + + if ($arrTableProp["header"]) { + echo '
' . $arrTableProp["header"] . '
'; + } + + echo '
'; + echo '
'; + echo '
    '; + + $cellWidth = floor(65 / count($arrTableProp["tblHeaders"])); + + foreach ($arrTableProp["tblHeaders"] as $header) { + if (is_array($header)) { + echo '
  • ' . $header['name'] . '
  • '; + } else { + echo '
  • ' . $header . '
  • '; + } + } + + echo '
'; + echo '
'; + + echo '
'; + + foreach ($queryItems as $item) { + $intId = $item->$arrTableProp["tblRowSrcId"]; + $action_check = array(); + $numActions = count($arrTableProp["actions"]); + $classActionsOptional = ( $numActions > 2 ) ? 'actions-optional' : ''; + + echo '
    '; + + foreach ($arrTableProp["tblRowSrc"] as $rowSrc) { + // If row is an array handle images in it + if (is_array($rowSrc)) { + echo '
  • '; + foreach ($rowSrc as $rowName => $imgProp) { + if ($item->$rowName) { + echo ''; + $action_check[$rowName] = 1; + } + } + echo '
  • '; + } else { + echo '
  • '; + echo ( $item->$rowSrc ) ? $item->$rowSrc : ' '; // Fix height + echo '
  • '; + } + } + + echo '
  • '; + //echo '
  • '; + foreach ($arrTableProp["actions"] as $action => $function) { + switch ($action) { + case "view": + echo ''; + break; + case "edit": + echo ''; + break; + case "del": + echo ''; + break; + case "pass": + if (isset($action_check['user_isLdap'])) { + break; + } + + echo ''; + break; + } + } + echo ($numActions > 2 ) ? '' : ''; + echo '
  • '; + echo '
'; + } + + echo '
'; + } + +} diff --git a/inc/import.class.php b/inc/import.class.php index b9393d38..8d0361d4 100644 --- a/inc/import.class.php +++ b/inc/import.class.php @@ -136,7 +136,6 @@ class SP_Import { $groupId = SP_Common::parseParams('s', 'ugroup', 0); $account = new SP_Account; - $customer = new SP_Customer; foreach (self::$fileContent as $data) { $fields = explode(';', $data); @@ -147,17 +146,17 @@ class SP_Import { list($accountName, $customerName, $categoryName, $url, $username, $password, $notes) = $fields; - $customer->customerName = $customerName; - if ( ! $customer->chekDupCustomer() ){ - $customerId = $customer->getCustomerByName(); + SP_Customer::$customerName = $customerName; + if ( !SP_Customer::checkDupCustomer() ){ + $customerId = SP_Customer::getCustomerByName(); } else{ - $customer->customerAdd(); - $customerId = $customer->customerLastId; + SP_Customer::addCustomer(); + $customerId = SP_Customer::$customerLastId; } $categoryId = SP_Category::getCategoryIdByName($categoryName); if ( $categoryId == 0 ){ - SP_Category::categoryAdd($categoryName); + SP_Category::addCategory($categoryName); $categoryId = SP_Category::$categoryLastId; } diff --git a/inc/init.php b/inc/init.php index 28e5d934..3c74684d 100644 --- a/inc/init.php +++ b/inc/init.php @@ -458,7 +458,7 @@ class SP_Init { $update = FALSE; $configVersion = (int) str_replace('.', '', SP_Config::getValue('version')); $databaseVersion = (int) str_replace('.', '', SP_Config::getConfigValue('version')); - $appVersion = (int) implode(SP_Util::getVersion()); + $appVersion = (int) implode(SP_Util::getVersion(TRUE)); if ( $databaseVersion < $appVersion && SP_Common::parseParams('g', 'nodbupgrade', 0) === 0){ if ( SP_Upgrade::needUpgrade($appVersion) && ! self::checkMaintenanceMode(TRUE) ){ diff --git a/inc/locales/en_US/LC_MESSAGES/messages.mo b/inc/locales/en_US/LC_MESSAGES/messages.mo index 661df5f92d745b135518ed13227a78bffafa1bb9..fe898accb153c043ccc89b725dd8f45805035b59 100644 GIT binary patch delta 14129 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 zV>9U7yKH7To~`0_%_`+customerName = $customer; + SP_Customer::$customerName = $customer; - if (!$objCustomer->chekDupCustomer()) { + if (!SP_Customer::checkDupCustomer()) { $num++; continue; } - if (!$objCustomer->customerAdd()) { + if (!SP_Customer::addCustomer()) { throw new MigrateException('critical', _('No es posible crear el cliente'), _('Contacte con el desarrollador')); @@ -330,7 +329,7 @@ class SP_Migrate { */ private static function insertAccounts($account) { if (!is_array(self::$customersByName)) { - $customers = SP_Customer::getCustomers(); + $customers = SP_Customer::getCustomers(NULL,TRUE); self::$customersByName = array_flip($customers); } @@ -481,7 +480,7 @@ class SP_Migrate { */ private static function insertAccountsHistory($accountHistory) { if (!is_array(self::$customersByName)) { - $customers = SP_Customer::getCustomers(); + $customers = SP_Customer::getCustomers(NULL,TRUE); self::$customersByName = array_flip($customers); } diff --git a/inc/profiles.class.php b/inc/profiles.class.php index 4d1a63af..16211cff 100644 --- a/inc/profiles.class.php +++ b/inc/profiles.class.php @@ -53,9 +53,10 @@ class SP_Profiles { 'userProfile_pDelete' => 0, 'userProfile_pFiles' => 0, 'userProfile_pConfig' => 0, - 'userProfile_pConfigCategories' => 0, 'userProfile_pConfigMasterPass' => 0, 'userProfile_pConfigBackup' => 0, + 'userProfile_pAppMgmtCategories' => 0, + 'userProfile_pAppMgmtCustomers' => 0, 'userProfile_pUsers' => 0, 'userProfile_pGroups' => 0, 'userProfile_pProfiles' => 0, @@ -99,9 +100,10 @@ class SP_Profiles { . 'userProfile_pDelete,' . 'userProfile_pFiles,' . 'userProfile_pConfig,' - . 'userProfile_pConfigCategories,' . 'userProfile_pConfigMasterPass,' . 'userProfile_pConfigBackup,' + . 'userProfile_pAppMgmtCategories,' + . 'userProfile_pAppMgmtCustomers,' . 'userProfile_pUsers,' . 'userProfile_pGroups,' . 'userProfile_pProfiles,' @@ -160,7 +162,8 @@ class SP_Profiles { */ public static function addProfile($profileProp = '') { $enableConfig = (int) ( $profileProp["pConfig"] || $profileProp["pConfigCat"] || $profileProp["pConfigMpw"] || $profileProp["pConfigBack"]); - $enableusers = (int) ( $profileProp["pUsers"] || $profileProp["pGroups"] || $profileProp["pProfiles"]); + $enableAppMgmt = (int) ( $profileProp["pAppMgmt"] || $profileProp["pAppMgmtCat"] || $profileProp["pAppMgmtCust"]); + $enableUsers = (int) ( $profileProp["pUsers"] || $profileProp["pGroups"] || $profileProp["pProfiles"]); $query = "INSERT INTO usrProfiles SET " . "userprofile_name = '" . DB::escape(self::$profileName) . "'," @@ -174,10 +177,12 @@ class SP_Profiles { . "userProfile_pFiles = " . $profileProp["pAccFiles"] . "," . "userProfile_pConfigMenu = " . $enableConfig . "," . "userProfile_pConfig = " . $profileProp["pConfig"] . "," - . "userProfile_pConfigCategories = " . $profileProp["pConfigCat"] . "," . "userProfile_pConfigMasterPass = " . $profileProp["pConfigMpw"] . "," . "userProfile_pConfigBackup = " . $profileProp["pConfigBack"] . "," - . "userProfile_pUsersMenu = " . $enableusers . "," + . "userProfile_pAppMgmtMenu = " . $enableAppMgmt . "," + . "userProfile_pAppMgmtCategories = " . $profileProp["pAppMgmtCat"] . "," + . "userProfile_pAppMgmtCustomers = " . $profileProp["pAppMgmtCust"] . "," + . "userProfile_pUsersMenu = " . $enableUsers . "," . "userProfile_pUsers = " . $profileProp["pUsers"] . "," . "userProfile_pGroups = " . $profileProp["pGroups"] . "," . "userProfile_pProfiles = " . $profileProp["pProfiles"] . "," @@ -198,7 +203,8 @@ class SP_Profiles { */ public static function updateProfile($profileProp = '') { $enableConfig = (int) ( $profileProp["pConfig"] || $profileProp["pConfigCat"] || $profileProp["pConfigMpw"] || $profileProp["pConfigBack"]); - $enableusers = (int) ( $profileProp["pUsers"] || $profileProp["pGroups"] || $profileProp["pProfiles"]); + $enableAppMgmt = (int) ( $profileProp["pAppMgmt"] || $profileProp["pAppMgmtCat"] || $profileProp["pAppMgmtCust"]); + $enableUsers = (int) ( $profileProp["pUsers"] || $profileProp["pGroups"] || $profileProp["pProfiles"]); $query = "UPDATE usrProfiles SET " . "userprofile_name = '" . DB::escape(self::$profileName) . "'," @@ -212,10 +218,12 @@ class SP_Profiles { . "userProfile_pFiles = " . $profileProp["pAccFiles"] . "," . "userProfile_pConfigMenu = " . $enableConfig . "," . "userProfile_pConfig = " . $profileProp["pConfig"] . "," - . "userProfile_pConfigCategories = " . $profileProp["pConfigCat"] . "," . "userProfile_pConfigMasterPass = " . $profileProp["pConfigMpw"] . "," . "userProfile_pConfigBackup = " . $profileProp["pConfigBack"] . "," - . "userProfile_pUsersMenu = " . $enableusers . "," + . "userProfile_pAppMgmtMenu = " . $enableAppMgmt . "," + . "userProfile_pAppMgmtCategories = " . $profileProp["pAppMgmtCat"] . "," + . "userProfile_pAppMgmtCustomers = " . $profileProp["pAppMgmtCust"] . "," + . "userProfile_pUsersMenu = " . $enableUsers . "," . "userProfile_pUsers = " . $profileProp["pUsers"] . "," . "userProfile_pGroups = " . $profileProp["pGroups"] . "," . "userProfile_pProfiles = " . $profileProp["pProfiles"] . "," @@ -253,20 +261,8 @@ class SP_Profiles { * @return mixed string con el número de usuarios, o bool si no está en uso */ public static function checkProfileInUse() { - - $numUsers = self::getProfileInUsers(); - - $out = ''; - - if ($numUsers) { - $out[] = _('Usuarios') . " (" . $numUsers . ")"; - } - - if (is_array($out)) { - return implode('
', $out); - } - - return TRUE; + $count['users'] = self::getProfileInUsers(); + return $count; } /** @@ -330,9 +326,10 @@ class SP_Profiles { . "userProfile_pFiles," . "userProfile_pConfigMenu," . "userProfile_pConfig," - . "userProfile_pConfigCategories," . "userProfile_pConfigMasterPass," . "userProfile_pConfigBackup," + . 'userProfile_pAppMgmtCategories,' + . 'userProfile_pAppMgmtCustomers,' . "userProfile_pUsersMenu," . "userProfile_pUsers," . "userProfile_pGroups," diff --git a/inc/tpl/accounts.php b/inc/tpl/accounts.php index ec8dbb58..0558f329 100644 --- a/inc/tpl/accounts.php +++ b/inc/tpl/accounts.php @@ -181,7 +181,7 @@ $maxFileSize = round(SP_Config::getValue('allowed_size') / 1024, 1);

@@ -197,7 +197,7 @@ $maxFileSize = round(SP_Config::getValue('allowed_size') / 1024, 1); category_name; } @@ -267,7 +267,9 @@ $maxFileSize = round(SP_Config::getValue('allowed_size') / 1024, 1); $otherUserId) { + $users = array_flip(DB::getValuesForSelect('usrData', 'user_id', 'user_name')); + + foreach ( $users as $otherUserName => $otherUserId) { $userSelected = ''; if ($otherUserId != $accountData->account_userGroupId && $otherUserId != $userId) { @@ -292,7 +294,9 @@ $maxFileSize = round(SP_Config::getValue('allowed_size') / 1024, 1); - - - - - - - - - - - - -
- -
-
- - - - - -
- - - - - - - -
- - - - - -
- - - - \ No newline at end of file +
+

+
+ + + + + + + + + + + + +
+ " /> +
" /> +
+ + + " /> + " /> + " /> + + + +
+
+
+
    +
  • +
+
+
\ No newline at end of file diff --git a/inc/tpl/customers.php b/inc/tpl/customers.php new file mode 100644 index 00000000..d3c3a0a1 --- /dev/null +++ b/inc/tpl/customers.php @@ -0,0 +1,66 @@ +. + * + */ + +defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); + +$customer = SP_Customer::getCustomerData($data['itemid']); +$activeTab = $data['active']; +?> + +
+

+
+ + + + + + + + + + + + +
+ " /> +
" /> +
+ + + " /> + " /> + " /> + + + +
+
+
+
    +
  • +
+
+
\ No newline at end of file diff --git a/inc/tpl/groups.php b/inc/tpl/groups.php index b978c632..672c09af 100644 --- a/inc/tpl/groups.php +++ b/inc/tpl/groups.php @@ -59,7 +59,7 @@ $activeTab = $data['active'];
    -
  • +
\ No newline at end of file diff --git a/inc/tpl/main.php b/inc/tpl/main.php index 880a6d41..841a4806 100644 --- a/inc/tpl/main.php +++ b/inc/tpl/main.php @@ -52,6 +52,7 @@ $chpass = ( ! isset($_SESSION['uisldap']) || $_SESSION['uisldap'] == 0 ) ? ' 'accsearch', 'title' => _('Buscar'), 'img' => 'search.png', 'checkaccess' => 0), array('name' => 'accnew', 'title' => _('Nueva Cuenta'), 'img' => 'add.png', 'checkaccess' => 1), array('name' => 'usersmenu', 'title' => _('Gestión de Usuarios'), 'img' => 'users.png', 'checkaccess' => 1), + array('name' => 'appmgmtmenu', 'title' => _('Gestión de Clientes y Categorías'), 'img' => 'appmgmt.png', 'checkaccess' => 0), array('name' => 'configmenu', 'title' => _('Configuración'), 'img' => 'config.png', 'checkaccess' => 1), array('name' => 'eventlog', 'title' => _('Registro de Eventos'), 'img' => 'log.png', 'checkaccess' => 1) ); diff --git a/inc/tpl/profiles.php b/inc/tpl/profiles.php index 6ec16664..2a18f306 100644 --- a/inc/tpl/profiles.php +++ b/inc/tpl/profiles.php @@ -72,11 +72,9 @@ $activeTab = $data['active'];
/> - - /> -
/> +
/>
@@ -93,6 +91,11 @@ $activeTab = $data['active'];
/> + + /> +
+ + />
@@ -126,7 +129,7 @@ $activeTab = $data['active'];
    -
  • +
\ No newline at end of file diff --git a/inc/tpl/search.php b/inc/tpl/search.php index 209e4ac0..5f3c0e58 100644 --- a/inc/tpl/search.php +++ b/inc/tpl/search.php @@ -68,8 +68,8 @@ $searchOrder = SP_Common::parseParams('s', 'accountSearchOrder', 0);
diff --git a/inc/tpl/users.php b/inc/tpl/users.php index f3deb37c..eb0145ae 100644 --- a/inc/tpl/users.php +++ b/inc/tpl/users.php @@ -96,14 +96,14 @@ $ro = ( $user['checks']['user_isLdap'] ) ? "READONLY" : ""; - + - + @@ -203,7 +203,7 @@ $ro = ( $user['checks']['user_isLdap'] ) ? "READONLY" : "";
    -
  • +
diff --git a/inc/upgrade.class.php b/inc/upgrade.class.php index 7ed6b92a..33418868 100644 --- a/inc/upgrade.class.php +++ b/inc/upgrade.class.php @@ -30,7 +30,7 @@ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo' */ class SP_Upgrade { private static $result = array(); - private static $upgrade = array(110); + private static $upgrade = array(110,1121); /** * @brief Inicia el proceso de actualización de la BBDD @@ -75,6 +75,10 @@ class SP_Upgrade { $queries[] = "ALTER TABLE `accHistory` ADD COLUMN `accHistory_otherUserEdit` BIT NULL AFTER `acchistory_mPassHash`, ADD COLUMN `accHistory_otherGroupEdit` VARCHAR(45) NULL AFTER `accHistory_otherUserEdit`;"; $queries[] = "ALTER TABLE `accFiles` CHANGE COLUMN `accfile_type` `accfile_type` VARCHAR(100) NOT NULL ;"; break; + case 1121: + $queries[] = "ALTER TABLE `categories` ADD COLUMN `category_description` VARCHAR(255) NULL AFTER `category_name`;"; + $queries[] = "ALTER TABLE `usrProfiles` ADD COLUMN `userProfile_pAppMgmtMenu` BIT(1) NULL DEFAULT b'0' AFTER `userProfile_pUsersMenu`,CHANGE COLUMN `userProfile_pConfigCategories` `userProfile_pAppMgmtCategories` BIT(1) NULL DEFAULT b'0' AFTER `userProfile_pAppMgmtMenu`,ADD COLUMN `userProfile_pAppMgmtCustomers` BIT(1) NULL DEFAULT b'0' AFTER `userProfile_pAppMgmtCategories`;"; + break; default : self::$result['text'][] = _('No es necesario actualizar la Base de Datos.'); return TRUE; diff --git a/inc/users.class.php b/inc/users.class.php index 268ef454..bf2845f0 100644 --- a/inc/users.class.php +++ b/inc/users.class.php @@ -172,136 +172,6 @@ class SP_Users { return $queryRes; } - /** - * @brief Obtener los datos para generar un select - * @param string $tblName con el nombre de la tabla a cunsultar - * @param string $tblColId con el nombre de la columna a mostrar - * @param array $arrFilter con las columnas a filtrar - * @return array con los valores del select con el Id como clave y el nombre como valor - */ - public static function getValuesForSelect($tblName, $tblColId, $tblColName, $arrFilter = "") { - if (!$tblName || !$tblColId || !$tblColName) { - return; - } - - $strFilter = ( is_array($arrFilter) ) ? " WHERE " . implode(" OR ", $arrFilter) : ""; - - $query = "SELECT $tblColId, $tblColName FROM $tblName $strFilter"; - $queryRes = DB::getResults($query, __FUNCTION__); - - if ($queryRes === FALSE) { - return FALSE; - } - - $arrValues = array(); - - foreach ($queryRes as $row) { - $arrValues[$row->$tblColId] = $row->$tblColName; - } - - return $arrValues; - } - - /** - * @brief Devolver la tabla de usuarios, grupos o perfiles - * @param array $arrUsersTableProp con las propiedades de la tabla - * @return none - */ - public static function getUsrGrpTable($arrUsersTableProp, $queryItems = NULL) { - $sk = SP_Common::getSessionKey(TRUE); - - echo '
'; - echo '
    '; - echo '
  • '; - echo '
'; - echo '
'; - - if ($arrUsersTableProp["header"]) { - echo '
' . $arrUsersTableProp["header"] . '
'; - } - - echo '
'; - echo '
'; - echo '
    '; - - $cellWidth = floor(65 / count($arrUsersTableProp["tblHeaders"])); - - foreach ($arrUsersTableProp["tblHeaders"] as $header) { - if (is_array($header)) { - echo '
  • ' . $header['name'] . '
  • '; - } else { - echo '
  • ' . $header . '
  • '; - } - } - - echo '
'; - echo '
'; - - echo '
'; - - if (!is_null($queryItems)){ - $items = $queryItems; - } else{ - $items = self::$queryRes; - } - - foreach ( $items as $item) { - $intId = $item->$arrUsersTableProp["tblRowSrcId"]; - $action_check = array(); - $numActions = count($arrUsersTableProp["actions"]); - $classActionsOptional = ( $numActions > 2 ) ? 'actions-optional' : ''; - - $lnkView = ''; - $lnkEdit = ''; - $lnkDel = ''; - $lnkPass = ''; - - echo '
    '; - - foreach ($arrUsersTableProp["tblRowSrc"] as $rowSrc) { - // If row is an array handle images in it - if (is_array($rowSrc)) { - echo '
  • '; - foreach ($rowSrc as $rowName => $imgProp) { - if ($item->$rowName) { - echo ''; - $action_check[$rowName] = 1; - } - } - echo '
  • '; - } else { - echo '
  • '; - echo ( $item->$rowSrc ) ? $item->$rowSrc : ' '; // Fix height - echo '
  • '; - } - } - - echo '
  • '; - //echo '
  • '; - foreach ($arrUsersTableProp["actions"] as $action) { - switch ($action) { - case "view": - echo $lnkView; - break; - case "edit": - echo $lnkEdit; - break; - case "del": - echo $lnkDel; - break; - case "pass": - echo (!isset($action_check['user_isLdap']) ) ? $lnkPass : ''; - break; - } - } - echo ($numActions > 2 ) ? '' : ''; - echo '
  • '; - echo '
'; - } - - echo '
'; - } - /** * @brief Obtener los datos de un usuario * @param int $id con el Id del usuario a consultar @@ -965,25 +835,4 @@ class SP_Users { return TRUE; } - - /** - * @brief Obtiene el listado de usuarios - * @return array con los registros con nombre de usuario como clave e id de usuario como valor - */ - public static function getUsersIdName(){ - $query = "SELECT user_id," - . "user_name " - . "FROM usrData"; - $queryRes = DB::getResults($query, __FUNCTION__, TRUE); - - if ( $queryRes === FALSE ){ - return FALSE; - } - - foreach ( $queryRes as $users ){ - $arrUsers[$users->user_name] = $users->user_id; - } - - return $arrUsers; - } } \ No newline at end of file diff --git a/inc/util.class.php b/inc/util.class.php index f20c5fbe..e099a68a 100644 --- a/inc/util.class.php +++ b/inc/util.class.php @@ -168,8 +168,15 @@ class SP_Util { * @brief Devuelve la versión de sysPass * @return array con el número de versión */ - public static function getVersion() { - return array(1, 1, 02); + public static function getVersion($retBuild = FALSE) { + $build = 1; + $version = array(1, 1, 2); + + if ( $retBuild ){ + array_push($version, $build); + } + + return $version; } /** diff --git a/js/functions.js b/js/functions.js index 3b4e6759..dd7a41c7 100644 --- a/js/functions.js +++ b/js/functions.js @@ -654,58 +654,8 @@ function importFile(sk){ }); } -// Función para mostrar los registros de usuarios y grupos -function usersData(id, type, sk, active, view){ - var data = {'id' : id, 'type' : type, 'sk' : sk, 'active' : active, 'view' : view, 'is_ajax' : 1}; - var url = APP_ROOT + '/ajax/ajax_usersMgmt.php'; - - $.fancybox.showLoading(); - - $.ajax({ - type: 'POST', - dataType: 'html', - url: url, - data: data, - success: function(response){ - $.fancybox(response,{ - padding: [0,10,10,10], - afterClose: function(){doAction('usersmenu','',active);} - }); - }, - error:function(jqXHR, textStatus, errorThrown){ - var txt = LANG[1] + '

' + errorThrown + textStatus + '

'; - resMsg("error", txt); - }, - complete: function(){$.fancybox.hideLoading();} - }); -} - -// Función para editar los registros de usuarios y grupos -function usersMgmt(frmId, isDel, id, type, sk){ - var data; - var url = '/ajax/ajax_usersSave.php'; - - if ( isDel === 1 ){ - var data = {'id' : id, 'type' : type, 'action' : 4, 'sk' : sk }; - var atext = '

' + LANG[12] + '

'; - var active = frmId; - - alertify.confirm(atext, function (e) { - if (e) { - usersAjax(data, url); - doAction('usersmenu','',active) - } - }); - } else { - data = $("#" + frmId).serialize(); - //type = parseInt($('input:[name=type]').val()); - - usersAjax(data, url); - } -} - -// Función para realizar la petición ajax de gestión de usuarios -function usersAjax(data, url){ +// Función para realizar la petición ajax +function sendAjax(data, url){ $.fancybox.showLoading(); $.ajax({ @@ -772,6 +722,55 @@ function usrUpdPass(id,usrlogin){ }); } +// Función para mostrar los datos de un registro +function appMgmtData(id, type, sk, active, view, nextaction){ + var data = {'id' : id, 'type' : type, 'sk' : sk, 'active' : active, 'view' : view, 'is_ajax' : 1}; + var url = APP_ROOT + '/ajax/ajax_appMgmtData.php'; + + $.fancybox.showLoading(); + + $.ajax({ + type: 'POST', + dataType: 'html', + url: url, + data: data, + success: function(response){ + $.fancybox(response,{ + padding: [0,10,10,10], + afterClose: function(){doAction(nextaction,'',active);} + }); + }, + error:function(jqXHR, textStatus, errorThrown){ + var txt = LANG[1] + '

' + errorThrown + textStatus + '

'; + resMsg("error", txt); + }, + complete: function(){$.fancybox.hideLoading();} + }); +} + +// Función para editar los datos de un registro +function appMgmtSave(frmId, isDel, id, type, sk, nextaction){ + var data; + var url = '/ajax/ajax_appMgmtSave.php'; + + if ( isDel === 1 ){ + var data = {'id' : id, 'type' : type, 'action' : 4, 'sk' : sk }; + var atext = '

' + LANG[12] + '

'; + var active = frmId; + + alertify.confirm(atext, function (e) { + if (e) { + sendAjax(data, url); + doAction(nextaction,'',active) + } + }); + } else { + data = $("#" + frmId).serialize(); + + sendAjax(data, url); + } +} + // Función para verificar si existen actualizaciones function checkUpds(){ $.ajax({