I'm following this book, and I'm in chapter 3 and this code is returning me the following error: Fatal error: Class 'Users\Model\User' not found in /var/www/CommunicationApp/module/Users/src/Users/Controller/RegisterController.php on line 70
I want to know what is wrong with the code, or if it's not the code than what is it?
<?php
namespace Users\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Users\Form\RegisterForm;
use Users\Form\RegisterFilter;
use Users\Model\User;
use Users\Model\UserTable;
class RegisterController extends AbstractActionController
{
public function indexAction()
{
$form = new RegisterForm();
$viewModel = new ViewModel(array('form' => $form));
return $viewModel;
}
public function processAction()
{
if (!$this->request->isPost()) {
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'index'
));
}
$post = $this->request->getPost();
$form = new RegisterForm();
$inputFilter = new RegisterFilter();
$form->setInputFilter($inputFilter);
$form->setData($post);
if (!$form->isValid()) {
$model = new ViewModel(array(
'error' => true,
'form' => $form,
));
$model->setTemplate('users/register/index');
return $model;
}
// Create user
$this->createUser($form->getData());
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'confirm'
));
}
public function confirmAction()
{
$viewModel = new ViewModel();
return $viewModel;
}
protected function createUser(array $data)
{
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype (new \Users\Model\User); //line 70
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user' /* table name */, $dbAdapter, null, $resultSetPrototype);
$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
return true;
}
}
for a correct autoloading check if the model file is in the following directory
/module/Users/src/Users/Model/User.php
if is not zend can't autoload your model file and that triggers your error if (as you pointed out your classname and namespace in the model file is correct) the file is not placed there.
Related
How to configure module.php?
I am trying to fetch data from two tables with in 2 different views using different controllers.
Below is my code that shows you what I am doing in my module, business controller and registration controller.
Module.php
public function getServiceConfig(){
return array(
'factories' => array(
// Instantiating StudentTable class by injecting TableGateway
'TaskForce\Model\RegistrationTable'=>function($sm){
$registerationGateway = $sm->get('RegistrationTableGateway');
$table = new RegistrationTable($registerationGateway);
return $table;
},
//Instantiating TableGateway to inject to StudentTable class
'RegistrationTableGateway'=>function($sm){
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Registration());
return new TableGateway('users', $dbAdapter,null,$resultSetPrototype);
},
'TaskForce\Model\BusinessTable'=>function($sm){
$businessGateway = $sm->get('BusinessTableGateway');
$businesstable = new BusinessTable($businessGateway);
return $businesstable;
},
//Instantiating TableGateway to inject to StudentTable class
'BusinessTableGateway'=>function($sm){
$dbAdapter2 = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype2 = new ResultSet();
$resultSetPrototype2->setArrayObjectPrototype(new Business());
return new TableGateway('business', $dbAdapter2,null,$resultSetPrototype2);
},
)
);
}
BusinessController.php
public function indexAction(){
// Setting layout for this action
$this->layout("layout/main_layout");
return new ViewModel(array(
// Fetching data from database
'business'=>$this->getBusinessTable()->fetchAll()
));
}
and RegistrationController.php
public function indexAction(){
// Setting layout for this action
$this->layout("layout/main_layout");
$form = new RegistrationForm();
$request = $this->getRequest();
if ($request->isPost()) {
$registration = new Registration();
//$form->get('submit')->setAttribute('value', 'Add New User');
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$registration->exchangeArray($form->getData());
$this->getRegistrationTable()->saveRegistration($registration);
// Redirect to list of users
return $this->redirect()->toRoute('registration');
}
}
return new ViewModel(array(
'form' => $form
));
}
If there is a relationship between the Business and the Registration records, you may wish to clarify it. However, if it is simply a matter of code arrangement, you can do this:
BusinessController.php
public function indexAction(){
// Setting layout for this action
$this->layout("layout/main_layout");
return new ViewModel(array(
// Fetching data from database
'business'=>$this->getBusinessTable()->fetchAll(),
'registration' => $this->getRegistrationTable()->fetchAll(),
));
}
RegistrationController.php
public function indexAction(){
// Setting layout for this action
$this->layout("layout/main_layout");
return new ViewModel(array(
// Fetching data from database
'business'=>$this->getBusinessTable()->fetchAll(),
'registration' => $this->getRegistrationTable()->fetchAll(),
));
}
// rename your index action in registrationcontroller.php to form
// so that the form is displayed on the formAction
public function formAction(){
// Setting layout for this action
$this->layout("layout/main_layout");
$form = new RegistrationForm();
$request = $this->getRequest();
if ($request->isPost()) {
$registration = new Registration();
//$form->get('submit')->setAttribute('value', 'Add New User');
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$registration->exchangeArray($form->getData());
$this->getRegistrationTable()->saveRegistration($registration);
// Redirect to list of users
return $this->redirect()->toRoute('registration');
}
}
return new ViewModel(array(
'form' => $form
));
}
I am a beginner of Zend Framework2. Following the example of "Zend Framework 2.0 by Example Beginner's Guide" I got stuck in a weird problem.
Here is my project structure.
I have a simple function creatureUser() in RegisterController.php:
<?php
namespace Users\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Users\Form\RegisterForm;
use Users\Form\RegisterFilter;
use users\Model\User;
use Users\Model\UserTable;
class RegisterController extends AbstractActionController
{
public function indexAction()
{
//$form = new RegisterForm();
$form = $this->getServiceLocator()->get('RegisterForm');
$viewModel = new ViewModel(array('form' => $form));
return $viewModel;
}
public function confirmAction()
{
$viewModel = new ViewModel();
return $viewModel;
}
public function processAction()
{
if (!$this->request->isPost()) {
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'index'
));
}
$post = $this->request->getPost();
//$form = new RegisterForm();
//$inputFilter = new RegisterFilter();
//$form->setInputFilter($inputFilter);
$form = $this->getServiceLocator()->get('RegisterForm');
$form->setData($post);
if (!$form->isValid()) {
$model = new ViewModel(array(
'error' => true,
'form' => $form,
));
$model->setTemplate('users/register/index');
return $model;
}
// Create user
$this->createUser($form->getData());
return $this->redirect()->toRoute(NULL , array(
'controller' => 'register',
'action' => 'confirm'
));
}
protected function createUser(array $data)
{
$user = new User();
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user', $dbAdapter, null, $resultSetPrototype);
//$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
return true;
}
}
When run the above code I get an error:
Fatal error: Class 'users\Model\User' not found in C:\WebApp\ZF2Skeleton\module\Users\src\Users\Controller\RegisterController.php on line 90.
But If I move $user = new User(); below. Like this one:
protected function createUser(array $data)
{
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
$tableGateway = new \Zend\Db\TableGateway\TableGateway('user', $dbAdapter, null, $resultSetPrototype);
$user = new User();
$user->exchangeArray($data);
$userTable = new UserTable($tableGateway);
$userTable->saveUser($user);
return true;
}
It will work perfectly. Can anyone tell me how this happens, please? Is it a sequence problem? Thank you!
It's a simple typo in your controller:
use users\Model\User;
should be:
use Users\Model\User;
(note the capital 'U' in 'Users').
I'm new with the zend framework 2. I have to make a login system with the plugin authentication from zend framework. i found many solutions to do this, but mine is still not working.
i'm probably doing something wrong, but i don't see my problem.
Will someone please help me with this?
code of my form LoginForm.php:
<?php
namespace System\Form;
use Zend\Form\Form;
class Login extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$this->addElement(
'text', 'email', array(
'label' => 'Email:',
'required' => true,
'filters' => array('StringTrim'),
));
$this->addElement('password', 'password', array(
'label' => 'Password:',
'required' => true,
));
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Login',
));
}
}
Code InlogController.php :
<?php
namespace System\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use System\Form\Login;
class InlogController extends AbstractActionController
{
public function loginAction()
{
$db = $this->_getParam('fms');
$loginForm = new Login();
if ($loginForm->isValid($_POST)) {
$adapter = new Zend_Auth_Adapter_DbTable(
$db,
'user_name',
'user_email',
'user_password'
);
$adapter->setIdentity($loginForm->getValue('user_email'));
$adapter->setCredential($loginForm->getValue('user_password'));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if ($result->isValid()) {
$this->_helper->FlashMessenger('Successful Login');
$this->_redirect('/');
return;
}
}
$this->view->loginForm = $loginForm;
}
}
Code index.phtml :
<?php
$title = "Login to vote";
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$this->form->setAction($this->url());
echo $this->form;
This is the error
Fatal error: Call to a member function setAction() on a non-object in /mnt/hgfs/Sites/fms/module/System/view/system/inlog/index.phtml on line 10
Please try with this:
In Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
// some other service config setup,
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter,
'users','email','password', '?');
$authService = new AuthenticationService();
$authService->setAdapter($dbTableAuthAdapter);
$authService->setStorage($sm->get('Application\Model\MyAuthStorage')); // this is for session storage and optional for you
return $authService;
},
// some other service config setup
)
);
}
In Controller
public function getAuthService()
{
if (! $this->authservice) {
$this->authservice = $this->getServiceLocator()->get('AuthService');
}
return $this->authservice;
}
While Authenticating
public function authenticateAction()
{
// code to get Postdata from login FORM
$this->getAuthService()->getAdapter()
->setIdentity($postData['email'])
->setCredential($postData['password']);
$result = $this->getAuthService()->authenticate();
if ($result->isValid()) {
// successful logged in
}
}
EDIT
namespace Application\Model;
use Zend\Authentication\Storage;
class MyAuthStorage extends Storage\Session
{
/**
* Set remember me option
* save the details in session
*
* #param <Int> $rememberMe default = 0
*
* #return <Void>
*/
public function setRememberMe($rememberMe = 0, $time = 1209600)
{
if ($rememberMe == 1) {
$this->session->getManager()->rememberMe($time);
}
}
/**
* forget me
* clear the session storage value
*
* #param <Void>
*
* #return <Void>
*/
public function forgetMe()
{
$this->session->getManager()->forgetMe();
}
}
In Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
// some other service config setup,
'Application\Model\MyAuthStorage' => function($sm){
return new \Application\Model\MyAuthStorage('xyz');
},
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$dbTableAuthAdapter = new DbTableAuthAdapter($dbAdapter,
'users','email','password', '?');
$authService = new AuthenticationService();
$authService->setAdapter($dbTableAuthAdapter);
$authService->setStorage($sm->get('Application\Model\MyAuthStorage')); // this is for session storage and optional for you
return $authService;
},
// some other service config setup
)
);
}
I think this one will help you.
UPDATE (2nd update)
You need to include Zend_Auth_Adapter_DbTable like the below in Module.php file:
use Zend\Mvc\ModuleRouteListener, Zend\Mvc\MvcEvent, Application\Model\IndexTable,
Zend\Db\ResultSet\ResultSet, Zend\Db\TableGateway\TableGateway,
Zend\Authentication\AuthenticationService,
Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;
Change this:
$adapter->setIdentity($loginForm->getValue('user_email'));
$adapter->setCredential($loginForm->getValue('user_password'));
By this, You must use right names of form elements to get its value:
$adapter->setIdentity($loginForm->getValue('email'));
$adapter->setCredential($loginForm->getValue('password'));
And in the view file change the form var name just as you had defined in the controller:
$this->loginForm->setAction(...);
Please find my code below
module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'Shopping\Model\ShopTable' => function($sm) {
$tableGateway = $sm->get('ShopTableGateway');
$table = new ShopCategoriesTable($tableGateway);
return $table;
},
'ShopTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new ShopCategories());
return new TableGateway('shop_goods', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
shoppingcontroller.php
public function getShopTable()
{
if (!$this->shopTable)
{
$sm = $this->getServiceLocator();
$this->shopTable = $sm->get('Shopping\Model\ShopTable');
}
return $this->shopTable;
}
As you can see on my first code shop_categories is my database table from which iam fetching data ,above code works fine.But now i need to fetch data from an other table named as shop_goods how do i configure module.php?
Try this :
module.php
<?php
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\ShopgoodsTable' => function($sm) {
$tableGateway = $sm->get('ShopgoodsTableGateway');
$table = new ShopgoodsTable($tableGateway);
return $table;
},
'ShopgoodsTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Shopgoods());
return new TableGateway('shops_goods', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
And in your controller
public function getShopgoodsTable()
{
if (!$this->shopGoodsTable)
{
$sm = $this->getServiceLocator();
$this->shopGoodsTable= $sm->get('Shopping\Model\ShopgoodsTable');
}
return $this->shopGoodsTable;
}
Well you have to use modify your query, use JOIN for your sql query but this will be a problem as you mapper might not know other table values to be populated with results. So, you have two options.
1) Use join and Modify your mapper -- not a clean approach, i will say
2) Learn to use doctrine and it will handle such things. You are using TableGateway. It is good only if you are doing transaction per table per mapper. If you want to use one/one-many relationship scenario you might have to trick your code just like in point 1 which will lead in complications. So Doctrine is the solution
Here is an example of how I accomplished this. My module name is Application and the two tables I'm fetching data from are 'projects' and 'users'.
Module.php
namespace Application;
// Project db
use Application\Model\Project;
use Application\Model\ProjectTable;
// User db
use Application\Model\User;
use Application\Model\UserTable;
// db connection
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module {
public function onBootstrap(MvcEvent $e) {...}
public function getConfig() {...}
public function getAutoloaderConfig() {...}
public function getServiceConfig() {
return array(
'factories' => array(
'Application\Model\ProjectTable' => function($sm) {
$tableGateway = $sm->get('ProjectTableGateway');
$table = new ProjectTable($tableGateway);
return $table;
},
'ProjectTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Project());
return new TableGateway('projects', $dbAdapter, null, $resultSetPrototype);
},
/*** Add other table gateways here ***/
'Application\Model\UserTable' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new UserTable($tableGateway);
return $table;
},
'UserTableGateway' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new User());
return new TableGateway('users', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
}
in my controller...
public function indexAction() {
return new ViewModel(array(
'projects' => $this->getProjectTable()->fetchAll(),
'users' => $this->getUserTable()->fetchAll(),
));
}
So, in your shoppingcontroller.php file, as long as your controller class is extending AbstractActionController and you've included...
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
you should be able to return a ViewModel object that contains the data fetched from your separate database tables. Then you can use as you'd like in your view. For example, I loop through $projects and $users in my view to display the contents.
I'm having issues trying to unit test an action which uses ZfcUser for authentication. I need some way to mock the ZfcUser Controller plugin but I'm not so sure how to do this. I've managed to successfully produce some unit tests for tables and models but the controller requires a lot of injected objects and is causing problems. Does anyone know how to set up the ZfcUser mocks to successfully unit test a controller?
Here is my test (copied from the ZF2 tutorial):
<?php
namespace SmsTest\Controller;
use SmsTest\Bootstrap;
use Sms\Controller\SmsController;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter;
use PHPUnit_Framework_TestCase;
class SmsControllerTest extends PHPUnit_Framework_TestCase
{
protected $controller;
protected $request;
protected $response;
protected $routeMatch;
protected $event;
protected function setUp()
{
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new SmsController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array('controller' => 'index'));
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
}
/* Test all actions can be accessed */
public function testIndexActionCanBeAccessed()
{
$this->routeMatch->setParam('action', 'index');
$result = $this->controller->dispatch($this->request);
$response = $this->controller->getResponse();
$this->assertEquals(200, $response->getStatusCode());
}
}
I tried the following in the setUp method:
$mockAuth = $this->getMock('ZfcUser\Entity\UserInterface');
$authMock = $this->getMock('Zend\Authentication\AuthenticationService');
$authMock->expects($this->any())
->method('hasIdentity')
->will($this->returnValue(true));
$authMock->expects($this->any())
->method('getIdentity')
->will($this->returnValue(array('user_id' => 1)));
But I'm not sure how to inject this in to the controller instance.
Lets pretend my index action code is just as follows:
public function indexAction() {
//Check if logged in
if (!$this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('zfcuser/login');
}
return new ViewModel(array(
'success' => true,
));
}
Test Results:
1) SmsTest\Controller\SmsControllerTest::testIndexActionCanBeAccessed
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:450
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php:110
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/PluginManager.php:90
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:276
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:291
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:974
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:974
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:158
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php:87
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:468
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:208
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:108
/var/www/soap-app.localhost/Zend/module/Sms/test/SmsTest/Controller/SmsControllerTest.php:57
The line which causes this exception is the controller is: if (!$this->zfcUserAuthentication()->hasIdentity()) {
That line relates to line 974 in the SmsController.
It's obvious I don't have access to the ZfcUserAuthentication service, so the question is, How do I mock the ZfcUserAuthentication service and inject it in to my Controller?
To continue the theme how would I go about mocking a logged in user to successfully test my action is working to specification?
The ZfcUser documentation suggests that this is a plugin so you need to inject this into the controller.
You will need to amend your class names to pick up the ZfcUser classes
Your mocks will also need to be addapted as getIdenty returns a different object.
The following worked for me - insert in your phpunit setUp() method.
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new RegisterController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array('controller' => 'add'));
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
$mockAuth = $this->getMock('ZfcUser\Entity\UserInterface');
$ZfcUserMock = $this->getMock('ZfcUser\Entity\User');
$ZfcUserMock->expects($this->any())
->method('getId')
->will($this->returnValue('1'));
$authMock = $this->getMock('ZfcUser\Controller\Plugin\ZfcUserAuthentication');
$authMock->expects($this->any())
->method('hasIdentity')
-> will($this->returnValue(true));
$authMock->expects($this->any())
->method('getIdentity')
->will($this->returnValue($ZfcUserMock));
$this->controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
There may be an easier way would welcome other thoughts.
This is how I did it.
<?php
namespace IssueTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class IssueControllerTest extends AbstractHttpControllerTestCase
{
protected $serviceManager;
public function setUp()
{
$this->setApplicationConfig(
include '/media/policybubble/config/application.config.php'
);
parent::setUp();
$ZfcUserMock = $this->getMock('ZfcUser\Entity\User');
$ZfcUserMock->expects($this->any())
->method('getId')
->will($this->returnValue('1'));
$authMock = $this->getMock(
'ZfcUser\Controller\Plugin\ZfcUserAuthentication'
);
$authMock->expects($this->any())
->method('hasIdentity')
->will($this->returnValue(true));
$authMock->expects($this->any())
->method('getIdentity')
->will($this->returnValue($ZfcUserMock));
$this->serviceManager = $this->getApplicationServiceLocator();
$this->serviceManager->setAllowOverride(true);
$this->serviceManager->get('ControllerPluginManager')->setService(
'zfcUserAuthentication', $authMock
);
}
public function testIndexActionCanBeAccessed()
{
$this->dispatch('/issue');
$this->assertResponseStatusCode(200);
$this->assertModuleName('Issue');
$this->assertControllerName('Issue\Controller\Issue');
$this->assertControllerClass('IssueController');
$this->assertMatchedRouteName('issue');
}
public function testAddActionRedirectsAfterValidPost()
{
$issueTableMock = $this->getMockBuilder('Issue\Model\IssueTable')
->disableOriginalConstructor()
->getMock();
$issueTableMock->expects($this->once())
->method('saveIssue')
->will($this->returnValue(null));
$this->serviceManager->setService('Issue\Model\IssueTable', $issueTableMock);
$postData = array(
'title' => 'Gun Control',
'id' => '',
);
$this->dispatch('/issue/add', 'POST', $postData);
$this->assertResponseStatusCode(302);
$this->assertRedirectTo('/issue');
}
public function testEditActionRedirectsAfterValidPost()
{
$issueTableMock = $this->getMockBuilder('Issue\Model\IssueTable')
->disableOriginalConstructor()
->getMock();
$issueTableMock->expects($this->once())
->method('saveIssue')
->will($this->returnValue(null));
$this->serviceManager->setService('Issue\Model\IssueTable', $issueTableMock);
$issueTableMock->expects($this->once())
->method('getIssue')
->will($this->returnValue(new \Issue\Model\Issue()));
$postData = array(
'title' => 'Gun Control',
'id' => '1',
);
$this->dispatch('/issue/edit/1', 'POST', $postData);
$this->assertResponseStatusCode(302);
$this->assertRedirectTo('/issue');
}
public function testDeleteActionRedirectsAfterValidPost()
{
$postData = array(
'title' => 'Gun Control',
'id' => '1',
);
$this->dispatch('/issue/delete/1', 'POST', $postData);
$this->assertResponseStatusCode(302);
$this->assertRedirectTo('/issue');
}
}
<?php
namespace Issue\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Issue\Model\Issue;
use Issue\Form\IssueForm;
class IssueController extends AbstractActionController
{
protected $issueTable;
public function indexAction()
{
if (!$this->zfcUserAuthentication()->hasIdentity()) {
return;
}
return new ViewModel(
array(
'issues' => $this->getIssueTable()->fetchAll(
$this->zfcUserAuthentication()->getIdentity()->getId()
),
)
);
}
public function addAction()
{
if (!$this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('issue');
}
$form = new IssueForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$issue = new Issue();
$form->setInputFilter($issue->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$issue->exchangeArray($form->getData());
$this->getIssueTable()->saveIssue(
$issue,
$this->zfcUserAuthentication()->getIdentity()->getId()
);
// Redirect to list of issues
return $this->redirect()->toRoute('issue');
}
}
return array('form' => $form);
}
public function editAction()
{
if (!$this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('issue');
}
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute(
'issue', array(
'action' => 'add'
)
);
}
// Get the Issue with the specified id. An exception is thrown
// if it cannot be found, in which case go to the index page.
try {
$issue = $this->getIssueTable()->getIssue($id);
} catch (\Exception $ex) {
return $this->redirect()->toRoute(
'issue', array(
'action' => 'index'
)
);
}
$form = new IssueForm();
$form->bind($issue);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($issue->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getIssueTable()->saveIssue(
$issue,
$this->zfcUserAuthentication()->getIdentity()->getId()
);
// Redirect to list of issues
return $this->redirect()->toRoute('issue');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
public function deleteAction()
{
if (!$this->zfcUserAuthentication()->hasIdentity()) {
return $this->redirect()->toRoute('issue');
}
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('issue');
}
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->getPost('del', 'No');
if ($del == 'Yes') {
$id = (int)$request->getPost('id');
$this->getIssueTable()->deleteIssue($id);
}
// Redirect to list of issues
return $this->redirect()->toRoute('issue');
}
return array(
'id' => $id,
'issue' => $this->getIssueTable()->getIssue($id)
);
}
public function getIssueTable()
{
if (!$this->issueTable) {
$sm = $this->getServiceLocator();
$this->issueTable = $sm->get('Issue\Model\IssueTable');
}
return $this->issueTable;
}
}