i have create a module and named: Custom_module by Developer Tools --> Module Builder
I trired to add "target lists" to Custom_module like module Campaign, but i can not find the way the do that
everyone can help you to find the best way to add "target lists" to my module.
thanks
You Just need to create a custom sub panel in your custom module.
target list is ProspectLists module.
Follow this link to create custom module.
http://shanedowling.com/sugarcrm-7-custom-subpanels
https://developer.sugarcrm.com/2015/05/18/creating-subpanels-with-custom-results-in-sugar-7-5/
1. Create a new link class
This should go into custom/modules//YourNewLink.php and this class will act as the custom functionality that will build your link between the two records.
<?php
/**
* Custom filtered link
*/
class YourNewLink extends Link2
{
/**
* DB
*
* #var DBManager
*/
protected $db;
public function __construct($linkName, $bean, $linkDef = false)
{
$this->focus = $bean;
$this->name = $linkName;
$this->db = DBManagerFactory::getInstance();
if (empty($linkDef)) {
$this->def = $bean->field_defs[$linkName];
} else {
$this->def = $linkDef;
}
}
/**
* Returns false if no relationship was found for this link
*
* #return bool
*/
public function loadedSuccesfully()
{
// this link always loads successfully
return true;
}
/**
* #see Link2::getRelatedModuleName()
*/
public function getRelatedModuleName()
{
return '<Your_Module>';
}
/**
*
* #see Link2::buildJoinSugarQuery()
*/
public function buildJoinSugarQuery($sugar_query, $options = array())
{
$joinParams = array('joinType' => isset($options['joinType']) ? $options['joinType'] : 'INNER');
$jta = 'active_other_invites';
if (!empty($options['joinTableAlias'])) {
$jta = $joinParams['alias'] = $options['joinTableAlias'];
}
$sugar_query->joinRaw($this->getCustomJoin($options), $joinParams);
return $sugar_query->join[$jta];
}
/**
* Builds main join subpanel
* #param string $params
* #return string JOIN clause
*/
protected function getCustomJoin($params = array())
{
$bean_id = $this->db->quoted($this->focus->id);
$sql = " INNER JOIN(";
$sql .= "SELECT id FROM accounts WHERE id={$bean_id}"; // This is essentially a select statement that will return a set of ids that you can match with the existing sugar_query
$sql .= ") accounts_result ON accounts_result.id = sugar_query_table.id";
return $sql;
}
2. Add a new vardef entry for the link field.
For this example, I'm going to create the custom link on the contacts module. So this code goes in custom/Extension/modules/Contacts/Ext/Vardefs/your_field_name.php
<?php
$dictionary["Contact"]["fields"]["your_field_name"] = array(
'name' => 'active_other_invites',
'type' => 'link',
'link_file' => 'custom/modules/<YourModule>/YourNewLink.php',
'link_class' => 'YourNewLink',
'source' => 'non-db',
'vname' => 'LBL_NEW_LINK',
'module' => '<YourModule>',
'link_type' => 'many',
'relationship' => '',
);
3. Add the new link as a subpanel
This goes under custom/Extension/modules/Contacts/Ext/clients/base/layouts/subpanels/your_subpanel_name.php
<?php
$viewdefs['Contacts']['base']['layout']['subpanels']['components'][] = array (
'layout' => 'subpanel',
'label' => 'LBL_NEW_LINK',
'context' =>
array (
'link' => 'your_field_name',
),
);
4. Add the label
Under custom/Extension/modules/Contacts/Ext/Language/en_us.new_link.php
<?php
$mod_strings['LBL_ACTIVE_OTHER_INVITES'] = 'Your New Link';
5. Quick Repair and Rebuild
I am new in Zend, my problem can be simple for you. I want to make a controller that displays form input data in another view. data are an email text and a text file uploaded. I created the index view and result view.
but i get nothing. when I replace the value of $email with text it works!! I can't find what is going wrong.
The controller also should display a sorted file by firstname
Id,Firstname,Lastname
5,John,Doe
6,Adam,Ant
7,Victor,Hugo
8,Britannie,Spears
this is my controller :
public function indexAction()
{
// initialzing of the customized form
$form = new Application_Form_Upload();
$rq = $this->getRequest();
$isForm = true; // the form has to be shown only if true
if ($rq->isPost()) {
if ($form->isValid($rq->getPost())) {
// show the uploaded data instead of the form
$isForm = false;
$this->view->data = new Application_Model_DataViewer();
$this->view->data->parseFromForm($form);
$result = new Zend_View();
$this->view->result= $result;
$this->render('result');
}
}
if ($isForm) {
$this->view->form = $form;}
}
this is my model :
class Application_Model_DataViewer
{
/**
* #var string Entered e-mail address
*/
private $email;
/**
* #var array Array of extracted data from uploaded file
*/
private $data;
public function __construct(){
$this->email=null;
$this->data=array();
}
/**
* Extracts the data from the form-object and saves it internally
* #param $form Application_Form_Upload
*/
public function parseFromForm($form){
if(!isset($form))return;
if(!isset($form->file)||!$form->file instanceof Zend_Form_Element_File){
throw new Zend_Exception('The field File is empty or has wrong type');
}
// for validation of the IDs
$ival = new Zend_Validate_Int();
// reading the CSV-file (values should be separated by comma, if not - should be extended)
if(($fp = #fopen($form->file->getFileName(), 'r')) !== false){
while(($data = fgetcsv($fp, 500, ',')) !== false){
if(
!is_array($data)
||!$ival->isValid($data[0])
||count($data)<3
)continue;
$this->data[$data[1]] = $data;
}
}else{return;}
#fclose($fp);
ksort($this->data);
$this->email = $form->getValue('email');
}
/**
* #return null|string
*/
public function getEmail(){
return $this->email;
}
/**
* #return array
*/
public function getData(){
return $this->data;
}
}
and here is my index and result views
<?php
// the form should only be rendered if form must be shown
if(isset($this->form)){
$this->form->setAction($this->url());
echo $this->form;
}
?>
result view:
<?php
// if the required data is submitted, it will be checked and displayed
if(isset($this->data)){
?>
<p>Thank you <strong><?php echo $this->escape($this->data->getEmail()); ?></strong>.</p>
<p>The result of the sorting is:
<?php
foreach($this->data->getData() as $row){
echo '<div>', $this->escape($row[0]), ',',
$this->escape($row[1]), ',',
$this->escape($row[2]), '</div>';
}
?></p><?php
}
?>
Use the partial helper in the view.
See: http://framework.zend.com/manual/2.2/en/modules/zend.view.helpers.partial.html
eg. your index.phtml
if ($this->data) {
echo $this->partial("result.phtml", array("data" => $this->data->getData()));
}
you can access the variable in result.phtml by $this->data
I downloaded the Editable combo box control with Auto-complete and added the extension. I am having problem with patient_id and problem_definition_id attributes of the model. Works fine for problem_duration_id and some other attributes. When I use them for the combo box I receive the following error:
Following is the code that i have used in my view:
$this->widget('ext.combobox.EJuiComboBox', array(
'model' => $PatientProblem,
'attribute' => 'problem_definition_id',
'id'=>'eeed',
'data'=>Yii::app()->cache->get('PATIENT_PROBLEM'),
// options passed to plugin
'assoc'=>true,
'options' => array(
'allowText' => false,),
// Options passed to the text input
'htmlOptions' => array('size' => 6),
));
Following is the my model:
<?php
/**
* This is the model class for table "patient_problem".
*
* The followings are the available columns in table 'patient_problem':
* #property integer $problem_id
* #property integer $problem_definition_id
* #property integer $patient_id
* #property integer $curr_or_history
* #property integer $patient_visit_id
* #property string $problem_notes
* #property string $chronic
* #property string $alert_on_dashboard
* #property integer $problem_duration_id
* #property integer $create_acc_id
* #property integer $create_user_id
* #property string $create_date
* #property integer $create_acc_assign_id
* #property integer $update_acc_id
* #property integer $update_user_id
* #property string $update_date
* #property integer $update_acc_assign_id
*
* The followings are the available model relations:
* #property Patient $patient
* #property ListOfValues $currOrHistory
* #property PatientVisit $patientVisit
* #property ListOfValues $problemDefinition
* #property ListOfValues $problemDuration
*/
class PatientProblem extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #param string $className active record class name.
* #return PatientProblem the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'patient_problem';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_duration_id, create_acc_id, create_user_id, create_acc_assign_id, update_acc_id, update_user_id, update_acc_assign_id', 'numerical', 'integerOnly'=>true),
array('chronic, alert_on_dashboard', 'length', 'max'=>1),
array('problem_notes, problem_reported_date, create_date, update_date', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('problem_id, problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_notes, problem_reported_date, chronic, alert_on_dashboard, problem_duration_id, create_acc_id, create_user_id, create_date, create_acc_assign_id, update_acc_id, update_user_id, update_date, update_acc_assign_id', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'patient' => array(self::BELONGS_TO, 'Patient', 'patient_id'),
'currOrHistory' => array(self::BELONGS_TO, 'ListOfValues', 'curr_or_history'),
'patientVisit' => array(self::BELONGS_TO, 'PatientVisit', 'patient_visit_id'),
'problemDefinition' => array(self::BELONGS_TO, 'ListOfValues', 'problem_definition_id'),
'problemDuration' => array(self::BELONGS_TO, 'ListOfValues', 'problem_duration_id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'problem_id' => 'Problem',
'problem_definition_id' => 'Problem Definition',
'patient_id' => 'Patient',
'curr_or_history' => 'Curr Or History',
'patient_visit_id' => 'Patient Visit',
'problem_notes' => 'Problem Notes',
'problem_reported_date'=>'Report Date',
'chronic' => 'Chronic',
'alert_on_dashboard' => 'Alert On Dashboard',
'problem_duration_id' => 'Problem Duration',
'create_acc_id' => 'Create Acc',
'create_user_id' => 'Create User',
'create_date' => 'Create Date',
'create_acc_assign_id' => 'Create Acc Assign',
'update_acc_id' => 'Update Acc',
'update_user_id' => 'Update User',
'update_date' => 'Update Date',
'update_acc_assign_id' => 'Update Acc Assign',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('problem_id',$this->problem_id);
$criteria->compare('problem_definition_id',$this->problem_definition_id);
$criteria->compare('patient_id',$this->patient_id);
$criteria->compare('curr_or_history',$this->curr_or_history);
$criteria->compare('patient_visit_id',$this->patient_visit_id);
$criteria->compare('problem_notes',$this->problem_notes,true);
$criteria->compare('problem_reported_date',$this->problem_reported_date,true);
$criteria->compare('chronic',$this->chronic,true);
$criteria->compare('alert_on_dashboard',$this->alert_on_dashboard,true);
$criteria->compare('problem_duration_id',$this->problem_duration_id);
$criteria->compare('create_acc_id',$this->create_acc_id);
$criteria->compare('create_user_id',$this->create_user_id);
$criteria->compare('create_date',$this->create_date,true);
$criteria->compare('create_acc_assign_id',$this->create_acc_assign_id);
$criteria->compare('update_acc_id',$this->update_acc_id);
$criteria->compare('update_user_id',$this->update_user_id);
$criteria->compare('update_date',$this->update_date,true);
$criteria->compare('update_acc_assign_id',$this->update_acc_assign_id);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/* The code till this line is Gii generated. All the code beyond this point is cutom code. */
public function beforeSave(){
$retval=false;
if ($this->isNewRecord){
//Handling duplicate Entries for Problem in one visit.
$criteria = new CDbCriteria;
$criteria->compare('problem_definition_id', $this->problem_definition_id);
$criteria->compare('patient_id', $this->patient_id);
$criteria->compare('patient_visit_id', $this->patient_visit_id);
$PatientProblem = $this->model()->findAll($criteria);
if (count($PatientProblem)==0){
$retval=true;
$this->setAttribute('create_date',date("Y-m-d H:i:s"));
$this->setAttribute('create_user_id',Yii::app()->user->id);
$this->setAttribute('create_acc_id',Yii::app()->user->assigner_account_id);
$this->setAttribute('create_acc_assign_id',Yii::app()->user->acc_assign_id);
}
else{
$errorMsg='';
$criteria = new CDbCriteria;
$criteria->compare('mCode','VISIT_PROBLEM_EXISTS');
$criteria->compare('mLang',Yii::app()->user->account_lang);
$SysMsgs=SystemMessages::model()->findAll($criteria);
if (count($SysMsgs)>0){
$errorMsg='"'.$this->problemDefinition->group_display_val.'"'.$SysMsgs[0]->mDesc.' Code['.$SysMsgs[0]->mId.']';
}
else{
$errorMsg=$this->problemDefinition->group_display_val.' already recorded.';
}
throw new Exception($errorMsg);
$retval=false;
}
}
else{
$this->setAttribute('update_date',date("Y-m-d H:i:s"));
$this->setAttribute('update_user_id',Yii::app()->user->id);
$this->setAttribute('update_acc_id',Yii::app()->user->assigner_account_id);
$this->setAttribute('update_acc_assign_id',Yii::app()->user->acc_assign_id);
$retval=true;
}
return $retval;
}
public function getProb_def_id(){
return $this->problem_definition_id;
}
public function setProb_def_id($val){
$this->problem_definition_id=$val;
}
public function getProblemFlaged(){
return $this->alert_on_dashboard=='1' ? CHtml::image(Yii::app()->baseUrl .'/images/Flagredicon.png') : '';
}
public function getProblemFlagSrc(){
return $this->alert_on_dashboard=='1' ? Yii::app()->baseUrl .'/images/Flagredicon.png' :'';
}
public function getProblemChronic(){
return $this->chronic=='1' ? CHtml::image(Yii::app()->baseUrl .'/images/tickedS.jpg') : '';
}
public function getProblemDel(){
return ' <a class="delete" title="Delete" onclick="DeletePatProblem('.$this->problem_id.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/delete.png" alt="Delete" /></a> <a class="delete" title="Update" onclick="UpdatePatProblem(this,'.$this->problem_id.','.$this->problem_definition_id.','.$this->curr_or_history.',\''.$this->problem_notes.'\','.$this->problem_duration_id.','.$this->chronic.','.$this->alert_on_dashboard.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/update.png" alt="Update" /></a>';
}
}
Following is the code of EJuiComboBox.php
<?php
/**
* jQuery combobox Yii extension
*
* Allows selecting a value from a dropdown list or entering in text.
* Also works as an autocomplete for items in the select.
*
* #copyright © Digitick <www.digitick.net> 2011
* #license GNU Lesser General Public License v3.0
* #author Ianaré Sévi
* #author Jacques Basseck
*
*/
Yii::import('zii.widgets.jui.CJuiInputWidget');
/**
* Base class.
*/
class EJuiComboBox extends CJuiInputWidget
{
/**
* #var array the entries that the autocomplete should choose from.
*/
public $data = array();
public $assoc;
/**
* #var string A jQuery selector used to apply the widget to the element(s).
* Use this to have the elements keep their binding when the DOM is manipulated
* by Javascript, ie ajax calls or cloning.
* Can also be useful when there are several elements that share the same settings,
* to cut down on the amount of JS injected into the HTML.
*/
public $scriptSelector;
public $defaultOptions = array('allowText' => true);
protected function setSelector($id, $script, $event=null)
{
if ($this->scriptSelector) {
if (!$event)
$event = 'focusin';
$js = "jQuery('body').delegate('{$this->scriptSelector}','{$event}',function(e){\$(this).{$script}});";
$id = $this->scriptSelector;
}
else
$js = "jQuery('#{$id}').{$script}";
return array($id, $js);
}
public function init()
{
$cs = Yii::app()->getClientScript();
$assets = Yii::app()->getAssetManager()->publish(dirname(__FILE__) . '/assets');
$cs->registerScriptFile($assets . '/jquery.ui.widget.min.js');
$cs->registerScriptFile($assets . '/jquery.ui.combobox.js');
parent::init();
}
/**
* Run this widget.
* This method registers necessary javascript and renders the needed HTML code.
*/
/*
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
$data = array_combine($this->data, $this->data);
array_unshift($data, null);
}
else
$data = array();
echo CHtml::dropDownList(null, null, $data, array('id' => $id . '_select'));
if ($this->hasModel())
echo CHtml::activeTextField($this->model, $this->attribute, $this->htmlOptions);
else
echo CHtml::textField($name, $this->value, $this->htmlOptions);
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id, $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
*/
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
//if $data is not an assoc array make each value its key
if($this->assoc){
$data=$this->data;
}
else{
$data=array_combine($this->data, $this->data);
}
//does the same as array_unshift($data,null) but does not break assoc arrays
$data=array(""=>"")+$data;
}
else
$data = array();
if ($this->hasModel())
echo CHtml::activeDropDownList($this->model,$this->attribute,$data);
else
echo CHtml::dropDownList($name, $this->value, $data);
echo CHtml::textField(null,($this->hasModel()?($data[$this->model->{$this->attribute}]):$data[$this->value]),array('id'=>$id.'_combobox'));
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id.'_combobox', $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
}
Any help would greatly appreciated.
I used to have the same error for EJuiComboBox, too. It happens whenever NO DATA is found to feed the Textfield in the combobox, it is a PHP Error.. I made the following change to the run method of EJuiComboBox to stop it from throwing this PHP error when no data is found
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
//if $data is not an assoc array make each value its key
$data=($this->assoc)?$this->data:array_combine($this->data, $this->data);
//does the same as array_unshift($data,null) but does not break assoc arrays
$data=array(""=>"")+$data;
}
else
$data = array();
if ($data == array()) {
echo "No hay registros";
return;
}
if ($this->hasModel())
echo CHtml::activeDropDownList($this->model,$this->attribute,$data,$this->selectHtmlOptions);
else
echo CHtml::dropDownList($name, $this->value, $data,$this->selectHtmlOptions);
echo CHtml::textField(null,($this->hasModel()?($data[$this->model->{$this->attribute}]):$data[$this->value]),array('id'=>$id.'_combobox'));
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id.'_combobox', $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
Using this method will result in a simple rendering of "No data found!" whenever there are No members in the data for the ComboBox.
I solved the problem. By default, Yii gets the Not Null attribute of a column during runtime from the database, so if a column is marked as Not Null in database, it applies zero (0) as its default value. When "$this->model->{$this->attribute}" was getting executed, it was putting "0" instead of "problem_definition_id" which was throwing error. After making the column to Nullable in database, the error vanished. But since this does not seem a good solution. So after I created the $PatientProblem object, I explicitly set the problem_definition_id to null and it resolved the error.
I develop new type, but I don't know how I can test it.
Assert annotation is not load and validations is not called.
Could any one please help me?
class BarcodeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->
add('price');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Bundles\MyBundle\Form\Model\Barcode',
'intention' => 'enable_barcode',
));
}
public function getName()
{
return 'enable_barcode';
}
}
A have following model for storing form data.
namepspace Bundles\MyBundle\Form\Model;
class Barcode
{
/**
* #Assert\Range(
* min = "100",
* max = "100000",
* minMessage = "...",
* maxMessage = "..."
* )
*/
public $price;
}
I develop some test like this, the form didn't get valid data but it is valid! (Because annotation is not applied)
I try adding ValidatorExtension but I dont know how can I set constructor paramaters
function test...()
{
$field = $this->factory->createNamed('name', 'barcode');
$field->bind(
array(
'price' => 'hello',
));
$data = $field->getData();
$this->assertTrue($field->isValid()); // Must not be valid
}
Not sure why you need to unit-test the form. Cant You unit test validation of Your entity and cover controller with your expected output?
While testing validation of entity You could use something like this:
public function testIncorrectValuesOfUsernameWhileCallingValidation()
{
$v = \Symfony\Component\Validator\ValidatorFactory::buildDefault();
$validator = $v->getValidator();
$not_valid = array(
'as', '1234567890_234567890_234567890_234567890_dadadwadwad231',
"tab\t", "newline\n",
"Iñtërnâtiônàlizætiøn hasn't happened to ", 'trśżź',
'semicolon;', 'quote"', 'tick\'', 'backtick`', 'percent%', 'plus+', 'space ', 'mich #l'
);
foreach ($not_valid as $key) {
$violations = $validator->validatePropertyValue("\Brillante\SampleBundle\Entity\User", "username", $key);
$this->assertGreaterThan(0, count($violations) ,"dissalow username to be ($key)");
}
}
Functional test. Given that you generate a CRUD with app/console doctrine:generate:crud with routing=/ss/barcode, and given that maxMessage="Too high" you can:
class BarcodeControllerTest extends WebTestCase
{
public function testValidator()
{
$client = static::createClient();
$crawler = $client->request('GET', '/ss/barcode/new');
$this->assertTrue(200 === $client->getResponse()->getStatusCode());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'ss_bundle_eavbundle_barcodetype[price]' => '12',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertTrue($crawler->filter('td:contains("12")')->count() > 0);
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
/* force validator response: */
$form = $crawler->selectButton('Edit')->form(array(
'ss_bundle_eavbundle_barcodetype[price]' => '1002',
));
$crawler = $client->submit($form);
// Check the element contains the maxMessage:
$this->assertTrue($crawler->filter('ul li:contains("Too high")')->count() > 0);
}
}
Include this line must be in Model and try it after include look like your model.
/* Include the required validators */
use Symfony\Component\Validator\Constraints as Assert;
namespace Bundles\MyBundle\Form\Model;
class Barcode
{
/**
* #Assert\Range(
* min = "100",
* max = "100000",
* minMessage = "min message here",
* maxMessage = "max message here"
* )
*/
public $price;
}
i wonder if many of my pages may use a FlashMessenger, whats the best way to automatically render out all messages say at the top of the page (like those here in SO, telling the user they got a badge etc)
I have this view helper:
<?php
class Zf_View_Helper_FlashMessenger extends Zend_View_Helper_Abstract
{
/**
* #var Zend_Controller_Action_Helper_FlashMessenger
*/
private $_flashMessenger = null;
/**
* Display Flash Messages.
*
* #param string $key Message level for string messages
* #param string $template Format string for message output
* #return string Flash messages formatted for output
*/
public function flashMessenger($key = 'success',
$template='<div id="flash-message" style="display:none"><p class="%s">%s</p></div>')
{
$flashMessenger = $this->_getFlashMessenger();
//get messages from previous requests
$messages = $flashMessenger->getMessages();
//add any messages from this request
if ($flashMessenger->hasCurrentMessages()) {
$messages = array_merge(
$messages,
$flashMessenger->getCurrentMessages()
);
//we don't need to display them twice.
$flashMessenger->clearCurrentMessages();
}
//initialise return string
$output ='';
//process messages
foreach ($messages as $message)
{
if (is_array($message)) {
list($key,$message) = each($message);
}
$output .= sprintf($template,$key,$message);
}
return $output;
}
/**
* Lazily fetches FlashMessenger Instance.
*
* #return Zend_Controller_Action_Helper_FlashMessenger
*/
public function _getFlashMessenger()
{
if (null === $this->_flashMessenger) {
$this->_flashMessenger =
Zend_Controller_Action_HelperBroker::getStaticHelper(
'FlashMessenger');
}
return $this->_flashMessenger;
}
}
In my controller I have this:
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->add($formData);
$this->_helper->flashMessenger('The category has been inserted.');
$this->_helper->redirector('list');
}
So, in my view I just echo the helper:
<?php echo $this->flashMessenger(); ?>
You could use a preDispatch-Plugin to inject the content of the FlashMessenger into your view and output it in your layout template.