Access Controller's action variable in layout in ZF - php

I want to access the variable in layout in zend framework, how can I do that. I searched a lot but can't find any thing useful or helpful for me. Below are the links that I already tried so admin please don't mark this question as duplicate one..
Thanks..
Zend Framework 2 - Layout and variable
access controller action variables to zf2 layout
Senario
I have a link in layout.phtml that I want to display on conditional bases. Like some user of my sites cannot see that link but other can do. That condition comes from the databases that I have but I don't know how to access that in layout.phtml
Example
<?php if($this->check == true) {?>This Link<?php } ?>
if $this->check == true than show the link otherwise not.

Pass the variable from the action to the view like
$this->view->check = true;
Then access it in the view like $this->check and do the checking
if($this->check){
//Do something
}
else{
//Do something
}

I got the solution of my problem
write the below code in IndexController's init Function
$this->_helper->layout()->myvar = $someValue;
and access it in the layout by this code
$this->placeholder('Zend_Layout')->myvar;
One has to so this for each controller that he/she has in his/her application. Otherwise will get an error regarding undefined variable.
Reference:
http://framework.zend.com/manual/1.12/en/zend.layout.quickstart.html
Line 15 of first code listing....

Related

Avoid repeating session and access right checks in codeigniter 3 controller

I have implemented a simple role check code with the help of helpers using sessions in my codeigniter 3 application.
Access Helper: Defines a function named as access_right which checks if the logged in user has access right to visit a specific module or not and correspondingly returns true or false.
In addition to it, I also have two versions of navigation bars one for admin user and for non admin users.
In controller i have added following code to perform the check for both i.e. which navigation to load and if the logged in user has access or not to module:
if($this->session->userdata('user-type') === 'admin')
{
$this->load->view('templates/sub_header_admin');
}
else
{
$this->load->view('templates/sub_header');
}
if(access_right('client_information'))
{
$this->load->view('pages/clientview/client_page');
}
else
{
$this->load->view('templates/restricted_access');
}
$this->load->view('templates/footer');
Problem is I need to repeat this much of code in each and every method inside a controller.
access_right('client_information'), of-course instead of client_information i check for different value like 'operator_information' depending on which controller is loaded.
How can i avoid this repetition of code ?
Just like you avoided repeating code for checking 'client_information' access rights - create a function to do that.

How to store data in sessions vars using Zend Framework 2

I am interested in having data that can be access through all my views and controllers, but I would like this data to be cleared when the browser is closed or on a logout action.
The reason for this is because I want my views to work only if a variable is set.
eg:
public function adminAction(){
if ($rol_type=='admin'){
$this->renderScript('index/admin.phtml');
}
else{
$this->renderScript('index/adminLogin.phtml');
}
}
I would like also that the admin.phtml view can't be accesed without the variable being set to admin, so that no one can just change the URL and acces admin panel.
I've been reading the zend framework's 2 documentation about session but there is a lot of stuff inside the session module, so I don't know what to use, or where to look for.
I also would be very grateful if you could tell me what is the best way to achive my goal (cause I'm not sure if this is the best way to do what I want to do).
You can use :
use Zend\Session\Container;
In Controller:
$user_session = new Container('mySession');
$user_session->key = "Your Value";
This key can be passed to your view or other models and controllers.
For retrieving we have to do like:
$user_session = new Container('mySession');
$keyValue = $user_session->key; //here you will get the value stored above
Hope that helps
Thanks

CakePHP - Controller or No Controller?

I am currently building a web app which has two models, Donor and Donation Models respectively. It has multiple user roles. When the staff user first registers a donor, I want him to be redirected to another form which allows him to fill in the Donation details(the donor is registered once the first donation is successful).
Firs of all, should I create a donation controller, from which I would redirect the user using:
return $this->redirect(array('controller'=>'donations','action'=>'add'));
For the above to work, it requires me to save the newly registered donor's id in a session like so :
$this->Session->write('id', $this->Donor->id);
So the user is redirected to 'donations/add' in the url, and this works fine.. However I think this has some flaws. I was wandering whether I should create another action inside the Donor controller called 'add_donation', which will have its respective 'View'. The idea is to be able to form a url of the sort : 'donors/add_donation/4' (4 being the donor_id ! )
This URL follows this construct: 'controller/action/id'
If anyone could shed some light on best practices, or describe any caveats to my solution(the former, using session etc.) , please do help a brother out! Ill be deeply indebted to you! Thanks in advance!
After you saved the data you can do this in the DonorsController:
$this->redirect(array(
'controller' => 'donations',
'action' => 'add',
$this->Donor->getLastInsertId()
));
There is no need to return a redirect, it's useless because you get redirected. Notice that we pass the last inserted record id as get param in the redirect. The redirect method of the controller calls by default _stop() which calls exit().
CakePHP3: There is a discussion about changing that default behavior in 3.0. Looks like in CakePHP 3.0 the redirect() won't exit() by default any more.
DonationsController:
public function add($donorId = null) {
// Get the donor to display it if you like to
if ($this->request->is('post')) {
$this->request->data['Donation']['donor_id'] = $donorId;
// Save code here
}
}
I would not use the session here, specially not by saving it to a totally meaningless and generic value named "id". If at all I would use always meaningful names and namespaces, for example Donor.lastInsertId as session key.
It's not always clear where to put things if they're related but the rule of thumb goes that things should go into the domain they belong to, which is pretty clear in this case IMHO.
Edit:
Leaving this edit here just if someone else needs it - it does not comply with the usage scenario of the asker.
If you have the user logged in at this stage, modify the add function to check if the userId passed is the same as the one logged in:
DonationsController:
public function add($donorId = null) {
// Get the donor to display it if you like to
if ($this->request->is('post')) {
if ($this->Auth->user('id') != $donorId) {
throw new InvalidArgumentException();
}
$this->request->data['Donation']['donor_id'] = $donorId;
// Save code here
}
}
You can use also the same controller using more models with uses.
Or you can also to ask to another controller with Ajax and morover to get response with Json.

cakephp - callback function for every controller action to set available navigation links

I'm trying to achieve something so basic in my cakephp-app, that I'm quite surprised I didn't easily find a solution to it...
What I just want to do is to set available links for my app's main navigation depending on the user being logged in or not and if he is, depending on his role (which is stored in the users-table).
So basically a function like this:
if(!$this->request->is('ajax')) {
if(_user_is_not_logged_in_) {
$availableNavItems = array('login','help');
}
else {
if($this->Auth->User('role') == 'user') {
$availableNavItems = array('something','something else','whatever','help','logout');
}
elseif($this->Auth->User('role') == 'admin') {
$availableNavItems = array('something','something else','whatever','admin-tool','user management','help','logout');
}
}
// set available pages for layout
$this->set('availableNavItems',$availableNavItems);
}
In my layout of course I would create a navbar with links to those available pages.
The only question I have - where would I put code like the above? Is there any callback-function I could put in AppController which cakephp calls on every request?
And, what would be a good way to check what I wrote as pseudo-code "_user_is_not_logged_in_" above?
Thanks in advance for any help!
if(_user_is_not_logged_in_) {
could be written as
if(!$this->Auth->user('id')){
And you could put the function in your beforeRender method of your AppController, which executes on every request, right before the view is rendered.
Also of note is the beforeFilter method, which gets called early, before the controller logic executes. You shouldn't need it in this case, but it's worth knowing about.

Change element's text in CakePHP

I have an element called userbar on every page - it tells the user if he/she is logged in or not. I created this element and echoed it in default.ctp:
<?php echo $this->element('userbar', array('text' => 'You are not logged in.')); ?>
Now it shows on every page. However, I can't find anywhere how to change this text. For e.g., I would like to access this element from some controller and change it. How?
You set a view variable and then use that.
<?php
class MyController extends AppController
{
function myaction () {
$this->set ('my_var', 'You are not logged in');
}
}
?>
And then in the view:
<?php echo $this->element ('userbar', array ('text' => $my_var)); ?>
Considering this is something you'd do on every page request its best to put it in the AppController::beforeFilter().
There are other ways to do this. But if you render the element in the controller you still need to set a view variable and echo that in the view.
Hope this helps.
I think that vanneto did a good job on answering the question very specifically. But based on my opinion what happens here is a design flaw. That's why I add this answer to give you another option on how to approach this question. Because I see this kind of solutions and on the longer run they cause issues.
The case is a logged-in or logged-out text.
Let's say that you use the Auth component:
http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
We will start at the controller, likely you have something like this in the AppController:
public function beforeFilter() {
parent::beforeFilter();
$this->set('userIsLoggedIn', AuthComponent:: loggedIn());
$this->set('loggedInUser', AuthComponent::user());
}
So what this does: At every request it sends the logged in user to the view. Now you could say the controller could have an if statement to detect which text should be sent out but it's not really necessary.
In you element you could do that also.
So in your element put something like:
if($userIsLoggedIn) {
echo 'User is logged in.';
}else{
echo 'You are not logged in!';
}
Generally we move a bit more to helper to implement this kind of logic because they are classes which have more options for well styled coding. But it's also doable simply with an element.
So now you got the texts right. Then you get to the point: Does a static text belong to the element? No, it does not. So what would improve it is to implement it like:
if($userIsLoggedIn) {
echo __('User is logged in');
}else{
echo __('User is not logged in');
}
That way you can put the static texts into your .po files. If you don't know what they are:
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
The element can now be used also if your site becomes multi language for example. Or you could let your textwriter edit the texts without touching the source code.
As you see it's a different approach but I think it will give you more clear code. It decoupled the code, the controller does his task, the element does his task and the text is also seperated out because it doesn't belong hardcoded in the views.
In terms of code it's not much more so I would strongly advise some solution which looks like this. Could also be done with a helper.
Some sources on this kind of approaches:
http://en.wikipedia.org/wiki/Object-oriented_programming#Decoupling
http://en.wikipedia.org/wiki/Single_responsibility_principle

Categories