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.
Related
I have a problem with all my forms in symfony 1.4. They work with good datas, my new objects are created ... But when i give bad datas, my forms do nothing as expected but have no errors.
My code in my action :
$this->form = new EtablissementForm();
$this->form->bind(
$request->getParameter($this->form->getName()),
$request->getFiles($this->form->getName())
);
Edit :
Solved. I guess i need some sleep. This was really a dumb mistake. I was sure i had removed a new E...Form(); In my view for my action, actually i did it ... in another file.
So my $form was overwritten by an empty form. So the problem is solved.
if ($this->form->isValid())
{
//some things and a redirect
}
In a nutshell, my form works with good datas. But i don't have any errors to display when i'm giving bad datas. And my form don't add something in my database. Validations works cause it raise exception in bind, but i just get an empty form to display.
Your view needs to have proper scope to $form. Your code above may be incomplete. In the action you show above, if the action ends, and you go to your view, and your view has the following, your validation errors should appear inline with your form.
<?php echo $form ?>
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
I want get the follow thing working.
I've a page with a couple of text articles, each article has his own 'id' in the database. Below every article I want to make it possible to discuss about it. So I setup a discuss form witch I print with my article trough a 'foreach'.
In the form I added a Zend_Form_Element_Hidden. In the view I want to set the value of the hidden field with 'article_id', this likes me the best way to put it in the database?
In the foreach I try the follow thing but when I do this, the form is gone and I only get the element where I add the value.
My code in the view:
foreach ($this->paginator as $article):
echo $this->form->getElement('article')->setValue($article['id']);
endforeach;
I hope some one can make this a bit more clear for me :)
With kind regards,
Nicky
I am guessing you want to print the form inside the loop but only the element is being printed.
If that is your problem, the reason is because setValue() returns the element and not the form.
// Your Code
// This will only print the element and not the entire form
echo $this->form->getElement('article')->setValue($article['id']);
You will have to change your code to:
// Set the element value first
$this->form->getElement('article')->setValue($article['id']);
// Then render the form
echo $this->form;
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.
I am having a few problems with Dojo Filtering Selects when using the Zend Framework Forms and need some help to find out what I have missed as this is driving me mad.
I am currently getting this errors in firebug:
dojo.data is undefined
dojo.data.ItemFileReadStore is not a constructor
Below is the code that I am using to create the filter select and provide the json data to the calling controller.
Zend_Form Element (Dojo Enabled)
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setStoreId('industrystore')
->setStoreType('dojo.data.ItemFileReadStore')
->setStoreParams(array('url' => $baseUrl.'/dojo/industry'))
->setAttrib("searchAttr", "title")
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
Dojo Controller
public function industryAction(){
$db = Zend_Db::factory($this->config->database);
$result = $db->fetchAll("SELECT * FROM industries");
$data = new Zend_Dojo_Data('industryid', $result);
$this->_helper->autoCompleteDojo($data);
$db->closeConnection();
}
The annoying thing is all my other Dojo elements on this form and other forms work well it is just whenever I do Filtering Selects that I hit these problems, and this problem causes all the other elements in a form to fail too.
Thanks in advance.
The problem is actually with how Zend Framework initializes the dijits and data stores before the toolkit is fully loaded, in this case specifically the methods assigning the store to the dijit. I ran into this issue as well and found the best way to work around the issues was to either pass the data store from the controller to a JavaScript variable defined in the view or do what your did with a specific autocomplete action. Based on your example I would make the following changes.
In your form I would simplify the element:
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
In your view you want to connect the store to your dijit and make sure that you have loaded the dojo.data.ItemFileReadStore module:
<?php $this->dojo()->onLoadCaptureStart()?>
function(){
dijit.byId('industry').store = new dojo.data.ItemFileReadStore({ url: '/controller/industry' });
}
<?php
$this->dojo()->onLoadCaptureEnd();
$this->dojo()->requireModule('dojo.data.ItemFileReadStore');
?>
As I mentioned I ran into a similar issue which I answered here . Another issue I discovered is that the data store does not like dealing with labels declared anything other than "name" for the label declaration in the Zend_Dojo_Data.