PageRenderTime 54ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/controllers/admin/AdminEmployeesController.php

https://bitbucket.org/enurkov/prestashop
PHP | 485 lines | 402 code | 44 blank | 39 comment | 66 complexity | d5fcbb66fdb2c46f8e60c02792437034 MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2012 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2012 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class AdminEmployeesControllerCore extends AdminController
  27. {
  28. /** @var array profiles list */
  29. protected $profiles_array = array();
  30. /** @var array themes list*/
  31. protected $themes = array();
  32. /** @var array tabs list*/
  33. protected $tabs_list = array();
  34. protected $restrict_edition = false;
  35. public function __construct()
  36. {
  37. $this->table = 'employee';
  38. $this->className = 'Employee';
  39. $this->lang = false;
  40. $this->addRowAction('edit');
  41. $this->addRowAction('delete');
  42. $this->context = Context::getContext();
  43. $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
  44. /*
  45. check if there are more than one superAdmin
  46. if it's the case then we can delete a superAdmin
  47. */
  48. $super_admin = Employee::countProfile(_PS_ADMIN_PROFILE_, true);
  49. if ($super_admin == 1)
  50. {
  51. $super_admin_array = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_, true);
  52. $super_admin_id = array();
  53. foreach ($super_admin_array as $key => $val)
  54. $super_admin_id[] = $val['id_employee'];
  55. $this->addRowActionSkipList('delete', $super_admin_id);
  56. }
  57. $profiles = Profile::getProfiles($this->context->language->id);
  58. if (!$profiles)
  59. $this->errors[] = Tools::displayError('No profile');
  60. else
  61. foreach ($profiles as $profile)
  62. $this->profiles_array[$profile['name']] = $profile['name'];
  63. $this->fields_list = array(
  64. 'id_employee' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
  65. 'lastname' => array('title' => $this->l('Last name'), 'width' => 'auto'),
  66. 'firstname' => array('title' => $this->l('First name'), 'width' => 130),
  67. 'email' => array('title' => $this->l('E-mail address'), 'width' => 180),
  68. 'profile' => array('title' => $this->l('Profile'), 'width' => 90, 'type' => 'select', 'list' => $this->profiles_array, 'filter_key' => 'pl!name'),
  69. 'active' => array('title' => $this->l('Can log in'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'width' => 30),
  70. );
  71. $this->fields_options = array(
  72. 'general' => array(
  73. 'title' => $this->l('Employee options'),
  74. 'fields' => array(
  75. 'PS_PASSWD_TIME_BACK' => array(
  76. 'title' => $this->l('Password regeneration'),
  77. 'desc' => $this->l('Security: minimum time to wait between two password changes'),
  78. 'cast' => 'intval',
  79. 'size' => 5,
  80. 'type' => 'text',
  81. 'suffix' => ' '.$this->l('minutes'),
  82. 'visibility' => Shop::CONTEXT_ALL
  83. ),
  84. 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG' => array(
  85. 'title' => $this->l('Memorize language used in Admin panel forms'),
  86. 'desc' => $this->l('Allow employees to select a specific language for Admin panel forms'),
  87. 'cast' => 'intval',
  88. 'type' => 'select',
  89. 'identifier' => 'value',
  90. 'list' => array(
  91. '0' => array('value' => 0, 'name' => $this->l('No')),
  92. '1' => array('value' => 1, 'name' => $this->l('Yes')
  93. )
  94. ), 'visibility' => Shop::CONTEXT_ALL)
  95. ),
  96. 'submit' => array()
  97. )
  98. );
  99. $path = _PS_ADMIN_DIR_.'/themes/';
  100. foreach (scandir($path) as $theme)
  101. if ($theme[0] != '.' && is_dir($path.$theme) && file_exists($path.$theme.'/css/admin.css'))
  102. $this->themes[] = $theme;
  103. $home_tab = Tab::getInstanceFromClassName('adminHome');
  104. $this->tabs_list[$home_tab->id] = array(
  105. 'name' => $home_tab->name[$this->context->language->id],
  106. 'id_tab' => $home_tab->id,
  107. 'children' => array(array('id_tab' =>$home_tab->id, 'name' => $home_tab->name[$this->context->language->id])));
  108. foreach (Tab::getTabs($this->context->language->id, 0) as $tab)
  109. {
  110. if (Tab::checkTabRights($tab['id_tab']))
  111. {
  112. $this->tabs_list[$tab['id_tab']] = $tab;
  113. foreach (Tab::getTabs($this->context->language->id, $tab['id_tab']) as $children)
  114. if (Tab::checkTabRights($children['id_tab']))
  115. $this->tabs_list[$tab['id_tab']]['children'][] = $children;
  116. }
  117. }
  118. parent::__construct();
  119. // An employee can edit its own profile
  120. if ($this->context->employee->id == Tools::getValue('id_employee'))
  121. {
  122. $this->tabAccess['view'] = '1';
  123. if (!$this->tabAccess['edit'])
  124. $this->restrict_edition = true;
  125. $this->tabAccess['edit'] = '1';
  126. }
  127. }
  128. public function renderList()
  129. {
  130. $this->_select = 'pl.`name` AS profile';
  131. $this->_join = 'LEFT JOIN `'._DB_PREFIX_.'profile` p ON a.`id_profile` = p.`id_profile`
  132. LEFT JOIN `'._DB_PREFIX_.'profile_lang` pl ON (pl.`id_profile` = p.`id_profile` AND pl.`id_lang` = '.(int)$this->context->language->id.')';
  133. return parent::renderList();
  134. }
  135. public function renderForm()
  136. {
  137. if (!($obj = $this->loadObject(true)))
  138. return;
  139. $available_profiles = Profile::getProfiles($this->context->language->id);
  140. if ($obj->id_profile == _PS_ADMIN_PROFILE_ && $this->context->employee->id_profile != _PS_ADMIN_PROFILE_)
  141. {
  142. $this->errors[] = Tools::displayError('You cannot edit SuperAdmin profile.');
  143. return parent::renderForm();
  144. }
  145. $this->fields_form = array(
  146. 'legend' => array(
  147. 'title' => $this->l('Employees'),
  148. 'image' => '../img/admin/nav-user.gif'
  149. ),
  150. 'input' => array(
  151. array(
  152. 'type' => 'text',
  153. 'label' => $this->l('First name:'),
  154. 'name' => 'firstname',
  155. 'size' => 33,
  156. 'required' => true
  157. ),
  158. array(
  159. 'type' => 'text',
  160. 'label' => $this->l('Last name:'),
  161. 'name' => 'lastname',
  162. 'size' => 33,
  163. 'required' => true
  164. ),
  165. array(
  166. 'type' => 'password',
  167. 'label' => $this->l('Password:'),
  168. 'name' => 'passwd',
  169. 'required' => true,
  170. 'size' => 33,
  171. 'desc' => ($obj->id ?
  172. $this->l('Leave blank if you do not want to change your password') :
  173. $this->l('Min. 8 characters; use only letters, numbers or').' -_')
  174. ),
  175. array(
  176. 'type' => 'text',
  177. 'label' => $this->l('E-mail address:'),
  178. 'name' => 'email',
  179. 'size' => 33,
  180. 'required' => true
  181. ),
  182. array(
  183. 'type' => 'color',
  184. 'label' => $this->l('Admin panel color:'),
  185. 'name' => 'bo_color',
  186. 'class' => 'color mColorPickerInput',
  187. 'size' => 20,
  188. 'desc' => $this->l('Admin panel background will be displayed in this color. HTML colors only (e.g.').' "lightblue", "#CC6600")'
  189. ),
  190. array(
  191. 'type' => 'default_tab',
  192. 'label' => $this->l('Default page:'),
  193. 'name' => 'default_tab',
  194. 'desc' => $this->l('This page will be displayed just after login'),
  195. 'options' => $this->tabs_list
  196. ),
  197. array(
  198. 'type' => 'text',
  199. 'label' => $this->l('Back Office width:'),
  200. 'name' => 'bo_width',
  201. 'size' => 10,
  202. 'desc' => $this->l('Back Office width, in pixels. The value "0" means that the Back Office width will be flexible.')
  203. ),
  204. array(
  205. 'type' => 'select',
  206. 'label' => $this->l('Language:'),
  207. 'name' => 'id_lang',
  208. 'required' => true,
  209. 'options' => array(
  210. 'query' => Language::getLanguages(),
  211. 'id' => 'id_lang',
  212. 'name' => 'name'
  213. )
  214. ),
  215. array(
  216. 'type' => 'select_theme',
  217. 'label' => $this->l('Theme:'),
  218. 'name' => 'bo_theme',
  219. 'options' => array('query' => $this->themes),
  220. 'desc' => $this->l('Back Office theme')
  221. ),
  222. array(
  223. 'type' => 'radio',
  224. 'label' => $this->l('Show screencast at log in:'),
  225. 'name' => 'bo_show_screencast',
  226. 'desc' => $this->l('Display the welcome video in the Admin panel dashboard at log in'),
  227. 'required' => false,
  228. 'class' => 't',
  229. 'is_bool' => true,
  230. 'values' => array(
  231. array(
  232. 'id' => 'bo_show_screencast_on',
  233. 'value' => 1,
  234. 'label' => $this->l('Enabled')
  235. ),
  236. array(
  237. 'id' => 'bo_show_screencast_off',
  238. 'value' => 0,
  239. 'label' => $this->l('Disabled')
  240. )
  241. )
  242. )
  243. )
  244. );
  245. if ((int)$this->tabAccess['edit'] && !$this->restrict_edition)
  246. {
  247. $this->fields_form['input'][] = array(
  248. 'type' => 'radio',
  249. 'label' => $this->l('Status:'),
  250. 'name' => 'active',
  251. 'required' => false,
  252. 'class' => 't',
  253. 'is_bool' => true,
  254. 'values' => array(
  255. array(
  256. 'id' => 'active_on',
  257. 'value' => 1,
  258. 'label' => $this->l('Enabled')
  259. ),
  260. array(
  261. 'id' => 'active_off',
  262. 'value' => 0,
  263. 'label' => $this->l('Disabled')
  264. )
  265. ),
  266. 'desc' => $this->l('Allow or disallow this employee to log into the Admin panel')
  267. );
  268. // if employee is not SuperAdmin (id_profile = 1), don't make it possible to select the admin profile
  269. if ($this->context->employee->id_profile != _PS_ADMIN_PROFILE_)
  270. foreach ($available_profiles as $i => $profile)
  271. if ($available_profiles[$i]['id_profile'] == _PS_ADMIN_PROFILE_)
  272. {
  273. unset($available_profiles[$i]);
  274. break;
  275. }
  276. $this->fields_form['input'][] = array(
  277. 'type' => 'select',
  278. 'label' => $this->l('Profile:'),
  279. 'name' => 'id_profile',
  280. 'required' => true,
  281. 'options' => array(
  282. 'query' => $available_profiles,
  283. 'id' => 'id_profile',
  284. 'name' => 'name',
  285. 'default' => array(
  286. 'value' => '',
  287. 'label' => $this->l('-- Choose --')
  288. )
  289. )
  290. );
  291. if (Shop::isFeatureActive())
  292. {
  293. $this->context->smarty->assign('_PS_ADMIN_PROFILE_', (int)_PS_ADMIN_PROFILE_);
  294. $this->fields_form['input'][] = array(
  295. 'type' => 'shop',
  296. 'label' => $this->l('Shop association:'),
  297. 'desc' => $this->l('Select the shops the employee is allowed to access'),
  298. 'name' => 'checkBoxShopAsso',
  299. );
  300. }
  301. }
  302. $this->fields_form['submit'] = array(
  303. 'title' => $this->l(' Save '),
  304. 'class' => 'button'
  305. );
  306. $this->fields_value['passwd'] = false;
  307. if (empty($obj->id))
  308. $this->fields_value['id_lang'] = $this->context->language->id;
  309. return parent::renderForm();
  310. }
  311. protected function _childValidation()
  312. {
  313. if (!($obj = $this->loadObject(true)))
  314. return false;
  315. $email = $this->getFieldValue($obj, 'email');
  316. if (!Validate::isEmail($email))
  317. $this->errors[] = Tools::displayError('Invalid e-mail');
  318. else if (Employee::employeeExists($email) && !Tools::getValue('id_employee'))
  319. $this->errors[] = Tools::displayError('An account already exists for this e-mail address:').' '.$email;
  320. }
  321. public function postProcess()
  322. {
  323. if (Tools::isSubmit('deleteemployee') || Tools::isSubmit('status') || Tools::isSubmit('statusemployee'))
  324. {
  325. /* PrestaShop demo mode */
  326. if (_PS_MODE_DEMO_ && $id_employee = Tools::getValue('id_employee') && (int)$id_employee == _PS_DEMO_MAIN_BO_ACCOUNT_)
  327. {
  328. $this->errors[] = Tools::displayError('This functionality has been disabled.');
  329. return;
  330. }
  331. if ($this->context->employee->id == Tools::getValue('id_employee'))
  332. {
  333. $this->errors[] = Tools::displayError('You cannot disable or delete your own account.');
  334. return false;
  335. }
  336. $employee = new Employee(Tools::getValue('id_employee'));
  337. if ($employee->isLastAdmin())
  338. {
  339. $this->errors[] = Tools::displayError('You cannot disable or delete the last administrator account.');
  340. return false;
  341. }
  342. // It is not possible to delete an employee if he manages warehouses
  343. $warehouses = Warehouse::getWarehousesByEmployee((int)Tools::getValue('id_employee'));
  344. if (Tools::isSubmit('deleteemployee') && count($warehouses) > 0)
  345. {
  346. $this->errors[] = Tools::displayError('You cannot delete this account because it manages warehouses. Check your warehouses first.');
  347. return false;
  348. }
  349. }
  350. elseif (Tools::isSubmit('submitAddemployee'))
  351. {
  352. $employee = new Employee((int)Tools::getValue('id_employee'));
  353. // If the employee is editing its own account
  354. if ($this->restrict_edition)
  355. {
  356. $_POST['id_profile'] = $_GET['id_profile'] = $employee->id_profile;
  357. $_POST['active'] = $_GET['active'] = $employee->active;
  358. // Unset set shops
  359. foreach ($_POST as $postkey => $postvalue)
  360. if (strstr($postkey, 'checkBoxShopAsso_'.$this->table) !== false)
  361. unset($_POST[$postkey]);
  362. foreach ($_GET as $postkey => $postvalue)
  363. if (strstr($postkey, 'checkBoxShopAsso_'.$this->table) !== false)
  364. unset($_GET[$postkey]);
  365. // Add current shops associated to the employee
  366. $result = Shop::getShopById((int)$employee->id, $this->identifier, $this->table);
  367. foreach ($result as $row)
  368. {
  369. $key = 'checkBoxShopAsso_'.$this->table;
  370. if (!isset($_POST[$key]))
  371. $_POST[$key] = array();
  372. if (!isset($_GET[$key]))
  373. $_GET[$key] = array();
  374. $_POST[$key][$row['id_shop']] = 1;
  375. $_GET[$key][$row['id_shop']] = 1;
  376. }
  377. }
  378. //if profile is super admin, manually fill checkBoxShopAsso_employee because in the form they are disabled.
  379. if ($_POST['id_profile'] == _PS_ADMIN_PROFILE_)
  380. {
  381. $result = Db::getInstance()->executeS('SELECT id_shop FROM '._DB_PREFIX_.'shop');
  382. foreach ($result as $row)
  383. {
  384. $key = 'checkBoxShopAsso_'.$this->table;
  385. if (!isset($_POST[$key]))
  386. $_POST[$key] = array();
  387. if (!isset($_GET[$key]))
  388. $_GET[$key] = array();
  389. $_POST[$key][$row['id_shop']] = 1;
  390. $_GET[$key][$row['id_shop']] = 1;
  391. }
  392. }
  393. if ($employee->isLastAdmin())
  394. {
  395. if (Tools::getValue('id_profile') != (int)_PS_ADMIN_PROFILE_)
  396. {
  397. $this->errors[] = Tools::displayError('You should have at least one employee in the administrator group.');
  398. return false;
  399. }
  400. if (Tools::getvalue('active') == 0)
  401. {
  402. $this->errors[] = Tools::displayError('You cannot disable or delete the last administrator account.');
  403. return false;
  404. }
  405. }
  406. if (!in_array(Tools::getValue('bo_theme'), $this->themes))
  407. {
  408. $this->errors[] = Tools::displayError('Invalid theme.');
  409. return false;
  410. }
  411. $assos = $this->getSelectedAssoShop($this->table);
  412. if (!$assos && $this->table = 'employee')
  413. if (Shop::isFeatureActive() && _PS_ADMIN_PROFILE_ != $_POST['id_profile'])
  414. $this->errors[] = Tools::displayError('The employee must be associated with at least one shop');
  415. }
  416. return parent::postProcess();
  417. }
  418. public function initContent()
  419. {
  420. if ($this->context->employee->id == Tools::getValue('id_employee'))
  421. $this->display = 'edit';
  422. return parent::initContent();
  423. }
  424. public function ajaxProcessGetTabByIdProfile()
  425. {
  426. $id_profile = Tools::getValue('id_profile');
  427. $tabs = Tab::getTabByIdProfile(0, $id_profile);
  428. $this->tabs_list = array();
  429. foreach ($tabs as $tab)
  430. {
  431. if (Tab::checkTabRights($tab['id_tab']))
  432. {
  433. $this->tabs_list[$tab['id_tab']] = $tab;
  434. foreach (Tab::getTabByIdProfile($tab['id_tab'], $id_profile) as $children)
  435. if (Tab::checkTabRights($children['id_tab']))
  436. $this->tabs_list[$tab['id_tab']]['children'][] = $children;
  437. }
  438. }
  439. die(Tools::jsonEncode($this->tabs_list));
  440. }
  441. }