1 <?php
2
3 namespace Objednavky;
4
5 use Nette\Application\UI;
6 use Nette\Utils\Html;
7 use Nette\Database\Table\Selection;
8 use Kdyby\BootstrapFormRenderer\BootstrapRenderer;
9 use PLus\Orders\Repositories;
10
11
12 13 14 15 16
17 class UserPresenter extends BasePresenter {
18
19
20 public $userRepository;
21
22
23 public $unitRepository;
24
25
26 public $roleRepository;
27
28
29 public $departmentRepository;
30
31
32 public $areaRepository;
33
34
35 public $parameters;
36
37
38 public $mailerCfg;
39
40
41
42 public function createComponentGrid($name) {
43
44 $user = $this->getUser();
45
46 $grid = new \Grido\Grid($this, $name);
47 $grid->setmodel($this->userRepository->getGridSelection());
48
49 $grid->translator->lang = 'cs';
50 $grid->defaultPerPage = 15;
51 $grid->filterRenderType = \Grido\Components\Filters\Filter::RENDER_INNER;
52 $grid->setRememberState(TRUE);
53
54 $grid->addColumnText('username', 'Login')
55 ->setSortable()
56 ->setFilterText()
57 ->setSuggestion();
58 $grid->getColumn('username')->headerPrototype->style['width'] = '5%';
59 $grid->getColumn('username')->cellPrototype->class[] = 'center';
60
61 $grid->addColumnText('jname', 'Jméno')
62 ->setSortable()
63 ->setColumn('jname')
64 ->setFilterText()
65 ->setColumn('jname')
66 ->setWhere(function ($value, $connection){ $connection->where("CASE WHEN user.isunit=1 THEN :unit_user.unit.name ELSE CONCAT_WS(' ',user.firstname, user.lastname) END LIKE ?", "%$value%");});
67 $grid->getColumn('jname')->headerPrototype->style['width'] = '20%';
68
69
70 $grid->addColumnEmail('email', 'Email')
71 ->setSortable()
72 ->setFilterText();
73 $grid->getColumn('email')->cellPrototype->class[] = 'center';
74 $grid->getColumn('email')->headerPrototype->style['width'] = '12%';
75
76
77 $column = new \Grido\Components\Columns\Boolean($grid, 'isunit', 'Oddělení');
78 $column->setSortable()
79 ->headerPrototype->style['width'] ='4%';
80 $grid->getColumn('isunit')->headerPrototype->class[] = 'center';
81
82 $list = array(''=>'','0'=>'ne','1'=>'ano');
83 $grid->addFilterSelect('isunit', '', $list);
84
85 $column = new \Grido\Components\Columns\Boolean($grid, 'ischief', 'Vedoucí');
86 $column->setSortable()
87 ->headerPrototype->style['width'] ='4%';
88 $grid->getColumn('ischief')->headerPrototype->class[] = 'center';
89 $grid->addFilterSelect('ischief', '', $list);
90
91
92 $grid->addActionHref('view', 'Zobrazit')
93 ->setIcon('fa fa-eye fa-fw');
94
95
96 $grid->setExport();
97
98 }
99
100
101 public function renderView($id){
102 $users = $this->userRepository->findById($id);
103 if (!$users) {
104 $this->flashMessage('Uživatel ID: '.$id.' nebyl dohledán.', 'error');
105 $this->redirect('Homepage:default');
106 }
107
108 if($this->getUser()->getId() == $id || $this->getUser()->isInRole('admin')) {
109 $this->template->users = $users;
110 }
111 else {
112 $this->flashMessage('Nemáte právo přístupu k detailu uživatele ID: '.$id, 'error');
113 $this->redirect('Homepage:default');
114 }
115
116 $this->template->roleRepository = $this->roleRepository;
117 $this->template->departmentRepository = $this->departmentRepository;
118
119 $this->template->userunit = $this->userRepository->findUserUnitById($id);
120 $this->template->userroles = $this->roleRepository->findPairRoleById($id);
121 $this->template->userdepartment = $this->userRepository->findUserDepartmentById($id);
122 $this->template->userasboss = $this->departmentRepository->findAll4BossById($id);
123 $this->template->userareas = $this->userRepository->getUserAreaById($id);
124 $this->template->userns = $this->unitRepository->getFullUnits($id);
125
126
127
128 }
129
130
131 132 133 134 135
136 public function createComponentAddArea() {
137
138 $form = new UI\Form();
139 $form->setRenderer(new BootstrapRenderer());
140
141 $form->getElementPrototype()->class = 'form-horizontal';
142 $form->addSelect('area_id', 'Oblast:', $this->areaRepository->getPairData())
143 ->setAttribute('class', 'form-control');
144
145 $form->addSubmit('saving', 'Zařadit')
146 ->setAttribute('class', 'btn btn-primary');
147
148 $form->onSuccess[] = $this->addAreaSubmitted;
149
150 return $form;
151 }
152
153 public function addAreaSubmitted($form) {
154
155 try {
156 $iduser = $this->getParameter('id');
157 $area = $form->getValues();
158
159 $this->userRepository->assignArea($area->area_id, $iduser);
160
161 } catch (\PDOException $e) {
162 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
163 }
164 }
165
166 167 168 169 170
171 public function createComponentRemoveArea() {
172
173 $form = new UI\Form();
174 $form->setRenderer(new BootstrapRenderer());
175 $iduser = $this->getParameter('id');
176
177 $form->getElementPrototype()->class = 'form-horizontal';
178 $form->addSelect('area_id', 'Oblast:', $this->areaRepository->findPairAreaById($iduser))
179 ->setAttribute('class', 'form-control');
180
181 $form->addSubmit('delete', 'Odebrat')
182 ->setAttribute('class', 'btn btn-primary');
183
184 $form->onSuccess[] = $this->removeAreaSubmitted;
185
186 return $form;
187 }
188
189 public function removeAreaSubmitted($form) {
190 try {
191 $iduser = $this->getParameter('id');
192 $area = $form->getValues();
193
194 $this->userRepository->removeAssignedArea($area->area_id, $iduser);
195
196 } catch (\PDOException $e) {
197 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
198 }
199 }
200
201 202 203 204 205
206 public function createComponentAddRole() {
207
208 $form = new UI\Form();
209 $form->setRenderer(new BootstrapRenderer());
210
211 $form->getElementPrototype()->class = 'form-horizontal';
212 $form->addSelect('role_code', 'Role:', $this->roleRepository->getPairData())
213 ->setAttribute('class', 'form-control');
214
215 $form->addSubmit('saving', 'Zařadit')
216 ->setAttribute('class', 'btn btn-primary');
217
218 $form->onSuccess[] = $this->addRoleSubmitted;
219
220 return $form;
221 }
222
223 public function addRoleSubmitted($form) {
224 try {
225 $iduser = $this->getParameter('id');
226 $role = $form->getValues();
227 $roles = $this->roleRepository->findPairRoleById($iduser);
228
229
230 if($role->role_code == 'consultant') {
231 if ($roles == FALSE) {
232 $this->userRepository->assignRole($role->role_code, $iduser);
233 $this->flashMessage('NEZAPOMEŇ. Uživateli s rolí Konzultant musí být přiřazena odborná oblast.', 'info');
234 }
235 else {
236 $this->flashMessage('Role Konzultant není slučitelná s žádnou jinou uživatelskou rolí. Musí být přidělena jako samostatná.', 'danger');
237 $this->redirect('this');
238 }
239 }
240 else {
241 $roleConsultant = FALSE;
242 foreach ($roles as $key => $value) {
243 if ($key == 'consultant') {
244 $roleConsultant = TRUE;
245 }
246 }
247 if(!$roleConsultant) {
248 $this->userRepository->assignRole($role->role_code, $iduser);
249 }
250 else {
251 $this->flashMessage('Role Konzultant není slučitelná s žádnou jinou uživatelskou rolí. Musí být přidělena jako samostatná.', 'danger');
252 $this->redirect('this');
253 }
254 }
255
256
257 if($role->role_code == 'chief') {
258 $this->userRepository->updateById($iduser, array('ischief' => 1));
259 }
260
261 } catch (\PDOException $e) {
262 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
263 }
264 }
265
266 267 268 269 270
271 public function createComponentRemoveRole() {
272
273 $form = new UI\Form();
274 $form->setRenderer(new BootstrapRenderer());
275 $iduser = $this->getParameter('id');
276
277 $form->getElementPrototype()->class = 'form-horizontal';
278 $form->addSelect('role_code', 'Role:', $this->roleRepository->findPairRoleById($iduser))
279 ->setAttribute('class', 'form-control');
280
281 $form->addSubmit('delete', 'Odebrat')
282 ->setAttribute('class', 'btn btn-primary');
283
284 $form->onSuccess[] = $this->removeRoleSubmitted;
285
286 return $form;
287 }
288
289 public function removeRoleSubmitted($form) {
290 try {
291 $iduser = $this->getParameter('id');
292 $role = $form->getValues();
293
294 $this->userRepository->removeAssignedRole($role->role_code, $iduser);
295 if($role->role_code == 'chief') {
296 $this->userRepository->updateById($iduser, array('ischief' => 0));
297 $this->userRepository->removeDepartment($iduser);
298 }
299 if($role->role_code == 'consultant' || $role->role_code == 'expert') {
300 $this->userRepository->removeAllAssignedArea($iduser);
301 }
302
303 } catch (\PDOException $e) {
304 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
305 }
306 }
307
308
309 310 311 312 313
314 public function createComponentAssignDepartment() {
315
316 $form = new UI\Form();
317 $form->setRenderer(new BootstrapRenderer());
318
319 $form->getElementPrototype()->class = 'form-horizontal';
320 $form->addSelect('department_id', 'Oddělení/Primariát:', $this->departmentRepository->getPairData())
321 ->setAttribute('class', 'form-control');
322
323 $form->addSubmit('saving', 'Zařadit')
324 ->setAttribute('class', 'btn btn-primary');
325
326 $form->onSuccess[] = $this->assignDepartmentSubmitted;
327
328 return $form;
329 }
330
331 public function assignDepartmentSubmitted($form) {
332 try {
333 $iduser = $this->getParameter('id');
334 $department = $form->getValues();
335
336 $this->userRepository->assignDepartment($department->department_id, $iduser);
337
338 } catch (\PDOException $e) {
339 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
340 }
341 }
342
343
344 345 346 347 348
349 protected function createSetup() {
350
351 $form = new UI\Form();
352 $form->setRenderer(new BootstrapRenderer());
353
354 $form->getElementPrototype()->class = 'form-horizontal';
355 $form->addPassword('password', 'Nové heslo:')
356 ->setRequired('Zadejte nové heslo')
357 ->addRule(UI\Form::MAX_LENGTH, 'Maximální délka hesla je %d znaků.', 50)
358 ->setAttribute('class', 'form-control');
359 $form->addPassword('passwordVerify', 'Potvrzení nového hesla:')
360 ->setRequired('Opakujte nové heslo')
361 ->addRule(UI\Form::EQUAL, 'Hesla se neshodují', $form['password'])
362 ->addRule(UI\Form::MAX_LENGTH, 'Maximální délka hesla je %d znaků.', 50)
363 ->setAttribute('class', 'form-control');
364
365 return $form;
366 }
367
368 369 370 371 372
373 protected function createComponentSetup() {
374
375 $form = $this->createSetup();
376 $form->addSubmit('saving', 'Odeslat')
377 ->setAttribute('class', 'btn btn-primary');
378
379 $form->onSuccess[] = $this->setupSubmitted;
380
381 return $form;
382
383 }
384
385
386 public function setupSubmitted($form) {
387 try {
388 $data = $form->getValues();
389 $iduser = $this->getUser()->getId();
390 $password = $data->password;
391 $rpassword = $data->passwordVerify;
392
393
394 $this->userRepository->setPassword($iduser, $password);
395 $this->flashMessage('Heslo bylo úspěšně změněno.', 'success');
396 $this->redirect('Homepage:default');
397
398 } catch (\PDOException $e) {
399 $this->flashMessage('Chyba při uložení do DB.', 'error');
400 $this->redirect('Homepage:default');
401 }
402 }
403
404 405 406 407 408 409
410 public function createComponentMail() {
411 $form = new UI\Form();
412 $form->setRenderer(new BootstrapRenderer());
413
414 $form->getElementPrototype()->class = 'form-horizontal';
415 $form->addText('email', 'Email:')
416 ->setRequired('Zadejte emailovou adresu')
417 ->addRule(UI\Form::EMAIL, 'Musí být zadána platná emailová adresa')
418 ->addRule(UI\Form::MAX_LENGTH, 'Adresa nesmí přesáhnout %d znaků', 100)
419 ->setAttribute('class', 'form-control');
420 $form->addSubmit('saving', 'Uložit')
421 ->setAttribute('class', 'btn btn-primary');
422
423 $form->onSuccess[] = $this->mailSubmitted;
424
425 return $form;
426
427 }
428
429 public function mailSubmitted($form) {
430 try{
431 $data = $form->getValues();
432 $iduser = $this->getUser()->getId();
433 $email = $data->email;
434
435 $this->userRepository->setEmail($iduser, $email);
436 $this->flashMessage('Emailová adresa byla úspěšně změněna.', 'success');
437 $this->redirect('Homepage:default');
438 }
439 catch (\PDOException $e){
440 $this->flashMessage('Chyba při uložení do DB.', 'error');
441 $this->redirect('Homepage:default');
442 }
443
444
445 }
446
447 protected function createComponentNewUserForm() {
448
449 $user = $this->getUser();
450 $form = new UI\Form();
451 $form->setRenderer(new BootstrapRenderer());
452
453 $form->getElementPrototype()->class = 'form-horizontal';
454
455 $form->addText('username', 'Uživatelské jméno:')
456 ->setRequired('Zadejte login')
457 ->setAttribute('class', 'form-control');
458
459 $form->addText('firstname', 'Jméno:')
460 ->setRequired('Zadejte jméno')
461 ->setAttribute('class', 'form-control');
462
463 $form->addText('lastname', 'Příjmení:')
464 ->setRequired('Zadejte příjmení')
465 ->setAttribute('class', 'form-control');
466
467 $form->addText('email', 'Email:')
468 ->addRule(UI\Form::EMAIL, 'Hodnota musí být emailová adresa')
469 ->setAttribute('class', 'form-control');
470
471 $form->addSelect('roles', 'Role:', $this->roleRepository->getPairData())
472 ->setPrompt('Vyberte roli ...')
473 ->setRequired()
474 ->setAttribute('class', 'form-control2');
475
476 $form->addRadioList('isunit', 'Oddělení', array('1' => 'ano', '0' => 'ne'))
477 ->setDefaultValue('1')
478 ->getSeparatorPrototype()->setName(NULL);
479
480 $form->addRadioList('ischief', 'Vedoucí', array('1' => 'ano', '0' => 'ne'))
481 ->setDefaultValue('0')
482 ->getSeparatorPrototype()->setName(NULL);
483
484 $form->addPassword('password', 'Heslo')
485 ->setAttribute('class', 'form-control')
486 ->setOption('description', Html::el('div')->add(Html::el('p class=text-muted')->setHtml('<small><i>Vyplňuje se jen pokud je uživatel typ Oddělení</i></small>')) )
487 ->addConditionOn($form['isunit'], UI\Form::EQUAL, 1)
488 ->setRequired('Pokud je uživatel typ Oddělení, pak je nutné zadat heslo ručně.');
489
490
491
492
493
494 $form->addSubmit('saving', 'Uložit')
495 ->setAttribute('class', 'btn btn-primary');
496
497 $form->addSubmit('back')
498 ->setAttribute('class', 'btn btn-default')
499 ->getControlPrototype()
500 ->setName('a')
501 ->href($this->link('User:default'))
502 ->add(Html::el('i')->class('fa fa-reply'))
503 ->add(Html::el('span', ' Zpět'));
504
505 $form->onSuccess[] = $this->newUserSubmitted;
506
507 return $form;
508 }
509
510 public function newUserSubmitted($form) {
511
512 try {
513 $fdata = $form->getValues();
514
515 $pswd = $fdata->isunit == 1 ? $fdata->password : bin2hex(openssl_random_pseudo_bytes(32));
516
517 $data = new \Nette\Utils\ArrayHash();
518 $data->username = $fdata->username;
519 $data->firstname = $fdata->firstname;
520 $data->lastname = $fdata->lastname;
521 $data->email = $fdata->email;
522 $data->isunit = $fdata->isunit;
523 $data->ischief = $fdata->ischief;
524 $data->password = Repositories\Security\UserManager::calculateHash($pswd);
525
526 $newuser = $this->userRepository->insertData($data);
527
528
529 $iduser = $newuser->id;
530 $this->userRepository->assignRole($fdata->roles, $iduser);
531
532 $text = $fdata->isunit == 1 ? '.' : ' s pseudonáhodně vygenerovaným heslem. Uživatel si musí vyžádat heslo pomocí odkazu Zapomenuté heslo? na přihlašovací obrazovce.';
533 $this->flashMessage('Uživatel byl vytvořen'.$text, 'success');
534 $this->redirect('User:view',$iduser);
535
536
537 } catch (\PDOException $e) {
538 $this->flashMessage("Chyba při uložení do DB. ".$e->getMessage(), 'error');
539 $this->redirect('User:create');
540 }
541 }
542
543
544 545 546 547 548
549 protected function createComponentForgotPassword() {
550
551 $user = $this->getUser();
552 $form = new UI\Form();
553 $form->setRenderer(new BootstrapRenderer());
554
555 $form->getElementPrototype()->class = 'form-horizontal';
556
557 $form->addText('email', 'Email:')
558 ->setRequired()
559 ->addRule(UI\Form::EMAIL, 'Musí být zadaná platná emailová adresa')
560 ->addRule(UI\Form::MAX_LENGTH, 'Adresa nesmí přesáhnout %d znaků', 100)
561 ->addRule(UI\Form::NOT_EQUAL, Html::el('div')->setHtml("Pro účet k emailové adrese <strong> blackhole@nemocnice-vs.cz </strong> nelze měnit heslo. Kontaktujte administrátora systému."),'blackhole@nemocnice-vs.cz')
562 ->setAttribute('class', 'form-control');
563 $form->addSubmit('passwdReset', 'Resetovat heslo')
564 ->setAttribute('class', 'btn btn-lg btn-primary btn-block');
565
566 $form->onSuccess[] = array($this, 'forgotPasswordSubmitted');
567
568 return $form;
569 }
570
571
572 public function forgotPasswordSubmitted($form, $values) {
573 try {
574
575 $expires = new \Nette\Utils\DateTime();
576 $expires->add(new \DateInterval('PT01H'));
577 $token = bin2hex(openssl_random_pseudo_bytes(32));
578 $userForgot = $this->userRepository->findUserByEmail($values->email);
579 $userCountForgot = $this->userRepository->getCountUserByEmail($values->email);
580
581 if(!isset($userForgot->id)) {
582 $form->addError(Html::el('div') ->setHtml("Pro účet k emailové adrese <strong> $values->email </strong> nelze měnit heslo. Kontaktujte administrátora systému."));
583 }
584 elseif(isset($userCountForgot->cnt) && $userCountForgot->cnt > 1) {
585 $form->addError(Html::el('div') ->setHtml("Pro účet k emailové adrese <strong> $values->email </strong> nelze měnit heslo. Účet není jednoznačný."));
586 }
587 else {
588 $this->userRepository->updateById($userForgot->id, array('token' => $token, 'expires' => $expires));
589
590
591 $uri = $this->getHttpRequest()->getUrl();
592 $from = $this->parameters->getFrom();
593 $support = $this->parameters->getSupport();
594 $to = array($userForgot->id => $values->email);
595 $subject = 'Obnova zapomenutého hesla';
596 $params = array(
597 'email' => $values->email,
598 'username' => $userForgot->username,
599 'contact' => $support,
600 'url' => $uri->hostUrl.'/user&execution=reset?token='.$token,
601 'reset' => $uri->hostUrl.'/user&execution=forgot'
602 );
603 $template = __DIR__ . '/../templates/Mailer/forgotPassword.latte';
604 $image = __DIR__ . '/../../www/img/logo32x32.gif';
605 $mailer = $this->mailerCfg->getMailConfig();
606
607 MailerPresenter::sendMail($from, $to, $subject, $params, $template, $image, $mailer);
608
609
610 $this->flashMessage(Html::el('div')
611 ->setHtml("Na emailovou adresu <strong> $values->email </strong> byl zaslán odkaz pro výměnu hesla."), 'success');
612
613 $this->redirect('Sign:in');
614 }
615
616
617 } catch (\PDOException $ex) {
618 $this->flashMessage("Chyba. Kontaktujte administrátora systému. ".$ex->getMessage(), 'error');
619 $this->redirect('Sign:in');
620 }
621
622 }
623
624 625 626 627 628 629
630 protected function createComponentResetPassword() {
631
632 $form = $this->createSetup();
633 $form->addHidden('token', $this->getParam('token'));
634 $form->addSubmit('saving', 'Odeslat')
635 ->setAttribute('class', 'btn btn-lg btn-primary btn-block');
636
637 $form->onSuccess[] = array($this, 'resetPasswordSubmitted');
638
639 return $form;
640 }
641
642 public function resetPasswordSubmitted($form, $values) {
643 try {
644
645 $userReset = $this->userRepository->getUserByToken($values->token);
646 $dt = new \Nette\Utils\DateTime();
647
648 if(!isset($userReset->id)) {
649 $this->flashMessage('Účet vázaný k požadavku na změnu hesla nebyl dohledán. Vytvořte nový požadavek.', 'danger');
650 }
651 elseif($dt > $userReset->expires) {
652 $this->flashMessage('Požadavek na změnu hesla již expiroval. Vytvořte nový požadavek.','danger');
653 }
654 else {
655 $this->userRepository->setPassword($userReset->id, $values->password);
656 $this->flashMessage('Heslo bylo úspěšně změněno. Přihlašte se prosím novým heslem.', 'success');
657 }
658
659 $this->redirect('Sign:in');
660
661 } catch (\PDOException $ex) {
662 $this->flashMessage("Chyba. Kontaktujte administrátora systému. ".$e->getMessage(), 'error');
663 $this->redirect('Sign:in');
664 }
665
666 }
667
668 669 670 671 672 673
674 protected function checkLogin() {
675
676 if ($this->getAction()=== 'forgot' || $this->getAction()=== 'reset') {
677 return;
678 }
679
680 parent::checkLogin();
681 }
682
683 }