Categorising FlashMessenger messages in Zend Framework - zend-framework

What is the easiest way to categorise (warning, success, error) flash messages in Zend Framework using the FlashMessenger helper? I also want a single method to check for messages where the controller may not necessarily have forward the request on. At the moment, I believe this is done via FlashMessenger::getCurrentMessage()?

In you're controller you can do this :
$this->_helper->FlashMessenger(
array('error' => 'There was a problem with your form submission.')
);
$this->_helper->FlashMessenger(
array('notice' => 'Notice you forgot to input smth.')
);
In you're view you can echo the notice like this :
<?php echo $this->flashMessenger('notice'); ?>
And the error like this :
<?php echo $this->flashMessenger('error'); ?>
Edit:
Check this link :
... Calling the regular getMessages() method here won't work. This only returns messages which were stored in the appropriate ZendSession namespace when the FlashMessenger was instantiated. Since any messages added this request were not in the ZendSession namespace at that time (because the FlashMessenger was instantiated in order to add the messages) they won't be returned by getMessages().
For just this use-case, the FlashMessenger also provides a getCurrentMessages() method (and a related family of current methods) which returns those messages set on the current request.

Okay, thanks for everyone's input I have however implemented a different approach.
I already had a parent controller that extends Zend_Controller_Action where I've placed common logic across the application, so in the postDispatch() method I merged the getCurrentMessages and getMessages into a view variable.
public function postDispatch()
{
$messages = array_merge(
$this->_helper->flashMessenger->getCurrentMessages(),
$this->_helper->flashMessenger->getMessages()
);
$this->view->messages = count($messages) > 0 ? $messages[0] : array();
}
I set the message via a controller action like;
$this->_helper->flashMessenger(array('error'=>'This is an error'));
And in my layout file, I use a conditional on the $messages variable;
<?php if(count($this->messages) > 0) : ?>
//.. my HTML e.g. key($this->messages) returns 'error'
// current($this->messages) returns 'This is an error'
<?php endif; ?>
This works for me as the messages is categorised and can be obtained from the current request in addition to the next redirect.

Two ideas.
1. PHPPlaneta
Check out the source code of PHPlaneta by Robert Basic:
https://github.com/robertbasic/phpplaneta
He uses the standard FlashMessenger action helper:
$this->_helper->flashMessenger()->addMessage(array('fm-bad' => 'Error occurred')
Then defines a view helper called FlashMessenger so that he can access the messages. In his layout or view script, he simply calls:
<?php echo $this->flashMessenger(); ?>
The view helper uses the key (ex: 'fm-bad') to set up CSS styling for the output message.
2. PriorityMessenger
Check out the Priority Messenger view helper from Sean P. O. MacCath-Moran:
http://emanaton.com/code/php/zendprioritymessenger
The thing I like about this is that this whole business of saving messages for display on the next page load strikes me as something that should be completely within the view. So in your action, before your redirect, you populate the view helper with your messages and your priorities. Then, in your layout or view script, you output those messages with their priorities via the same view helper.

Related

Cakephp Controller isn´t processing form data

Hi I´m new with cakephp (v.1.3). I´m trying to do something simple.
I have two tables: fichas[id,... etc] and labos[id,laboratorio,ficha_id] so "labos" belongs to "fichas". (labos.laboratorio is ENUM field).
I would like to view a "ficha" given labos.id and labos.laboratorio so I´ve included the following code in "home.ctp"
<h3>Mostrar Ficha</h3>
<?php echo $this->Form->create('ficha',array('action'=>'localiza'));?>
<?php echo $this->Form->radio('laboratorio',array('A','B','C'),array('A','B','C')); ?>
<?php echo $this->Form->input('id',array('label'=>'Numero','type'=>'text')); ?>
<?php echo $this->Form->end("Mostrar");?>
Then in "fichas_controller.php" added the following:
function localiza(){
$laboratorio=$this->data['Ficha']['laboratorio'];
$id=$this->data['Ficha']['id'];
if(!$id){
$this->Session->setFlash('Por favor introduzca un valor valido');
$this->redirect(array('action'=>'index'));
}
$this->set('fichas',$this->Ficha->findID($id,$laboratorio));
}
Finally in the model "ficha.php" the following:
function findID($id=null,$laboratorio=null){
return $this->find('all',array('conditions'=>array('Labo.laboratorio'=>$laboratorio,'Labo.id'=>$id)));
}
Obviously the file views/fichas/localiza.ctp exists
The thing is when I press the submit button in the form it just reloads the home.ctp page. Looks like the controller´s code is not being executed because i´ve tried to force the error message that should load the index action changing the if condition to true but the same result. I´ve changed the name of the function in the model expecting an error to ocurr but I get the same result.
I have another two forms in the home.ctp page but calling another actions and models.
One of them its almost identical and it works fine.
I can´t figure out the error.
Thanks in advance for any help.
Marcelo.
The array key $this->data['Ficha'] likely doesn't exist. You've created the lowercase "ficha" form, this name should be capitalized, otherwise the data is available in $this->data['ficha']. So the form creation call would look like this:
<?php echo $this->Form->create('Ficha',array('action'=>'localiza'));?>
You can debug in two ways on Cake
Configure::write('debug', 2);
debug($this->data);
OR
The other PHP ways
print_r($this->data);
This way, you will know if you are passing the data->params properly.
Why is your model has first charcter in lower-case? It should be
Fichas
Labos
Then you can issue a direct find on the controller, if you only want.
$d = $this->Fichas->find('all', array();
You might have added the home.ctp file into another controller. Try adding the controller in the following line:
<?php echo $this->Form->create('ficha',array('controller' => 'fichas', 'action'=>'localiza'));?>
Hope it helps.

Best practice: Zend View: Load content from database and render PHP-code included in content

Let's say I load a value from a database which return something like:
<?php
//Zend_Controller_Action
public function indexAction()
{
$dbContent = "<p>Hello <?php echo $user?>!</p>";
$this->view->paragraph = $dbContent;
}
?>
How is it possible, that
<?php echo $user?>
will be rendered?
What precaution need to be taken (safety issuses, XXS)?
Thanks so much indeed!
== Edit: ==
Sorry, I obviously formulated my question misunderstandingly. What I actually ment:
I would like to avoid implementing a template engine like smarty.
In my project, there will be content that has PHP-Code within a string and that needs to be parsed.
Example:
<?php
//Zend_Controller_Action
public function indexAction()
{
$dbContent = "<p>Hello <?php echo $user?>!</p>";
$this->view->paragraph = $dbContent;
}
<?php
//viewscript.phtml
$user = 'John Doe';
echo $this->paragraph;
?>
is supposed to output:
Hello John Doe!
Is there any safe solution to do this without an external template engine?
Thanks once more... :-)
If found a solution here, which seems to perfectly fill my needs.
Thanks to all who answered here,
==UPDATE==
Unfortunately the posted link is dead. However, the solution was pretty simple. As far as i Remember, it went through the following steps:
Fetch content from database and save it in a file
Use Zend_Cache to check, whether this file exists
If file exists, simply render it. If not, go to step 1.
==UPDATE II ==
Found a copy of the page:
archive.org
In zend framework you will be always be able to print string (or whatever you want) from a controller but it's a very bad practice.
You should give the $user value from the controller to the view in this way:
$this->view->paragraph = $user;
and then, in the view, have:
<p>Hello <?php echo $this->paragraph; ?>!</p>
To ensure this code from XSS you should do some check before (before you print the value) like this:
$user = strip_tags($user);
Zend Framework doesn't support automatic output escaping , but you can prevent XSS in many ways.
First of all push all values into view layer and then print them with a View Helper like Zend\View\Escape , by default it returns string under htmlspecialchars() but you can set a callback function simple with :
//view.phtml
$this->setEscape('yourClass','methodName');
$this->setEscape('functionName');
echo $this->escape($this->myGreatDbValue);
Sure you can create your custom View Helper for all your need.
Another way is to create a custom View class extending Zend\View\Abstract , override __get() magic method and filtering output .
Read documentations for Zend View Helper and Zend Filter: http://framework.zend.com/manual/en/zend.filter.html
http://framework.zend.com/manual/en/zend.view.helpers.html

Zend framework - access controller or model from the view

I need to give the front-end designer the ability to choose whether or not to display a single xml feed or an mash-up, from the view.phtml file
This means I need to be able to call a method from the controller or model which then returns a variable to the view containing the requested feed(s).
So how do I access methods of the controller or model from the view?
you don't call controller methods in view , but you can create an instance of model (for read only purposes) inside view and then call its public methods .eg
Foo.phtml
<?php $feedsTb = new Default_Model_Feeds() ?>
<?php $allFeeds = $feedsTb->fetchAll(); ?>
I don't know if i got your problem right, but this is something i'd probably do in a way like
Controller:
if($this->_getParam('single')) {
$this->view->data = $model->getFeedSingleData();
$this->render('single_feed.phtml');
} else { //mashup
$this->view->data = $model->getMashUpData();
$this-render('mashup_feed.phtml');
}
Though admittedly an example like this is better off with two different actions (singleAction() and mashupAction())
But i really don't know if i got your problem figured out at all :S You may explain it further

passing values from model to view in CI

I have this library in CI that retrieves my latest twitter updates. It has a function that sends my latest updates as objects to my controller.
I would like to show these twitter updates on the footer of my page, so they're visible at all times.
Now my question is how I call these directly from a view? I know this is not a good practice in MVC but I don't see how else I could do this.
My controller currently takes care of all my different pages (it's a small website) and I don't think it's very good practice to call my twitter class at the end of every page-function in the controller and then send it through to the views.
Typycally I do this in my controller:
<?php
function index(){
$data['page'] = 'home';
//i don't want to call my twitter class here every single time I write a new page. (DRY?!)
$this->load->view('template', $data);
}
?>
And it loads the "template" view that looks like this:
<?php
$this->load->view('header');
$this->load->view('pages/'.$page);
$this->load->view('footer');
?>
So any suggestions how I should do this?
I have a helper library that takes a page Partial and wraps it in the master theme. You can use the optional parameter on your load->view to render to a string.
Then when you render your master page, you can load the twitter updates, and display them. Although, I highly suggest caching your twitter response for 5 minutes at least, will save you a LOT of overhead.
Example:
// Controller somwhere:
$content = $this->load->view('pages/'.$page, array(), true);
$this->myLibrary->masterPage($content);
// Your library:
function masterPage($content)
{
$twitterData = $this->twitter->loadStuff(); // whatever your function is
$twitter = $this->load->view('twitter_bar', array('data' => $twitterData), true);
$this->load->view('master', array('content' => $content, 'twitter' => $twitter);
}
An alternative approach is to use a base controller. All my controllers extend my custom base controller which holds things I need on every page, for example an object containing the current user.

Zend Framework's Action helper doesn't use a ViewRenderer

I'm trying to execute an action from the view using the Action helper like but although the action is been executed the output isn't displayed.
Here's part of my .phtml file:
<div id="active-users">
<?php echo $this->action('active', 'Users') ?>
</div>
The action works like this:
class UsersController extends Zend_Controller_Action
{
function activeAction()
{
$model = new UsersModel();
$this->view->users = $model->getActiveUsers();
}
}
And there's another .phtml file that renders the list of users. The action works fine when called directly from /users/active but doesn't display anything when called from inside another .phtml file.
I've tracked the problem to the ViewRenderer not been available when called with action() helper... or at least not working as usual (automatically rendering the default .phtml file).
The content is displayed if I explicitly render the view inside the action but I need the ViewRender behaviour because I don't control the code of some of the actions I need to use.
Is there anyway to turn the ViewRenderer on while using the action() view helper? I'm open to replace the action() view helper if needed.
I forgot: I'm using PHP 5.2.8, Zend Framework 1.7.5, Apache 2.2 on Windows Vista.
Thanks
i think you should asign the active users from the controller or if you want you can use singleton on the models an use the directly in the views
$this->view = UsersModel::instance()->getActiveUsers();
Are you using _forward() o redirect on your action? Actions that result in a _forward() or redirect are considered invalid, and will return an empty string.
Update: I test it, and it works, try writing 'users' instead of 'Users' in the controllers param.
<div id="active-users">
<?php echo $this->action('active', 'users') ?>
</div>