I would like to deny access to the private areas on my website. But I don't know what I am doing wrong.
I don't want to use Acl::DENY as the default rule.
Instead I am using Acl::ALLOW as the global rule and denying access to the private resources.
Here is my code:
<?php
use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;
class SecurityPlugin extends Plugin {
public function getAcl() {
if (!isset($this->persistent->acl)) {
$acl = new AclList();
$acl->setDefaultAction(Acl::ALLOW);
$roles = array(
'admin' => new Role('Administrators'),
'guests' => new Role('Guests')
);
foreach ($roles as $role) {
$acl->addRole($role);
}
//Private area resources
$privateResources = array(
'admin' => array('index'),
'products' => array('index', 'search', 'new');
foreach ($privateResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($privateResources as $resource => $actions) {
foreach ($actions as $action) {
$acl->deny('Guests', $resource, $action);
}
}
}
return $this->persistent->acl;
}
public function beforeDispatch(Event $event, Dispatcher $dispatcher) {
$auth = $this->session->get('auth');
if (!$auth) {
$role = 'Guests';
} else {
$role = 'Admin';
}
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->getAcl();
$allowed = $acl->isAllowed($role, $controller, $action);
if ($allowed != Acl::ALLOW) {
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show401'
));
$this->session->destroy();
return false;
}
}
}
Thank you, for trying to help me.
You forgot to actually assign your ACL definitions to $this->persistent->acl
public function getAcl() {
if (!isset($this->persistent->acl)) {
$acl = new AclList();
...
//The acl is stored in session
$this->persistent->acl = $acl;
}
return $this->persistent->acl;
}
By looking at your code, I am guessing you used the Phalcon INVO example for this SecurityPlugin?
If so, refer to line 88. If not, this is a nice and easy example that can help you.
Related
Thanks to all in advance for posting answers.
Actually I am learning the Zend framework so now I am working with Zend ACL for allowed/deny multiple user roles to access controller/action. so for this, I did create a helper in app/controllers/helpers/acl.php and a code in app/bootstrap.php. now I did use this helper in bootstrap.php so when the application will be load/initialize then it will be work. Now it's working but I am looking for advance I want to add custom assertion where is allowed only for the user which is related to him like I can only edit or delete post I did create it.
So if you can help me please do.
My code is posted below
file App/Controllers/Helpers/Acl.php
<?php
require_once 'Zend/Controller/Action/Helper/Abstract.php';
class Zend_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract {
protected $acl;
protected $role;
function __construct() {
$this->sess = new Zend_Session_Namespace("session");
$this->logger = Zend_Registry::get('logger');
}
protected function getAcl(){
if (is_null($this->acl)){
$acl = new Zend_Acl();
$roles = array('owner', 'administrator', 'editor', 'readonly');
$controllers = array('index', 'projects', 'applications', 'checks', 'settings', 'ajax', 'error', 'languageswitch');
//Add Roles
foreach ($roles as $role) {
$acl->addRole(new Zend_Acl_Role($role));
}
//Add Resources
foreach ($controllers as $controller) {
$acl->add(new Zend_Acl_Resource($controller));
//Administrator, Editior, Readonly
if($controller == 'projects'){
$acl->allow('administrator', $controller, array('main', 'add', 'detail', 'edit'));
$acl->allow('editor', $controller, array('main', 'add', 'detail', 'edit'));
$acl->allow('readonly', $controller, array('main', 'add', 'detail'));
}else if($controller == 'applications'){
$acl->allow('administrator', $controller, array('main', 'add', 'detail', 'edit', 'auditview', 'delete'));
$acl->allow('editor', $controller, array('main', 'add', 'detail', 'edit', 'audit'));
$acl->allow('readonly', $controller, array('main', 'detail', 'audit'));
}else {
$acl->allow('administrator', $controller);
$acl->allow('editor', $controller);
$acl->allow('readonly', $controller);
}
}
//Owner
$acl->allow('owner'); // Owner Has access to everything.
$this->acl = $acl;
}
return $this->acl;
}
protected function getRole(){
if (is_null($this->role)){
$session = new Zend_Session_Namespace('session');
$role = (isset($session->currentrole)) ? $session->currentrole : 'guest';
$this->role = $role;
}
return $this->role;
}
public function direct($resource, $privilege = null){
$acl = $this->getAcl();
$role = $this->getRole();
$allowed = $acl->isAllowed($role, $resource, $privilege);
return $allowed;
}
}
file App/Bootstrap.php
//Set Role Permission
$acl = new Zend_Controller_Action_Helper_Acl();
Zend_Registry::set('acl', $acl);
$permission = Zend_Registry::get('acl');
$request = new Zend_Controller_Request_Http();
$resource = $request->getControllerName();
$privilege = $request->getActionName();
if (!$permission->direct($resource, $privilege)) {
$request->setControllerName('error');
$request->setActionName('error');
}
My advice is to use a different approach.
First, you should create a class where you define you full ACL definitions, for example "My_Acl" that extends Zend_Acl.
Register in My_Acl all your roles, resources and privileges.
Make "My_Acl" singleton in order to get your configured Acl ( Zend_Acl ) using My_Acl::getInstance().
If you like you can also register this instance in your Zend_Registry.
Since you want to check in the user has privileges to access any action of any controller, my advice is to create a Plugin and register it at predispatch, in order to check all access in a single point.
You can also create an action helper ( eg My_Controller_Action_Helper_Acl ) with a isAllowed method that proxies the $alc->isAllowed, in order to check if a specific part of yuor action is accessible to the current logged user.
I am working on a small project where I have to implement an Acl, so i tried to implement it like in the sample invo project and it worked well. However, I want to add to the functionality that it gets its roles from the existing model called Role. Whenever I add the line $roles = Role::find(); there is an error in the application. Is it not possible to access this data from a plugin? Or if possible how to access it?
Here is my SecurityPlugin file
<?php
use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;
/**
* SecurityPlugin
*
* This is the security plugin which controls that users only have access to the modules they're assigned to
*/
class SecurityPlugin extends Plugin
{
/**
* Returns an existing or new access control list
*
* #returns AclList
*/
public function getAcl()
{
if (!isset($this->persistent->acl)) {
$acl = new AclList();
$acl->setDefaultAction(Acl::DENY);
//Register roles **this is the line that causes the problem**
$roles = Role::find();
$acl->addRole(new Role('Guest'));
$acl->addRole(new Role('User'));
//Public area resources
$publicResources = array(
'index' => array('index'),
'User' => array('new'),
'Errors' => array('show401'),
'Session' => array('index', 'register', 'start', 'end')
);
foreach ($publicResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($publicResources as $resource => $actions) {
foreach ($actions as $action) {
$acl->allow('Guest', $resource, $action);
$acl->allow('User', $resource, $action);
}
}
//Grant access to public areas to both users and guests
//The acl is stored in session, APC would be useful here too
$this->persistent->acl = $acl;
}
return $this->persistent->acl;
}
/**
* This action is executed before execute any action in the application
*
* #param Event $event
* #param Dispatcher $dispatcher
*/
public function beforeDispatch(Event $event, Dispatcher $dispatcher)
{
$auth = $this->session->get('auth');
if (!$auth){
$role = 'Guest';
} else {
$role = 'User';
}
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
if ($auth['username'] == 'Admin') {
return;
}
$acl = $this->getAcl();
$allowed = $acl->isAllowed($role, $controller, $action);
if ($allowed != Acl::ALLOW) {
$dispatcher->forward(array(
'controller' => 'Errors',
'action' => 'show401'
));
$this->session->destroy();
return false;
}
}
}
and here is the related code in services.php
$di->set('dispatcher', function() use ($di) {
$eventsManager = new EventsManager;
/**
* Check if the user is allowed to access certain action using the SecurityPlugin
*/
$eventsManager->attach('dispatch:beforeDispatch', new SecurityPlugin);
$dispatcher = new Dispatcher;
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
It looks like your Role model and the Phalcon\Acl\Role are colliding.
I would alias your Role model to something like RoleModel.
<?php
use Phalcon\Acl\Role;
use \Role as RoleModel;
...
class SecurityPlugin extends Plugin {
public function getAcl() {
...
$roles = RoleModel::find();
...
Hi can someone help me to prevent bjyauthorize to catch my api event error raised?
bjyauthorize redirect non logged user to login form as added to config. But since my api are allowed for all roles even for guest i just want it to return Json error message catched by ApiProblemListener
ApplicationRest\Module.php
class Module implements
ConfigProviderInterface,
AutoloaderProviderInterface
{
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$events = $app->getEventManager();
$listener = $sm->get('ApplicationRest\ApiAuthenticationListener');
$events->getSharedManager()->attach('ApplicationRest\Controller', 'dispatch', $listener, 500);
$events->attach('render', array($this, 'onRender'), 100);
$events->attach($sm->get('ApplicationRest\ApiProblemListener'));
}
/**
* Listener for the render event
* Attaches a rendering/response strategy to the View.
*
* #param \Zend\Mvc\MvcEvent $e
*/
public function onRender($e)
{
$result = $e->getResult();
if (!$result instanceof RestfulJsonModel) {
return;
}
//var_dump(123);exit();
$app = $e->getTarget();
$services = $app->getServiceManager();
$view = $services->get('View');
$restfulJsonStrategy = $services->get('ApplicationRest\RestfulJsonStrategy');
$events = $view->getEventManager();
// register at high priority, to "beat" normal json strategy registered
// via view manager
$events->attach($restfulJsonStrategy, 500);
}
}
Have many modules and i am really thinking to move away my apiModule "ApplicationRest" to another project but don't really want to update model and service each time i make some updates on main project.
Any suggestions would welcome!
Thanks for your time!
EDIT: Provided more HeaderAuthentication class
class HeaderAuthentication implements AdapterInterface
{
const AUTHORIZATION_HEADER = 'Authorization';
const CRYPTO = 'sha256';
protected $request;
protected $repository;
public function __construct(RequestInterface $request, UserRepository $repository)
{
$this->request = $request;
$this->repository = $repository;
}
/**
* Authorization: Key={key} Timestamp={timestamp} Signature={signature}
* #return Result
*/
public function authenticate()
{
$request = $this->getRequest();
if (!$request instanceof Request) {
return;
}
$headers = $request->getHeaders();
// Check Authorization header presence
if (!$headers->has(static::AUTHORIZATION_HEADER)) {
return new Result(Result::FAILURE, null, array(
'Authorization header missing'
));
}
$authorization = $headers->get(static::AUTHORIZATION_HEADER)->getFieldValue();
// Validate public key
$publicKey = $this->extractPublicKey($authorization);
$user = $this->getUserRepository()
->findOneByApiSecret($publicKey);
if (null === $user) {
$code = Result::FAILURE_IDENTITY_NOT_FOUND;
return new Result($code, null, array(
'User not found based on public key'
));
}
// Validate signature
$signature = $this->extractSignature($authorization);
/*$hmac = $this->getHmac($request, $user);
if ($signature !== $hmac) {
$code = Result::FAILURE_CREDENTIAL_INVALID;
return new Result($code, null, array(
'Signature does not match'
));
}*/
return new Result(Result::SUCCESS, $user);
}
}
ApiAuthenticationListener
class ApiAuthenticationListener
{
protected $adapter;
public function __construct(HeaderAuthentication $adapter)
{
$this->adapter = $adapter;
}
public function __invoke(MvcEvent $event)
{
$result = $this->adapter->authenticate();
if (!$result->isValid()) {
$response = $event->getResponse();
// Set some response content
$response->setStatusCode(401);
return $response;
}
// All is OK
$event->setParam('user', $result->getIdentity());
}
}
I'm guessing you configured guards on your route. You need to tell BJYAuthorize, through your module config, that this controller or route shouldn't be protected.
'bjyauthorize' => [
'default_role' => 'guest',
...
'guards' => [
'BjyAuthorize\Guard\Controller' => [
// system tools
['controller' => 'Application\Controller\Api', 'roles' => [] ],
['controller' => 'error', 'roles' => []],
],
],
],
I cut out the nitty gritty that's app specific, but this type of thing is quickly solved. I had a similar need for CLI routes to be unprotected by what is otherwise, http auth.
AR model Player:
public function scopes()
{
return array(
'proleague' => array(
'condition' => 'mode = "proleague"',
),
'main' => array(
'condition' => 'mode = "main"',
),
);
}
Using model Player:
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
^^^ That's all ok. Scope-condition will be executed. But...
In my project I have many places where any scope for Player model doesn't specified and in this cases I need use this scope-condition as default:
'main' => array(
'condition' => 'mode = "main"',
)
If I add defaultScope() method to Player model like this
public function defaultScope()
{
return array(
'condition' => 'mode = "main"',
);
}
the next code
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
won't run correct. I won't get mode = "proleague" condition, becouse I'll use defaultScope() with mode = "main".
Any suggestions? How can I resolve the problem?
You should just use the resetScope(true) method. It "removes" the defaultScope filter.
$model = Player::model()->resetScope(true)->proleague();
create a new Class for this.
<?php
## e.g. protected/models/
class MyCoreAR extends CActiveRecord
{
/**
* Switch off the default scope
*/
private $_defaultScopeDisabled = false; // Flag - whether defaultScope is disabled or not
public function setDefaultScopeDisabled($bool)
{
$this->_defaultScopeDisabled = $bool;
}
public function getDefaultScopeDisabled()
{
return $this->_defaultScopeDisabled;
}
public function noScope()
{
$obj = clone $this;
$obj->setDefaultScopeDisabled(true);
return $obj;
}
// see http://www.yiiframework.com/wiki/462/yii-for-beginners-2/#hh16
public function resetScope($bool = true)
{
$this->setDefaultScopeDisabled(true);
return parent::resetScope($bool);
}
public function defaultScope()
{
if(!$this->getDefaultScopeDisabled()) {
return array(
'condition' => 'mode = "main"',
);
} else {
return array();
}
}
}
In your code:
// no default scope
$model = Player::model()->noScope()->proleague();
// with default scope
$model = Player::model()->proleague();
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;
}
}