I have been using this documentation (the only one I can find on the web) to build a component:
http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Introduction
I can understand it to a certain extent, however it does really lack any definition. The component I have created works to a degree, though I am having some wier problems.
Basically all I need the component to do is simply load a settings area to set a few values, and through it be able to change those values. Here is a breakdown of what I have:
A view for a form, loading in form data from database.
toolbars setup for save/apply and cancel.
This loads with no errors, and according to all docs on joomla I have found, by initializing a JControllerForm instance with a JTable connected in the model, simple saving of forms should work automatically. However even though there is absolutely no reference anywhere in the code to a view with an s at the end (main view is tireapi, the forms always redirects to tireapis).
This brings up a 500 error, as there is no place set that has that view. The documentation does include a list for a view, however I have only one row I need to edit, so a list is pointless. I know parameters can be set to components rather then making a database field, however I am unable to find any documentation relating to it.
What I am looking for is direction on how to stop the component from redirecting to a none existent view, and properly save the data. Links to documentation that not only shows example code, but describes functions and how they work would be beneficial.
Here is some of the code, feel free to point out anything I might be completely overlooking (I am newer to creating components):
tireapi.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import joomla controller library
jimport('joomla.application.component.controller');
// Get an instance of the controller prefixed by TireAPI
$controller = JController::getInstance('TireAPI');
// Get the task
$jinput = JFactory::getApplication()->input;
$task = $jinput->get('task', "", 'STR' );
// Perform the Request task
$controller->execute($task);
// Redirect if set by the controller
$controller->redirect();
?>
controller.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controller library
jimport('joomla.application.component.controller');
class TireAPIController extends JController{
function display($cachable = false){
// set default view if not set
$input = JFactory::getApplication()->input;
$input->set('view', $input->getCmd('view', 'TireAPI'));
// call parent behavior
parent::display($cachable);
}
}
?>
controllers/tireapi.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controllerform library
jimport('joomla.application.component.controllerform');
class TireAPIControllerTireAPI extends JControllerForm{}
?>
models/tireapi.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import the Joomla modellist library
jimport('joomla.application.component.modeladmin');
class TireAPIModelTireAPI extends JModelAdmin{
protected $settings; //define settings
public function getTable($type = 'TireAPI', $prefix = 'TireAPITable', $config = array()){
return JTable::getInstance($type, $prefix, $config);
}
public function getSettings(){ //grab settings from database
if(!isset($this->settings)){
$table = $this->getTable();
$table->load(1);
$this->settings = $table;
}
return $this->settings;
}
public function getForm($data = array(), $loadData = true){
// Get the form.
$form = $this->loadForm('com_tireapi.tireapi', 'tireapi',
array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)){
return false;
}
return $form;
}
protected function loadFormData(){
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_tireapi.edit.tireapi.data', array());
if (empty($data)){
$data = $this->getSettings();
}
return $data;
}
}
?>
tables/tireapi.php:
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
// import Joomla table library
jimport('joomla.database.table');
class TireAPITableTireAPI extends JTable
{
function __construct( &$db ) {
parent::__construct('#__tireapi', 'id', $db);
}
}
?>
views/tireapi/view.html.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
class TireAPIViewTireAPI extends JView{
function display($tpl = null){
$form = $this->get('Form');
$item = $this->get('Settings');
// Check for errors.
if(count($errors = $this->get('Errors'))){
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Assign data to the view
$this->item = $item;
$this->form = $form;
$this->addToolBar();
// Display the template
parent::display($tpl);
}
protected function addToolBar() {
$input = JFactory::getApplication()->input;
JToolBarHelper::title(JText::_('COM_TIREAPI_MANAGER_TIREAPIS'));
JToolBarHelper::apply('tireapi.apply');
JToolBarHelper::save('tireapi.save');
JToolBarHelper::cancel('tireapi.cancel');
}
}
?>
views/tireapi/tmpl/default.php:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_tireapi&layout=edit&id='.(int) $this->item->id); ?>"
method="post" name="adminForm" id="tireapi-form">
<fieldset class="adminform">
<legend><?php echo JText::_( 'COM_TIREAPI_DETAILS' ); ?></legend>
<ul class="adminformlist">
<?php foreach($this->form->getFieldset() as $field): ?>
<li><?php echo $field->label;echo $field->input;?></li>
<?php endforeach; ?>
</ul>
</fieldset>
<div>
<input type="hidden" name="task" value="tireapi.edit" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
These are all the files I can think of that may matter, let me know if I should include anymore.
UPDATE:
Now I can get the redirect problem to stop, however it will not save data.
I get this error:
You are not permitted to use that link to directly access that page (#1).
This is the last hurdle to get this extremely basic admin feature to work. Any ideas?
To clarify, I set the forms though an xml file and that loads properly, even filling them with the proper data from database. However when I click "apply" it just directs me back to the form with the error listed above, without saving.
The main question that you left open is where do you want it to redirect? Joomla by default redirects to the list view (by adding an 's' to the view name unless you specify a list view directly).
You can override this in a couple of ways:
In your controller (controllers/tireapi.php), set your own list view. I think you can even make this the same view:
function __construct() {
$this->view_list = 'tireapi';
parent::__construct();
}
Override the save function to change the redirect that happens after save (again in the controller). This works by changing the redirect that happens naturally to something else:
public function save($key = null, $urlVar = null) {
$return = parent::save($key, $urlVar);
$this->setRedirect(JRoute::_('index.php?option=com_tireapi&view=tireapi'));
return $return;
}
One of those should do the trick for you.
** UPDATE
To get the item to checkout initially you will want to change how your component handles no view being set. Right now you just set the view, instead, let's redirect! Updated controller.php is below.
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controller library
jimport('joomla.application.component.controller');
class TireAPIController extends JController{
function display($cachable = false){
// set default view if not set
$input = JFactory::getApplication()->input;
$view = $input->get('view');
if (!$view) {
JFactory::getApplication()->redirect('index.php?option=com_tireapi&task=tireapi.edit&id=1');
exit();
}
// call parent behavior
parent::display($cachable);
}
}
?>
NOTE: This will work really poorly if more than one person needs to edit this, since the system checks it out when you open the component if you also have it redirect back to this page after saving. Because then it will always be checked out to the last person that edited it so the next person won't be able to open it. If only one person edits it, it will be fine.
SECOND NOTE: If you don't want to hack the checkout system you can also ignore it during the save process, which is basically the same level of hacking.
Below is a copy of the save function from controllerform.php in libraries/joomla/application/component/. This is what is running on save normally (because of where you inherit from. I have removed the check if the item is checked out. So if you put this in your tireapi.php controller where the parent::save... bit is, it will run instead and you don't have to bother with checking the item out (i.e. ignore all the comments...). (Honestly, in your case, you can probably delete a lot more of this, but this is what is happening on save, btw!)
public function save($key = null, $urlVar = null)
{
// Check for request forgeries.
JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
// Initialise variables.
$app = JFactory::getApplication();
$lang = JFactory::getLanguage();
$model = $this->getModel();
$table = $model->getTable();
$data = JRequest::getVar('jform', array(), 'post', 'array');
$checkin = property_exists($table, 'checked_out');
$context = "$this->option.edit.$this->context";
$task = $this->getTask();
// Determine the name of the primary key for the data.
if (empty($key))
{
$key = $table->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary key.
if (empty($urlVar))
{
$urlVar = $key;
}
$recordId = JRequest::getInt($urlVar);
// Populate the row id from the session.
$data[$key] = $recordId;
// The save2copy task needs to be handled slightly differently.
if ($task == 'save2copy')
{
// Check-in the original row.
if ($checkin && $model->checkin($data[$key]) === false)
{
// Check-in failed. Go back to the item and display a notice.
$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
// Reset the ID and then treat the request as for Apply.
$data[$key] = 0;
$task = 'apply';
}
// Access check.
if (!$this->allowSave($data, $key))
{
$this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
return false;
}
// Validate the posted data.
// Sometimes the form needs some posted data, such as for plugins and modules.
$form = $model->getForm($data, false);
if (!$form)
{
$app->enqueueMessage($model->getError(), 'error');
return false;
}
// Test whether the data is valid.
$validData = $model->validate($form, $data);
// Check for validation errors.
if ($validData === false)
{
// Get the validation messages.
$errors = $model->getErrors();
// Push up to three validation messages out to the user.
for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
{
if ($errors[$i] instanceof Exception)
{
$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
}
else
{
$app->enqueueMessage($errors[$i], 'warning');
}
}
// Save the data in the session.
$app->setUserState($context . '.data', $data);
// Redirect back to the edit screen.
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
// Attempt to save the data.
if (!$model->save($validData))
{
// Save the data in the session.
$app->setUserState($context . '.data', $validData);
// Redirect back to the edit screen.
$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
// Save succeeded, so check-in the record.
if ($checkin && $model->checkin($validData[$key]) === false)
{
// Save the data in the session.
$app->setUserState($context . '.data', $validData);
// Check-in failed, so go back to the record and display a notice.
$this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()));
$this->setMessage($this->getError(), 'error');
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
return false;
}
$this->setMessage(
JText::_(
($lang->hasKey($this->text_prefix . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS')
? $this->text_prefix
: 'JLIB_APPLICATION') . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS'
)
);
// Redirect the user and adjust session state based on the chosen task.
switch ($task)
{
case 'apply':
// Set the record data in the session.
$recordId = $model->getState($this->context . '.id');
$this->holdEditId($context, $recordId);
$app->setUserState($context . '.data', null);
$model->checkout($recordId);
// Redirect back to the edit screen.
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend($recordId, $urlVar), false
)
);
break;
case 'save2new':
// Clear the record id and data from the session.
$this->releaseEditId($context, $recordId);
$app->setUserState($context . '.data', null);
// Redirect back to the edit screen.
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_item
. $this->getRedirectToItemAppend(null, $urlVar), false
)
);
break;
default:
// Clear the record id and data from the session.
$this->releaseEditId($context, $recordId);
$app->setUserState($context . '.data', null);
// Redirect to the list screen.
$this->setRedirect(
JRoute::_(
'index.php?option=' . $this->option . '&view=' . $this->view_list
. $this->getRedirectToListAppend(), false
)
);
break;
}
// Invoke the postSave method to allow for the child class to access the model.
$this->postSaveHook($model, $validData);
return true;
}
This is not a real answer but your question is also not a real question (I had to read it 3 times).
The thing with the plural "s" (for tireapis) is what Joomla! does automatically. You can override that.
I suggest that you take a look at the core components (like com_banners).
What you need to do is to avoid the redirect. You should have only the "Save" button, that should keep you on the same page. While "Save & Close" redirects you to the plural page.
Related
I want to show filter of category on submenu, my code works!!
My problem is that if page are already filtered, my code does not return the options
I believe it has to do something in the code that bypasses the filter page and again bring the options in the submenu even if already have the filter on page
HTML of submenu:
{{block type="core/template" category="3" template="page/html/icons_submenu.phtml"}}
Content of page icons_submenu.phtml:
<?php
$layer = Mage::getModel("catalog/layer");
$category = Mage::getModel('catalog/category')->load($this->getCategory());
$layer->setCurrentCategory($category);
$attributes = $layer->getFilterableAttributes();
foreach ($attributes as $attribute) {
if ($attribute->getAttributeCode() == 'color') {
$filterBlockName = 'catalog/layer_filter_attribute';
$result = Mage::app()->getLayout()->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();
echo '<strong>Color:</strong><br />';
foreach($result->getItems() as $option) {
echo ' ' . $option->getValue() . ' - ' . $option->getLabel() . '<br />';
}
}
}
?>
Example:
I would really suggest you to actually move all that logic into a proper module, a proper block and a proper model and not in a template like you are doing right now.
If you actually want further help for that, feel free to ask, making something according to the coding guide lines of Magento would make you even happier of your job, I can assure you.
This being said, what you actually want is a current filter model based on the current category and a specify attribute.
You don't need to go by the block catalog/layer_filter_attribute in a way to do this, you can directly go by the model based on the layer you already load.
So, this way of doing it should work, although it should not be in a template or view, once again :
<?php
$category = Mage::getModel('catalog/category')
->load($this->getCategory());
$layer = Mage::getModel('catalog/layer')
->setCurrentCategory($category);
$attributes = $layer->getFilterableAttributes();
foreach ($attributes as $attribute) {
if ($attribute->getAttributeCode() == 'color') {
// $filterBlockName = 'catalog/layer_filter_attribute';
/** This is actually your only problem in your code **/
// $result = Mage::app()->getLayout()->createBlock($filterBlockName)->setLayer($layer)->setAttributeModel($attribute)->init();
/** But would work with this line **/
$result = Mage::getModel('catalog/layer_filter_attribute')
->setLayer($layer)
->setAttributeModel($attribute);
echo '<strong>Color:</strong><br />';
foreach($result->getItems() as $option) {
echo ' ' . $option->getValue() . ' - ' . $option->getLabel() . '<br />';
}
}
}
?>
Then you can see it still works based on only the colours I have in the current category
But also when the category is already filtered on a specific colour
i am developing an application where i need some suggestions. Here is the detail of the problem.
public function form()
{
$this->load->helper('inflector');
$id = $this->uri->segment(3,0);
if($data = $this->input->post()){
$result = $this->form_validation->run();
if($result){
if($id > 0){
// here update code
}else{
$this->mymodel->insert($data);
$this->session->set_flashdata('message','The page has been added successfully.');
$this->redirect = "mycontroller/index";
$this->view = FALSE;
}
}else{
//$this->call_post($data);
$this->session->set_flashdata('message','The Red fields are required');
$this->view = FALSE;
$this->redirect = "mycontroller/form/$id";
}
}else{
$row = $this->mymodel->fetch_row($id);
$this->data[]= $row;
}
}
public function _remap($method, $parameters)
{
if (method_exists($this, $method))
{
$return = call_user_func_array(array($this, $method),$parameters);
}else{
show_404();
}
if(strlen($this->view) > 0)
{
$this->template->build('default',array());
}else{
redirect($this->redirect);
}
}
Here you can see how i am trying to reload the page on failed validation.
Now the problem is that i have to display the flash data on the view form which is only available after redirect and i need to display the validation errors to which are not being displayed on redirect due to the loss of post variable. If i dont use redirect then cant display flashdata but only validation errors. I want both of the functionalities togather. I have tried even creating POSt again like this
public function call_post($data)
{
foreach($data as $key => $row){
$_POST[$key] = $row;
}
}
Which i commented out in the formmethod.How can i achieve this.
Here's a thought.
I think you can add the validation error messages into the flash data. Something like this should work:
$this->session->set_flashdata('validation_error_messages',validation_errors());
Notice the call to the validation_errors function. This is a bit unconventional, but I think it should work. Just make sure that the code are executed after the statement $this->form_validation->run(); to make sure the validation error messages are produced by the Form Validation library.
well i have little different approach hope will help you here it is
mycontroller extend CI_Controller{
function _remap($method,$params){
switch($method){
case 'form':
$this->form($params);
break;
default:
$this->index();
break;
}
}
function form(){
$this->load->helper('inflector');
$id = $this->uri->segment(3,0);
$this->form_validation->set_rules('name','Named','required|trim');
$this->form_validation->set_rules('email','email','required|valid_email|trim');
// if validation fails and also for first time form called
if(!$this->form_validation->run()){
$this->template->build('default',array());
}
else{ // validation passed
$this->save($id)
}
}
function save($id = 0){
$data = $this->input->post();
if($id == 0){
$this->mymodel->insert($data);
$this->session->set_flashdata('message','The page has been added successfully.');
$this->redirect = "mycontroller/index";
$this->view = FALSE;
}else{
// update the field
$this->session->set_flashdata('message','The Red fields are required');
}
redirect("mycontroller/index");
}
}
your form/default view should be like this
<?
if(validation_errors())
echo validation_errors();
elseif($this->session->flashdata('message'))
echo $this->session->flashdata('message');
echo form_open(uri_string());// post data to same url
echo form_input('name',set_value('name'));
echo form_input('email',set_value('email'));
echo form_submit('submit');
echo form_close();
try it if you face any problem post here.
I am using pre-controller hook codeigniter in my project
Description:
we are using subdomain concept and three templates(theme). eg: My site is xyz.com. this is having one first template.
some business signup with this xyz site. for eg. abc(business). We create abc.xyz.com. abc chooses 2 template. abc.xyz.com in browser need to show 2nd template. It is not showing 2nd template. it is showing only 1st template.
When we clicked any link on the site more than once , then the template 2 is set for abc.xyz.com link.
I am using codeigniter. loaded session, database in autoload files.
I used precontroller hook to check whether the url is xyz or any subdomain abc.xyz.com
In hook i am setting template if the url is subdomain one.
But template is not showing when abc.xyz.com is in browser. when i refresh the url for some clicks or clicked any of the header link some count , it showing the actual template of the business abc.
Please help me to fix this issue or provide me some solution .
<?php
class Subdomain_check extends CI_Controller{
public function __construct(){
parent::__construct();
$this->CI =& get_instance();
if (!isset($this->CI->session))
{
$this->CI->load->library('session');
}
}
function checking()
{
$subdomain_arr = explode('.', $_SERVER['HTTP_HOST']); //creates the various parts
if($subdomain_arr[0] == 'www')
{
$subdomain_name = $subdomain_arr[1]; //2ND Part
}
else
{
$subdomain_name = $subdomain_arr[0]; // FIRST Part
}
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header ("Cache-Control: no-cache, must-revalidate");
header ("Pragma: no-cache");
if( $subdomain_name != 'xyz' )
{
$where = array();
$where['subdomain_name'] = $subdomain_name;
$where['status'] = 1;
$this->db->from('subdomain_map');
$this->db->where($where);
$query = $this->db->get();
if($query->num_rows() < 1)
{
header('Location:http://xyz.com/index.php?/error');
}
else
{
$result = $query->row_array();
$this->CI->session->set_userdata('subdomain_id',$result['subdomain_id']);
$this->CI->session->set_userdata('subdomain_name',$result['subdomain_name']);
$org_id = gat_organisationid_using_subdomainid($result['subdomain_id']);
$this->CI->session->set_userdata('organisation_id', $org_id);
if($org_id)
{
$templ_id = get_templid_using_organisationid($org_id);
$org_logo = get_organisation_logo($org_id);
}
if($templ_id){
if($this->session->userdata('pinlogin'))
$this->CI->session->set_userdata('template_set', 4);
else
$this->CI->session->set_userdata('template_set', $templ_id);
}
if($org_logo)
$this->CI->session->set_userdata('org_logo', $org_logo);
}
}
else
{
$this->CI->session->unset_userdata('subdomain_id');
$this->CI->session->unset_userdata('subdomain_name');
if( $this->CI->session->userdata('user_id') && $this->CI->session->userdata('user_category')<=2 )
{
$this->CI->session->unset_userdata('organisation_id');
$this->CI->session->unset_userdata('org_logo');
}
}
}
}
Here is the basic check you need to support custom themes per subdomain
// Gets the current subdomain
$url = 'http://' . $_SERVER['HTTP_HOST'];
$parsedUrl = parse_url($url);
$host = explode('.', $parsedUrl['host']);
// store $host[0], which will contain subdomain or sitename if no subdomain exists
$subdomain = $host[0];
// check for subdomain
if ($subdomain !== 'localhost' OR $subdomain !== 'mysite')
{
// there is a subdomain, lets check that its valid
// simplified get_where using activerecord
$query = $this->db->get_where('subdomain_map', array('subdomain_name' => $subdomain, 'status' => 1));
// num_rows will return 1 if there was a valid subdomain selected
$valid = $query->num_rows() === 1 ? true : false;
if($valid)
{
// set theme, user_data, etc. for subdomain.
}
else
{
// get user out of here with redirect
header('Location: http://' . $_SERVER['HTTP_HOST'] . '/error');
exit();
}
}
Note that when using subdomains with codeigniter, you should set your config > base_url to the following:
$config['base_url'] = 'http://' . $_SERVER['HTTP_HOST'] . '/poasty/poasty-starterkit/';
this will ensure things like site_url() and other CI helpers still work.
Reading through your code may I suggest utilizing more of Codeigniters built-in functionality, for example your __construct function has a lot of un-necessary code:
Original code
public function __construct(){
parent::__construct();
/**
* CI already exists
* since this controller extends CI_controller, there is already and instance of CI available as $this.
$this->CI =& get_instance();
*/
/**
* duplicate check, CI checks if library is loaded
* and will ignore if loaded already
if (!isset($this->CI->session))
{
$this->CI->load->library('session');
}
*/
$this->CI->load->library('session');
}
Optimized for Codeigniter
public function __construct()
{
parent::__construct();
$this->CI->load->library('session');
}
I suggest reading up on the Codeigniter user_guide to better understand what codeigniter can do. #see http://codeigniter.com/user_guide/
I hope you find this helpful!
How can i use flash messenger in zend freamwork 2? Session documentation is not yet. Anyone know it? But session libraries are there.
Update :
Zend Framework new release added FlashMessenger View Helper , found in path /library/Zend/View/Helper/FlashMessenger.php
FlashMessenger.php
Old answer :
I have written a custom view helper, for printing flash messages
In /module/Application/Module.php
public function getViewHelperConfig()
{
return array(
'factories' => array(
'flashMessage' => function($sm) {
$flashmessenger = $sm->getServiceLocator()
->get('ControllerPluginManager')
->get('flashmessenger');
$message = new \My\View\Helper\FlashMessages( ) ;
$message->setFlashMessenger( $flashmessenger );
return $message ;
}
),
);
}
Create a custom view helper in /library/My/View/Helper/FlashMessages.php
namespace My\View\Helper;
use Zend\View\Helper\AbstractHelper;
class FlashMessages extends AbstractHelper
{
protected $flashMessenger;
public function setFlashMessenger( $flashMessenger )
{
$this->flashMessenger = $flashMessenger ;
}
public function __invoke( )
{
$namespaces = array(
'error' ,'success',
'info','warning'
);
// messages as string
$messageString = '';
foreach ( $namespaces as $ns ) {
$this->flashMessenger->setNamespace( $ns );
$messages = array_merge(
$this->flashMessenger->getMessages(),
$this->flashMessenger->getCurrentMessages()
);
if ( ! $messages ) continue;
$messageString .= "<div class='$ns'>"
. implode( '<br />', $messages )
.'</div>';
}
return $messageString ;
}
}
then simple call from layout.phtml , or your view.phtml
echo $this->flashMessage();
Let me show example of controller action
public function testFlashAction()
{
//set flash message
$this->flashMessenger()->setNamespace('warning')
->addMessage('Mail sending failed!');
//set flash message
$this->flashMessenger()->setNamespace('success')
->addMessage('Data added successfully');
// redirect to home page
return $this->redirect()->toUrl('/');
}
In home page, it prints
<div class="success">Data added successfully</div>
<div class="warning">Mail sending failed!</div>
Hope this will helps !
i have written a post about this some time ago. You can find it right here
Basically you use it just the same like earlier.
<?php
public function commentAction()
{
// ... display Form
// ... validate the Form
if ($form->isValid()) {
// try-catch passing data to database
$this->flashMessenger()->addMessage('Thank you for your comment!');
return $this->redirect()->toRoute('blog-details'); //id, blabla
}
}
public function detailsAction()
{
// Grab the Blog with given ID
// Grab all Comments for this blog
// Assign the view Variables
return array(
'blog' => $blog,
'comments' => $comments,
'flashMessages' => $this->flashMessenger()->getMessages()
);
}
Then in your .phtml file you do it like this:
// details.phtml
<?php if(count($flashMessages)) : ?>
<ul>
<?php foreach ($flashMessages as $msg) : ?>
<li><?php echo $msg; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Obviously this isn't all too handy, as you have to do this for every single .phtml file. Therefore doing it within the layout you have to do it at best like the following:
<?php
// layout.phtml
// First get the viewmodel and all its children (ie the actions viewmodel)
$children = $this->viewModel()
->getCurrent()
->getChildren();
$ourView = $children[0];
if (isset($ourView->flashMessages) && count($ourView->flashMessages)) : ?>
<ul class="flashMessages">
<?php foreach ($ourView->flashMessages as $fMessage) : ?>
<li><?php echo $fMessage; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
If you need further description, please see my blog, but i guess the code itself is pretty clear (apart frmo the layout.phtml example). Alternatively you're always free to write your own view helper to have it look a little cleaner inside your view-templates.
How to grab Flashmessenger’s messages in a View Helper – sharing code as requested by Sam.
The View helper should implement the ServiceManagerAwareInterface interface and related methods. The plugin will now have access to a Service Manager which we can use to get the Service Locator and ultimately access to the Flash Messenger.
I’ve not touched this code since I initially wrote it – so there may be a more elegant way of doing this.
protected function getMessages()
{
$serviceLocator = $this->getServiceManager()->getServiceLocator();
$plugin = $serviceLocator->get('ControllerPluginManager');
$flashMessenger = $plugin->get('flashmessenger');
$messages = $flashMessenger->getMessages();
// Check for any recently added messages
if ($flashMessenger->hasCurrentMessages())
{
$messages += $flashMessenger->getCurrentMessages();
$flashMessenger->clearCurrentMessages();
}
return $messages;
}
And calling getMessages() from within the plugin should return an array of messages that can be passed to a partial and rendered.
Add code below to the view to render error messages:
<?php echo $this->flashmessenger()
->setMessageOpenFormat('<div class="alert alert-danger"><ul%s><li>')
->setMessageCloseString('</li></ul></div>')
->render('error')
; ?>
In previous request, make sure you created an error message by running code below in your controller:
$this->flashmessenger()->addErrorMessage('Whops, something went wrong...');
hi i am new in joomla.I need the dynamic link in view file.
//no direct access
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
// include the helper file
require_once(dirname(FILE).DS.'helper.php');
// get a parameter from the module's configuration
$userCount = 5;
// get the items to display from the helper
$items = ModNewHelper::getItems($userCount);
//link of the component
// include the template for display
require(JModuleHelper::getLayoutPath('mod_new'));
this is main file
/**
* #author Raju Gautam
* #copyright 2011
*/
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
class ModNewHelper
{
/**
* Returns a list of post items
*/
public function getItems($userCount)
{
// get a reference to the database
$db = &JFactory::getDBO();
// get a list of $userCount randomly ordered users
$query = 'SELECT name,id FROM `#__hello` ORDER BY ordering LIMIT ' . $userCount . '';
$db->setQuery($query);
$items = ($items = $db->loadObjectList())?$items:array();
return $items;
} //end getItems
} //end ModHelloWorld2Helper
this is helper file
defined('JEXEC') or die('Restricted access'); // no direct access
echo JText::('Latest News');
//echo ""; print_r($items); exit;
foreach ($items as $item) {
echo JText::sprintf($item->name);
} this is view file
I need the link on echo JText::sprintf($item->name); this line. can i helped please?
change your this line from view file:
echo JText::sprintf($item->name);
to :
echo "<a href='".$item->link."'>". JText::sprintf($item->name)."</a>";
assuming, link is the field name of your link else change it according to the field name you've used for link. this may help, i guess .. good luck with it.
use
echo "<a href='".JRoute::_($item->link, false)."'>". JText::sprintf($item->name)."</a>";
JRoute will take care of routing also, if routing is enabled.