Having problems combining Zend_Acl and Zend_Navigation - zend-framework

I have a Federico_Plugin_Acl that extends Zend_Controller_Plugin_Abstract which looks like this:
class Federico_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
private $_acl = null;
private $_auth = null;
const DEFAULT_ROLE = 'guest';
public function __construct($auth) {
$this->_auth = $auth;
$this->_acl = new Zend_Acl();
$this->_acl->addRole(new Zend_Acl_Role(self::DEFAULT_ROLE));
$this->_acl->addRole(new Zend_Acl_Role('user'), self::DEFAULT_ROLE);
$this->_acl->addRole(new Zend_Acl_Role('admin'), 'user');
$this->_acl->addResource(new Zend_Acl_Resource('index'));
$this->_acl->addResource(new Zend_Acl_Resource('users'));
$this->_acl->addResource(new Zend_Acl_Resource('about'));
$this->_acl->addResource(new Zend_Acl_Resource('gisele'));
$this->_acl->addResource(new Zend_Acl_Resource('admin'));
$this->_acl->allow('guest', 'index');
$this->_acl->allow('guest', 'about');
$this->_acl->deny('guest', 'gisele');
$this->_acl->deny('guest', 'users');
$this->_acl->allow('user', 'users', array('index'));
$this->_acl->allow('admin', 'users');
$this->_acl->allow('admin', 'gisele');
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
if ($this->_auth->hasIdentity()) {
$role = $this->_auth->getStorage()->read()->role;
} else {
$role = self::DEFAULT_ROLE;
}
$action = $request->getActionName();
$controller = $request->getControllerName();
if ($this->_acl->has($controller)) {
if (!$this->_acl->isAllowed($role, $controller, $action)) {
$request->setActionName('login');
$request->setControllerName('index');
}
}
}
}
And this method is in my bootstrap to make use of this class:
protected function _initNavigation()
{
$this->_auth = Zend_Auth::getInstance();
$this->_acl = new Federico_Plugin_Acl($this->_auth);
$this->bootstrap('view');
$view = $this->getResource('view');
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml','nav');
$navigation = new Zend_Navigation($config);
$roleAuth = $this->_auth->getIdentity();
if(null == $roleAuth)
$role = 'guest';
else
$role = $roleAuth->role;
$view->navigation($navigation)->setAcl($this->_acl)->setRole($role);
}
With these configurations set like that, I get the following error:
Catchable fatal error: Argument 1 passed to Zend_View_Helper_Navigation_HelperAbstract::setAcl() must be an instance of Zend_Acl, instance of Federico_Plugin_Acl given, called in /home/fiodorovich/public_html/gisele/application/Bootstrap.php on line 118 and defined in /home/fiodorovich/library/ZendFramework/library/Zend/View/Helper/Navigation/HelperAbstract.php on line 333
Call Stack
Which is to be expected since Federico_Plugin_Acl is an instance of Zend_Controller_Plugin_Abstract...Still, if I extend Zend_Acl instead I get this error:
Fatal error: Zend_Acl_Role_Registry_Exception: Role 'guest' not found in /home/fiodorovich/library/ZendFramework/library/Zend/View/Helper/Navigation/HelperAbstract.php on line 522
So...I've been trying for a while to get this thing solved,... but don't seem to get this to work properly...Any ideas on what I'm missing here?

Zend_Controller_Plugin_Abstract and Zend_Acl are completelly different things. What you want to do is get the ACL object out of your plugin (which is now in private section) and pass it over to
$view->navigation($navigation)->setAcl(<here>);

Related

It doesn't find my class even if it exists

This is the error:
Fatal error: Class 'Admin_Controller' not found in C:\xampp\htdocs\ci-blog-master\application\modules\admin\controllers\Settings.php on line 4
A PHP Error was encountered
Severity: Error
Message: Class 'Admin_Controller' not found
Filename: controllers/Settings.php
Line Number: 4
Backtrace:
And here is my code for :
Admin_controller.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Admin_Controller extends MY_Controller {
function __construct()
{
parent::__construct();
}
}
And here is my Settings.php
class Settings extends Admin_Controller {
public function __construct(){
parent::__construct();
$this->allow_group_access(array('admin'));
$this->load->model('Category');
$this->data['parent_menu'] = 'post';
}
public function index(){
$this->session->set_flashdata('message',message_box('Setting is the coming soon feature!','danger'));
redirect('admin/posts/index');
$config['base_url'] = site_url('admin/categories/index/');
$config['total_rows'] = count($this->Category->find());
$config['per_page'] = 10;
$config["uri_segment"] = 4;
$this->data['categories'] = $this->Category->find($config['per_page'], $this->uri->segment(4));
$this->data['pagination'] = $this->bootstrap_pagination($config);
$this->render('admin/categories/index');
}
public function add(){
$this->form_validation->set_rules('name', 'name', 'required|is_unique[categories.name]');
$this->form_validation->set_rules('status', 'status', 'required');
if($this->form_validation->run() == true){
$category = array(
'name' => $this->input->post('name'),
'status' => $this->input->post('status')
);
$this->Category->create($category);
$this->session->set_flashdata('message',message_box('Category has been saved','success'));
redirect('admin/categories/index');
}
$this->render('admin/categories/add');
}
public function edit($id = null){
if($id == null){
$id = $this->input->post('id');
}
$this->form_validation->set_rules('name', 'name', 'required');
$this->form_validation->set_rules('status', 'status', 'required');
if($this->form_validation->run() == true){
$category = array(
'name' => $this->input->post('name'),
'status' => $this->input->post('status')
);
$this->Category->update($category, $id);
$this->session->set_flashdata('message',message_box('Category has been saved','success'));
redirect('admin/categories/index');
}
$this->data['category'] = $this->Category->find_by_id($id);
$this->render('admin/categories/edit');
}
public function delete($id = null){
if(!empty($id)){
$this->Category->delete($id);
$this->session->set_flashdata('message',message_box('Category has been deleted','success'));
redirect('admin/categories/index');
}else{
$this->session->set_flashdata('message',message_box('Invalid id','danger'));
redirect('admin/categories/index');
}
}
public function update_multiple(){
#test commit
#test commit di branch sendiri
}
}
You can put more classes in MY_Controller.php file:
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function some_mycontr_method()
{
// appropriate code here
}
}
class Admin_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function some_admin_method()
{
// appropriate code here
}
}

Symfony2, Keep form data across redirect

How to use session for retrieving data during redirect? I am getting the error message: "exception 'Symfony\Component\Form\Exception\AlreadySubmittedException' with message 'You cannot change the data of a submitted form."
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Controller\UserController.php
/**
* Creates a new User entity.
*
* #Route("/new", name="user_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm(new UserType(), $user);
$form->handleRequest($request);
$session = $this->getRequest()->getSession();
$form->setData(unserialize($session->get('userFilter')));
if ( $form->isSubmitted() && $form->isValid() ) {
$session->set( 'userFilter', serialize($form->getData()) );
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('MeetingBundle::user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
} // public function newAction(Request $request)
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\EventListener\ExceptionListener.php
<?php
namespace MeetingBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
//every time the Kernel throws the kernel.exception event, the function onKernelException() is called.
/* also must create service :
meeting.exception_listener:
class: MeetingBundle\EventListener\ExceptionListener
arguments: [#templating, #kernel, #router]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
*/
class ExceptionListener
{
protected $templating;
protected $kernel;
protected $router;
public function __construct( EngineInterface $templating, $kernel, Router $router)
{
$this->templating = $templating;
$this->kernel = $kernel;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$request=$event->getRequest();
$referer = $event->getRequest()->headers->get('referer');
$msg="";
$excStr=$exception->__toString(); // returns string finally!
$bdup=strpos( $excStr , 'Integrity constraint violation: 1062 Duplicate entry' );
if($bdup) {
$msg=" This username is already taken. Choose another username. ";
}
if(strlen($msg)!=0) {
// flash messsages are displayed in layout.html
$request->getSession()
->getFlashBag()
->add('Error', $msg);
}
$response = new RedirectResponse($referer); // redirect to the error page
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
}

Zend_ACL guest roles overide Adminstrator roles?

I have created Zend_ACL with three roles :'administrator, guest, *edito*r'. I want guest cannot access /album/index after login. Administrator, editor can access /album/index. All other pages are accessible by all.
I created the access list below with Acl.php in helper.
/library/My/Helper/Acl.php:
public function __construct() {
$this->acl = new Zend_Acl();
}
public function setRoles() {
$this->acl->addRole(new Zend_Acl_Role('guest'));
$this->acl->addRole(new Zend_Acl_Role('editor'));
$this->acl->addRole(new Zend_Acl_Role('administrator'));
}
public function setResource () {
$this->acl->add(new Zend_Acl_Resource('album::index'));
$this->acl->add(new Zend_Acl_Resource('album::add'));
$this->acl->add(new Zend_Acl_Resource('album::edit'));
$this->acl->add(new Zend_Acl_Resource('album::delete'));
$this->acl->add(new Zend_Acl_Resource('auth::index'));
$this->acl->add(new Zend_Acl_Resource('auth::logout'));
$this->acl->add(new Zend_Acl_Resource('error::error'));
}
public function setPrivilages() {
$allowEditorAdmin=array('administrator','editor');
$allowAll=array('administrator','guest','editor');
$this->acl->allow($allowEditorAdmin,'album::index');
$this->acl->allow($allowAll,'album::add');
$this->acl->allow($allowAll,'album::edit');
$this->acl->allow($allowAll,'album::delete');
$this->acl->allow($allowAll,'auth::index');
$this->acl->allow($allowAll,'auth::logout');
$this->acl->allow($allowAll,'error::error');
Then, I create a plugin Acl.php
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$acl1 = new My_Controller_Helper_Acl();
$acl = Zend_Registry::get('acl');
$userNs = new Zend_Session_Namespace('members');
if($userNs->userType=='')
{
$roleName='guest';
}
else
$roleName=$userNs->userType;
if(!$acl->isAllowed($roleName,$request->getControllerName()."::".$request->getActionname()))
{
echo $request->getControllerName()."::".$request->getActionName();
$request->setControllerName('auth');
$request->setActionName('index');
}
else
echo "got authenticated";
}
The problem is my code "isallowed" not work correctly. The 'guest,editor,administrator' cannot access to /album/index after authenticate successfully. They redirect to /auth/index
if(!$acl->isAllowed($roleName,$request->getControllerName()."::".$request->getActionname()))
{
echo $request->getControllerName()."::".$request->getActionName();
$request->setControllerName('auth');
$request->setActionName('index');
}
else
echo "got authenticated";
}
As far as I can tell, You are using 2 different ACL instances, and never set up the appropriate ACL in the first place. I can share a bit of my own code, that does almost the same thing:
In Bootstrap.php
$this->_acl = new Model_AuthAcl();
//Check for access rights
$fc = Zend_Controller_Front::getInstance();
$fc->registerPlugin(new App_Plugin_AccessCheck($this->_acl));
In App_Plugin_AccessCheck
class App_Plugin_AccessCheck extends Zend_Controller_Plugin_Abstract
{
private $_acl = null;
public function __construct(Zend_Acl $acl)
{
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$module = $request->getModuleName();
$resource = $request->getControllerName();
$action = $request->getActionName();
try {
if (!$this->_acl->isAllowed(Zend_Registry::get('role'), $module . ':' . $resource, $action)) {
$request->setControllerName('authentication')->setModuleName('default')
->setActionName('login');
}
}
catch (Exception $ex) {
if (APPLICATION_ENV == "development") {
var_dump($ex->getMessage());
}
}
}
}
In Model_AuthAcl
class Model_AuthAcl extends Zend_Acl
{
/**
* Creates the resource, role trees
*/
public function __construct ()
{
//Create roles
$this->addRole(new Zend_Acl_Role('guest'));
$this->addRole(new Zend_Acl_Role('user'), 'guest');
$this->addRole(new Zend_Acl_Role('admin'), 'user');
//Create resources
//Default module
$this->addResource(new Zend_Acl_Resource('default'))
->addResource(new Zend_Acl_Resource('default:authentication'), 'default')
->addResource(new Zend_Acl_Resource('default:error'), 'default')
//Admin module
->addResource(new Zend_Acl_Resource('admin'))
->addResource(new Zend_Acl_Resource('admin:index'), 'admin')
//Guest permissions
$this->deny('guest')
->allow('guest', 'default:authentication', array('index', 'login', 'logout', 'email', 'forgot'))
->allow('guest', 'default:error', array('error'))
->allow('guest', 'api:authentication', array('index', 'get', 'head', 'post', 'put', 'delete'))
//Admin permissions
->deny('admin', 'admin:admins')
;
}
}
May not be the most OOP solution, bet it sure as hell works.
Hope this helps you set up your dream ACL :)

Zend Framework - Passing a variable request in controller

In one of these php frameworks I've noticed a posibility to request the object Request in action as $this->request->paramName
class MyRequest extends Zend_Controller_Request_Http{
public $params = array();
public function __construct() {
$this->params = $this->getParams();
parent::__construct();
}
public function __get($name) {
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
}
public function __isset($name) {
return isset($this->_params[$name]);
}
}
in MyController I've added variable request
public $request = null;
How can I change that standart Request to my one?
public function __construct(
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()) {
$request = new MyRequest();
parent::__construct($request, $response, $invokeArgs);
$this->request = $this->getRequest();
}
This function has given no results.
Option 1 is make method _initRequest() in bootstrap:
protected function _initRequest() {
$this->bootstrap ( 'FrontController' );
$front = $this->getResource ( 'FrontController' );
$request = $front->getRequest ();
if (null === $front->getRequest ()) {
$request = new MyRequest();
$front->setRequest ( $request );
}
return $request;
}
A bit dirty and untested solution. Would love to hear if it works.
//Bootstrap:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new MyRequest());
}
Try this it might help you:
in controller file
public function exampleAction(){
$result = $this->_request;
$model = new Employer_Model_JobInfo();
$results = $model->sample($result);
}
// the above line stores the values sent from the client side in $result.then sends that values to Model file with parameter $result ..
in model file
class Employer_Model_JobInfo extends Gears_Db_Table_Abstract{
public function sample($param){
$paramVal = $param->getParam('name');
$paramVal1 = $param->getParam('email');
}
}
The name and email are what name used to sent the data from client to server.

is there a way to set up the acl roles that are allowed to access different parts of the site in my navigation.xml?

I have this in my bootstrap:
protected function _initAutoload()
{
$this->_auth = Zend_Auth::getInstance();
$this->_acl = new Federico_Plugin_Acl($this->_auth);
....
}
....
protected function _initNavigation()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml','nav');
$navigation = new Zend_Navigation($config);
$view->navigation($navigation)->setAcl($this->_acl)
->setRole($this->_auth->getStorage()->read()->role);//I just added this
}
however the insert I just did generated this:
Catchable fatal error: Argument 1 passed to Zend_View_Helper_Navigation_HelperAbstract::setAcl() must be an instance of Zend_Acl, instance of Federico_Plugin_Acl given, called in /home/fiodorovich/public_html/gisele/application/Bootstrap.php on line 106 and defined in /home/fiodorovich/library/ZendFramework/library/Zend/View/Helper/Navigation/HelperAbstract.php on line 333
And this is what my navigation.xml looks like so far:
<configdata>
<nav>
<home>
<label>HOME</label>
<controller>index</controller>
<action>index</action>
</home>
<about>
<label>Nosotros</label>
<module>default</module>
<controller>about</controller>
<action>index</action>
</about>
<admin>
<label>Admin</label>
<uri>admin/index</uri>
<resource>admin</resource>
<pages>
<alta>
<active>0</active>
<label>Alta Usuario</label>
<controller>users</controller>
<action>create</action>
</alta>
</pages>
</admin>
</nav>
Right now, even the guests users can see that items in the nav, althogh they can't access since that's already set up in the Acl class... how do I pass the acl roles in here?
EDIT:
//my acl
class Federico_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
private $_acl = null;
private $_auth = null;
const DEFAULT_ROLE = 'guest';
public function __construct($auth)
{
$this->_auth = $auth;
$this->_acl = new Zend_Acl();
$this->_acl->addRole(new Zend_Acl_Role(self::DEFAULT_ROLE));
$this->_acl->addRole(new Zend_Acl_Role('user'), self::DEFAULT_ROLE);
$this->_acl->addRole(new Zend_Acl_Role('admin'), 'user');
$this->_acl->addResource(new Zend_Acl_Resource('index'));
$this->_acl->addResource(new Zend_Acl_Resource('users'));
$this->_acl->addResource(new Zend_Acl_Resource('about'));
$this->_acl->addResource(new Zend_Acl_Resource('gisele'));
$this->_acl->addResource(new Zend_Acl_Resource('admin'));
$this->_acl->allow('guest', 'index');
$this->_acl->allow('guest', 'about');
$this->_acl->deny('guest', 'gisele');
$this->_acl->deny('guest', 'users');
$this->_acl->allow('user', 'users', array('index'));
$this->_acl->allow('admin','users');
$this->_acl->allow('admin','gisele');
}
public function preDispatch (Zend_Controller_Request_Abstract $request)
{
if ($this->_auth->hasIdentity()) {
// user is logged in and we can get role
$role = $this->_auth->getStorage()->read()->role;
} else {
// guest
$role = self::DEFAULT_ROLE;
}
$action = $request->getActionName();
$controller = $request->getControllerName();
if($this->_acl->has($controller)) {
if(!$this->_acl->isAllowed($role, $controller, $action)) {
$request->setActionName('error');
$request->setControllerName('error');
}
}
}
}
Get the Zend_View instance (in your bootstrap, in an action helper, wherever it's easier for you) and then:
$view->navigation()
->setAcl(Zend_Acl $acl)
->setRole(Zend_Acl_Role $role);
Basically, the navigation view helper must explicitly be given knowledge about the ACL and current role.