Skip to content

Commit b850524

Browse files
committed
- Replaced closures with factories for [performance](per #3 in top answer at http://stackoverflow.com/questions/14667621/zf2-optimize-for-high-traffic)
- CreateForm and EditForm add hydrator (per ZfcUser settings) in `__construct`. This makes it available to extend during the form `init` event. - Converted EditForm to inherit directly from Base rather than indirectly through Register (requires ZfcUser PR) - Converted EditForm to store data using `$form->bind($object)` pattern often used in Zend Forms (requires ZfcUser PR to avoid sending password to browser) - Forms now use an enhanced Validation Group logic. Elements are selectively excluded based on specific options or attributes. This significantly improves extensibility. - Cleaned out old helper code - Now repopulates disabled fields (side-effect)
1 parent 16bd258 commit b850524

File tree

9 files changed

+257
-173
lines changed

9 files changed

+257
-173
lines changed

config/services.config.php

Lines changed: 6 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,16 @@
44
* Date: 3/18/13
55
* Time: 6:39 PM
66
*/
7-
use Zend\ServiceManager\ServiceLocatorInterface;
8-
use ZfcUser\Form\RegisterFilter;
9-
use ZfcUser\Mapper\UserHydrator;
10-
use ZfcUser\Validator\NoRecordExists;
11-
use ZfcUserAdmin\Form;
12-
use ZfcUserAdmin\Options;
13-
use ZfcUserAdmin\Validator\NoRecordExistsEdit;
147

158
return array(
169
'invokables' => array(
17-
'ZfcUserAdmin\Form\EditUser' => 'ZfcUserAdmin\Form\EditUser',
18-
'zfcuseradmin_user_service' => 'ZfcUserAdmin\Service\User',
10+
'ZfcUserAdmin\Form\EditUser' => 'ZfcUserAdmin\Form\EditUser',
11+
'zfcuseradmin_user_service' => 'ZfcUserAdmin\Service\User',
1912
),
2013
'factories' => array(
21-
'zfcuseradmin_module_options' => function (ServiceLocatorInterface $sm) {
22-
$config = $sm->get('Config');
23-
return new Options\ModuleOptions(isset($config['zfcuseradmin']) ? $config['zfcuseradmin'] : array());
24-
},
25-
'zfcuseradmin_edituser_form' => function (ServiceLocatorInterface $sm) {
26-
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
27-
$zfcUserOptions = $sm->get('zfcuser_module_options');
28-
/** @var $zfcUserAdminOptions \ZfcUserAdmin\Options\ModuleOptions */
29-
$zfcUserAdminOptions = $sm->get('zfcuseradmin_module_options');
30-
$form = new Form\EditUser(null, $zfcUserAdminOptions, $zfcUserOptions, $sm);
31-
$filter = new RegisterFilter(
32-
new NoRecordExistsEdit(array(
33-
'mapper' => $sm->get('zfcuser_user_mapper'),
34-
'key' => 'email'
35-
)),
36-
new NoRecordExistsEdit(array(
37-
'mapper' => $sm->get('zfcuser_user_mapper'),
38-
'key' => 'username'
39-
)),
40-
$zfcUserOptions
41-
);
42-
if (!$zfcUserAdminOptions->getAllowPasswordChange()) {
43-
$filter->remove('password')->remove('passwordVerify');
44-
} else {
45-
$filter->get('password')->setRequired(false);
46-
$filter->remove('passwordVerify');
47-
}
48-
$form->setInputFilter($filter);
49-
return $form;
50-
},
51-
'zfcuseradmin_createuser_form' => function (ServiceLocatorInterface $sm) {
52-
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
53-
$zfcUserOptions = $sm->get('zfcuser_module_options');
54-
/** @var $zfcUserAdminOptions \ZfcUserAdmin\Options\ModuleOptions */
55-
$zfcUserAdminOptions = $sm->get('zfcuseradmin_module_options');
56-
$form = new Form\CreateUser(null, $zfcUserAdminOptions, $zfcUserOptions, $sm);
57-
$filter = new RegisterFilter(
58-
new NoRecordExists(array(
59-
'mapper' => $sm->get('zfcuser_user_mapper'),
60-
'key' => 'email'
61-
)),
62-
new NoRecordExists(array(
63-
'mapper' => $sm->get('zfcuser_user_mapper'),
64-
'key' => 'username'
65-
)),
66-
$zfcUserOptions
67-
);
68-
if ($zfcUserAdminOptions->getCreateUserAutoPassword()) {
69-
$filter->remove('password')->remove('passwordVerify');
70-
}
71-
$form->setInputFilter($filter);
72-
return $form;
73-
},
74-
'zfcuser_user_mapper' => function (ServiceLocatorInterface $sm) {
75-
/** @var $config \ZfcUserAdmin\Options\ModuleOptions */
76-
$config = $sm->get('zfcuseradmin_module_options');
77-
$mapperClass = $config->getUserMapper();
78-
if (stripos($mapperClass, 'doctrine') !== false) {
79-
$mapper = new $mapperClass(
80-
$sm->get('zfcuser_doctrine_em'),
81-
$sm->get('zfcuser_module_options')
82-
);
83-
} else {
84-
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
85-
$zfcUserOptions = $sm->get('zfcuser_module_options');
86-
87-
/** @var $mapper \ZfcUserAdmin\Mapper\UserZendDb */
88-
$mapper = new $mapperClass();
89-
$mapper->setDbAdapter($sm->get('zfcuser_zend_db_adapter'));
90-
$entityClass = $zfcUserOptions->getUserEntityClass();
91-
$mapper->setEntityPrototype(new $entityClass);
92-
$mapper->setHydrator($sm->get('zfcuser_user_hydrator'));
93-
$mapper->setTableName($zfcUserOptions->getTableName());
94-
}
95-
96-
return $mapper;
97-
},
14+
'zfcuseradmin_module_options' => 'ZfcUserAdmin\Factory\Options\ModuleOptionsFactory',
15+
'zfcuser_user_mapper' => 'ZfcUserAdmin\Factory\Mapper\UserZendDbFactory',
16+
'zfcuseradmin_createuser_form' => 'ZfcUserAdmin\Factory\Form\CreateUserFactory',
17+
'zfcuseradmin_edituser_form' => 'ZfcUserAdmin\Factory\Form\EditUserFactory',
9818
),
9919
);

src/ZfcUserAdmin/Controller/UserAdminController.php

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ public function createAction()
4040
{
4141
/** @var $form \ZfcUserAdmin\Form\CreateUser */
4242
$form = $this->getServiceLocator()->get('zfcuseradmin_createuser_form');
43+
/** @var $request \Zend\Http\Request */
4344
$request = $this->getRequest();
4445

45-
/** @var $request \Zend\Http\Request */
4646
if ($request->isPost()) {
4747
$zfcUserOptions = $this->getZfcUserOptions();
4848
$class = $zfcUserOptions->getUserEntityClass();
4949
$user = new $class();
50-
$form->setHydrator(new ClassMethods());
5150
$form->bind($user);
51+
5252
$form->setData($request->getPost());
5353

5454
if ($form->isValid()) {
55-
$user = $this->getAdminUserService()->create($form, (array)$request->getPost());
55+
$user = $this->getAdminUserService()->create($form, (array)$request->getPost(), $user);
5656
if ($user) {
5757
$this->flashMessenger()->addSuccessMessage('The user was created');
5858
return $this->redirect()->toRoute('zfcadmin/zfcuseradmin/list');
@@ -67,15 +67,17 @@ public function createAction()
6767

6868
public function editAction()
6969
{
70-
$userId = $this->getEvent()->getRouteMatch()->getParam('userId');
71-
$user = $this->getUserMapper()->findById($userId);
72-
7370
/** @var $form \ZfcUserAdmin\Form\EditUser */
7471
$form = $this->getServiceLocator()->get('zfcuseradmin_edituser_form');
75-
$form->setUser($user);
76-
7772
/** @var $request \Zend\Http\Request */
7873
$request = $this->getRequest();
74+
75+
$userId = $this->getEvent()->getRouteMatch()->getParam('userId');
76+
$user = $this->getUserMapper()->findById($userId);
77+
$form->bind($user);
78+
79+
// don't automatically overwrite password since input permit blank
80+
$form->getInputFilter()->remove('password');
7981
if ($request->isPost()) {
8082
$form->setData($request->getPost());
8183
if ($form->isValid()) {
@@ -85,9 +87,10 @@ public function editAction()
8587
return $this->redirect()->toRoute('zfcadmin/zfcuseradmin/list');
8688
}
8789
}
88-
} else {
89-
$form->populateFromUser($user);
9090
}
91+
// Necessary so validators know whether a username and email have changed since they may be a "duplicate" of
92+
// their own database record, but not of other users.
93+
$form->get('userId')->setValue($user->getId());
9194

9295
return array(
9396
'editUserForm' => $form,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Clayton Daley
5+
* Date: 1/31/2015
6+
* Time: 1:06 PM
7+
*/
8+
9+
namespace ZfcUserAdmin\Factory\Form;
10+
11+
use Zend\ServiceManager\FactoryInterface;
12+
use Zend\ServiceManager\ServiceLocatorInterface;
13+
use ZfcUser\Form\RegisterFilter;
14+
use ZfcUser\Validator\NoRecordExists;
15+
use ZfcUserAdmin\Form\CreateUser;
16+
17+
class CreateUserFactory implements FactoryInterface {
18+
19+
function createService(ServiceLocatorInterface $serviceLocator) {
20+
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
21+
$zfcUserOptions = $serviceLocator->get('zfcuser_module_options');
22+
/** @var $zfcUserAdminOptions \ZfcUserAdmin\Options\ModuleOptions */
23+
$zfcUserAdminOptions = $serviceLocator->get('zfcuseradmin_module_options');
24+
$form = new CreateUser(null, $zfcUserAdminOptions, $zfcUserOptions, $serviceLocator);
25+
$filter = new RegisterFilter(
26+
new NoRecordExists(array(
27+
'mapper' => $serviceLocator->get('zfcuser_user_mapper'),
28+
'key' => 'email'
29+
)),
30+
new NoRecordExists(array(
31+
'mapper' => $serviceLocator->get('zfcuser_user_mapper'),
32+
'key' => 'username'
33+
)),
34+
$zfcUserOptions
35+
);
36+
if ($zfcUserAdminOptions->getCreateUserAutoPassword()) {
37+
$filter->remove('password')->remove('passwordVerify');
38+
}
39+
$form->setInputFilter($filter);
40+
return $form;
41+
}
42+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Clayton Daley
5+
* Date: 1/31/2015
6+
* Time: 1:03 PM
7+
*/
8+
9+
namespace ZfcUserAdmin\Factory\Form;
10+
11+
use Zend\ServiceManager\FactoryInterface;
12+
use Zend\ServiceManager\ServiceLocatorInterface;
13+
use ZfcUser\Form\RegisterFilter;
14+
use ZfcUserAdmin\Form\EditUser;
15+
use ZfcUserAdmin\Validator\NoRecordExistsEdit;
16+
17+
class EditUserFactory implements FactoryInterface {
18+
19+
public function createService(ServiceLocatorInterface $serviceLocator) {
20+
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
21+
$zfcUserOptions = $serviceLocator->get('zfcuser_module_options');
22+
/** @var $zfcUserAdminOptions \ZfcUserAdmin\Options\ModuleOptions */
23+
$zfcUserAdminOptions = $serviceLocator->get('zfcuseradmin_module_options');
24+
$form = new EditUser(null, $zfcUserAdminOptions, $zfcUserOptions, $serviceLocator);
25+
$filter = new RegisterFilter(
26+
new NoRecordExistsEdit(array(
27+
'mapper' => $serviceLocator->get('zfcuser_user_mapper'),
28+
'key' => 'email'
29+
)),
30+
new NoRecordExistsEdit(array(
31+
'mapper' => $serviceLocator->get('zfcuser_user_mapper'),
32+
'key' => 'username'
33+
)),
34+
$zfcUserOptions
35+
);
36+
if (!$zfcUserAdminOptions->getAllowPasswordChange()) {
37+
$filter->remove('password')->remove('passwordVerify');
38+
} else {
39+
$filter->get('password')->setRequired(false);
40+
$filter->remove('passwordVerify');
41+
}
42+
$form->setInputFilter($filter);
43+
return $form;
44+
}
45+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Clayton Daley
5+
* Date: 1/31/2015
6+
* Time: 1:09 PM
7+
*/
8+
9+
namespace ZfcUserAdmin\Factory\Mapper;
10+
11+
use Zend\ServiceManager\FactoryInterface;
12+
use Zend\ServiceManager\ServiceLocatorInterface;
13+
14+
class UserZendDbFactory implements FactoryInterface {
15+
16+
public function createService(ServiceLocatorInterface $serviceLocator) {
17+
/** @var $config \ZfcUserAdmin\Options\ModuleOptions */
18+
$config = $serviceLocator->get('zfcuseradmin_module_options');
19+
$mapperClass = $config->getUserMapper();
20+
if (stripos($mapperClass, 'doctrine') !== false) {
21+
$mapper = new $mapperClass(
22+
$serviceLocator->get('zfcuser_doctrine_em'),
23+
$serviceLocator->get('zfcuser_module_options')
24+
);
25+
} else {
26+
/** @var $zfcUserOptions \ZfcUser\Options\UserServiceOptionsInterface */
27+
$zfcUserOptions = $serviceLocator->get('zfcuser_module_options');
28+
29+
/** @var $mapper \ZfcUserAdmin\Mapper\UserZendDb */
30+
$mapper = new $mapperClass();
31+
$mapper->setDbAdapter($serviceLocator->get('zfcuser_zend_db_adapter'));
32+
$entityClass = $zfcUserOptions->getUserEntityClass();
33+
$mapper->setEntityPrototype(new $entityClass);
34+
$mapper->setHydrator($serviceLocator->get('zfcuser_user_hydrator'));
35+
$mapper->setTableName($zfcUserOptions->getTableName());
36+
}
37+
38+
return $mapper;
39+
}
40+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Clayton Daley
5+
* Date: 1/31/2015
6+
* Time: 1:13 PM
7+
*/
8+
9+
namespace ZfcUserAdmin\Factory\Options;
10+
11+
use Zend\ServiceManager\FactoryInterface;
12+
use Zend\ServiceManager\ServiceLocatorInterface;
13+
use ZfcUserAdmin\Options\ModuleOptions;
14+
15+
class ModuleOptionsFactory implements FactoryInterface {
16+
17+
public function createService(ServiceLocatorInterface $serviceLocator) {
18+
$config = $serviceLocator->get('Config');
19+
return new ModuleOptions(isset($config['zfcuseradmin']) ? $config['zfcuseradmin'] : array());
20+
}
21+
}

src/ZfcUserAdmin/Form/CreateUser.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace ZfcUserAdmin\Form;
44

5-
use ZfcUserAdmin\Options\UserCreateOptionsInterface;
5+
use Zend\Stdlib\Hydrator\ClassMethods;
66
use ZfcUser\Options\RegistrationOptionsInterface;
77
use ZfcUser\Form\Register as Register;
8+
use ZfcUserAdmin\Options\UserCreateOptionsInterface;
89

910
class CreateUser extends Register
1011
{
@@ -24,6 +25,8 @@ public function __construct($name = null, UserCreateOptionsInterface $createOpti
2425
$this->setCreateOptions($createOptions);
2526
$this->setServiceManager($serviceManager);
2627
parent::__construct($name, $registerOptions);
28+
// ZfcUser should have setHydrator() which we replace or extend
29+
$this->setHydrator($serviceManager->get('zfcuser_user_hydrator'));
2730

2831
if ($createOptions->getCreateUserAutoPassword()) {
2932
$this->remove('password');
@@ -68,4 +71,34 @@ public function getServiceManager()
6871
{
6972
return $this->serviceManager;
7073
}
74+
75+
/**
76+
* Override isValid() to set an validation group of all elements that do not
77+
* have an 'exclude' option, if at least one element has this option set.
78+
*
79+
* @return boolean
80+
*/
81+
public function isValid()
82+
{
83+
if ($this->hasValidated) {
84+
return $this->isValid;
85+
}
86+
87+
if ($this->getValidationGroup() === null) {
88+
// Add all non-excluded elements to the validation group
89+
$validationGroup = null;
90+
foreach ($this->getElements() as $element) {
91+
if ($element->getOption('exclude') === false or
92+
($element->getAttribute('readonly') !== true && $element->getOption('exclude') !== true))
93+
{
94+
$validationGroup[] = $element->getName();
95+
}
96+
}
97+
if ($validationGroup) {
98+
$this->setValidationGroup($validationGroup);
99+
}
100+
}
101+
102+
return parent::isValid();
103+
}
71104
}

0 commit comments

Comments
 (0)