ZEND, Edit form - zend-framework

I have a Zend form to add something to database. And then I want to use this form to edit what I added to the databese. Is any possibility to use this form (fill it from database and display it???)
I have this in my controller:
public function editAction() {
if (Zend_Auth::getInstance()->hasIdentity()) {
try {
$form = new Application_Form_NewStory();
$request = $this->getRequest();
$story = new Application_Model_DbTable_Story();
$result = $story->find($request->getParam('id'));
// $values = array(
// 'title' => $result->title,
// 'story' => $result->story,
// );
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
$data = array(
'title' => $form->getValue("title"),
'story' => $form->getValue("story"),
);
$where = array(
'id' => $request->getParam('id'),
);
$story->update($data, $where);
}
}
$this->view->form = $form;
$this->view->titleS= $result->title;
$this->view->storyS= $result->story;
} catch (Exception $e) {
echo $e;
}
} else {
$this->_helper->redirector->goToRoute(array(
'controller' => 'auth',
'action' => 'index'
));
}
}
In my view:
<?php
try
{
$tmp = $this->form->setAction($this->url());
//$tmp->titleS=$this->title;
//$tmp->storyS=$this->story;
//echo $tmp->title = "aaaaa";
}
catch(Exception $e)
{
echo $e;
}
And when I try to change something in this view I mean give any value different then NULL I have error that I can not do it so is any possibility to reuse this form? Or not?
Thanks!

Zend_Form has method populate(), which sets values of the form based on array data. So just do:
$form->populate($result->current()->toArray());
and form will be populated based on keys from array.

Related

How to update data using session in codeigniter

This my code in codeigniter but it doesn't update in database, I'm beginner ni codeigniter, how could I fix this error, or what is wrong in my code?
THis is my Controller:
function edit() {
$role = $this->session->userdata('role');
$this->form_validation->set_rules('firstname', 'firstname', 'required|xss_clean');
$this->form_validation->set_rules('lastname', 'lastname', 'required|xss_clean');
if ($this->form_validation->run() == FALSE) {
//set page data
$data['title'] = 'Update Profile';
if($role!=''){
$data['admin'] = $this->M_user->get($this->session->userdata('user_id'));
}else{
$data['admin'] = $this->M_administrator->getAdmin($this->session->userdata('id_admin'));
}
$data['sitename'] = $this->M_website->getName();
$data['content'] = 'admin/myaccount/edit';
//parse template
$this->parser->parse('admin/template', $data);
} else {
if($role!=''){
if ($this->M_user->updateStatus($_POST['user_id'])) {
//SAVE ADMIN ACTION LOG
//save_admin_action(array('module' => Constant::AM_ACCOUNT, 'action' => Constant::AL_EDIT, 'title' => $this->form_validation['username'], 'object_id' => $id));
//redirect page
$this->session->set_flashdata('saved', TRUE);
redirect('admin/myaccount');
}
}else{
if ($this->M_administrator->updateStatus($_POST['id_admin'])) {
//SAVE ADMIN ACTION LOG
//save_admin_action(array('module' => Constant::AM_ACCOUNT, 'action' => Constant::AL_EDIT, 'title' => $this->form_validation['username'], 'object_id' => $id));
//redirect page
$this->session->set_flashdata('saved', TRUE);
redirect('admin/myaccount');
}
}
}
}
This is my model administrator:
function updateStatus($post, $id){
$data = array(
'firstname' => $post['firstname'],
'lastname' => $post['lastname']
);
$this->db->where('id_admin', $id);
if($this->db->update('admin', $data)){
return TRUE;
}else{
return FALSE;
}
}
user Model:
function updateStatus($post, $id){
$data = array(
'firstname' => $post['firstname'],
'lastname' => $post['lastname']
);
$this->db->where('user_id', $id);
if($this->db->update('user', $data)){
return TRUE;
}else{
return FALSE;
}
}
pass firstname and last name to your updatestatus model function if you are not getting that value in model so you are not able to change
print your query using $this->db->last_query(); to get query output and post your query here
Change your where clause to
$this->db->where('id_admin', $post);

Phalcon uniqueness on update

folks. The uniqueness validator in my form works as expected on adding new records, but on updating an exsisting record, it throws an error that the url already exists. It exists, in fact, but only in the current record.
Here is my controller:
$feed = Feeds::findFirst($id);
$feedForm = new FeedForm($feed, array('edit' => true));
if ($this->request->isPost() == true) {
$feedData = $this->request->getPost();
if ($feedForm->isValid($feedData, $feed)) {
if ($feed->save()) {
$this->flash->success("Feed successfuly updated.");
} else {
$this->flash->error("Update failed.");
}
} else {
foreach ($feedForm->getMessages() as $message) {
$this->flash->error($message);
}
}
}
And my form class:
class FeedForm extends FormBase {
public $options;
public function initialize($entity = null, $options = null) {
parent::initialize();
$this->setEntity($entity);
$this->options = $options;
$status = new Radio('status');
$status->addValidator(
new PresenceOf(
array(
'message' => 'The status is required.'
)
));
$this->add($status);
$name = new Text('name');
$name->addValidator(
new PresenceOf(
array(
'message' => 'The name is required.'
)
));
$name->addValidator(
new StringLength(
array(
'max' => 50,
'messageMaximum' => 'The name you entered is too long.'
)
));
$this->add($name);
$xml = new Text('xml');
$xml->addValidator(
new PresenceOf(
array(
'message' => 'The URL address is required.'
)
));
$xml->addValidator(
new StringLength(
array(
'max' => 2048,
'messageMaximum' => 'The URL address you entered is too long.'
)
));
$xml->addValidator(
new Url(
array(
'message' => 'The URL you entered is invalid.'
)
));
$xml->addValidator(
new Uniqueness(
array(
'model' => 'Sravnisite\Admin\Models\Feeds',
'table' => 'feeds',
'column' => 'xml',
'message' => 'The entered URL address already exists.'
)
));
$periodOptions = array();
for ($i = 4; $i <= 24; $i++) {
array_push($periodOptions, $i);
}
$this->add($xml);
$period = new Select('period', $periodOptions);
$period->addValidator(
new PresenceOf(
array(
'message' => 'The period is required.'
)
));
$this->add($period);
$shopID = new Select('shop_id', Shops::find(), array('using' => array('id', 'name')));
$shopID->addValidator(
new PresenceOf(
array(
'message' => 'The shop is required.'
)
));
$this->add($shopID);
}
}
Any ideas?
The form validation doesn't know to ignore the record you are updating - so for uniqueness it finds the record you're trying to update and gives an error. You could do some complicated find logic to keep the uniqueness validation in the form but it is better moved to the model. Your result would end up something like:
Controller
$feed = Feeds::findFirst($id);
$feedForm = new FeedForm($feed, array('edit' => true));
if ($this->request->isPost() == true) {
$feedData = $this->request->getPost();
if ($feedForm->isValid($feedData, $feed)) {
if ($feed->save()) {
$this->flash->success("Feed successfuly updated.");
} else {
$this->flash->error("Update failed.");
// Get each of the validation messages from the model
foreach ($feed->getMessages() as $message) {
$this->flash->error($message);
}
}
} else {
foreach ($feedForm->getMessages() as $message) {
$this->flash->error($message);
}
}
}
Form
// Exactly the same as you currently have but without the Uniqueness Validator
Model
class Feeds extends Phalcon\Mvc\Model
/**
* Validate that xml URLs are unique
*/
public function validation()
{
$this->validate(new Uniqueness(array(
"field" => "xml",
"message" => "The url must be unique."
)));
return $this->validationHasFailed() != true;
}

InputFilter "setRequired" not working for html5 multiple

I'm having hard time with a weird behaviour of fileinput.
This is my form:
namespace Frontend\Form;
use NW\Form\Form;
use Zend\InputFilter;
use Zend\Form\Element;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
class EnrollStructure extends Form implements ServiceManagerAwareInterface
{
protected $sm;
public function __construct($name=null) {
parent::__construct("frmEnrollStructure");
$this->setAttribute("action", "/registrazione_struttura/submit")
->setAttribute('method', 'post')
->setAttribute("id", "iscrizione_struttura")
->setAttribute("class", "form fullpage");
$this->addInputFilter();
}
public function init()
{
$structureFs = $this->sm->get('Structure\Form\Fieldsets\Structure');
$structureFs->setUseAsBaseFieldset(true);
$structureFs->remove("id")
->remove("creationTime")
->remove("latLon");
$file = new Element\File("images");
$file->setAttribute('multiple', true);
$this->add($structureFs)->add($file);
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Iscriviti',
'id' => 'sbmtEnrollStructure',
'class' => 'submit_btn'
),
));
$this->setValidationGroup(
array(
'structure' =>
array(
'companyname',
'vatNumber',
'addressStreet',
'addressZip',
'addressCity',
'addressRegion',
'fax',
'publicPhone',
'publicEmail',
'website',
'status',
'ownerNotes',
'category',
'subcategory',
"facilities",
"agreeOnPolicy",
"agreeOnPrivacy",
"subscribeNewsletter",
"contact" => array("name", "surname", "email", "role", "phone"),
),
"images"
));
}
/**
* Set service manager
*
* #param ServiceManager $serviceManager
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->sm = $serviceManager;
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('images');
$fileInput->setRequired(true);
$fileInput->getValidatorChain()
->attachByName('filesize', array('max' => "2MB"))
->attachByName('filemimetype', array('mimeType' => 'image/png,image/x-png,image/jpg,image/jpeg'))
->attachByName('fileimagesize', array('maxWidth' => 2048, 'maxHeight' => 2048));
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
Basically, I mainly use a fieldset which contains most of the data I request to the user, plus a File input field.
This is the Fieldset Structure: (most important parts..)
use Zend\Form\Element;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Validator\Identical;
use Zend\Validator\NotEmpty;
use Zend\Validator\Regex;
use Zend\Validator\StringLength;
class Structure extends Fieldset implements InputFilterProviderInterface, ServiceManagerAwareInterface
{
protected $sm;
public function __construct()
{
parent::__construct('structure');
}
public function init()
{
$this->setHydrator(new DoctrineHydrator($this->_entityManager(),'Structure\Entity\Structure'));
$this->setObject($this->sm->getServiceLocator()->get("Structure_Structure"));
$id = new Element\Hidden("id");
$name = new Element\Text("companyname");
$name->setLabel("Ragione Sociale");
...........
}
public function getInputFilterSpecification()
{
return array
(
"id" => array(
"required" => false,
),
"companyname" => array(
"required" => true,
"validators" => array(
array('name' => "NotEmpty", 'options' => array("messages" => array( NotEmpty::IS_EMPTY => "Inserire la ragione sociale")))
),
),
.....
}
}
This is my controller:
public function submitAction()
{
try {
$this->layout("layout/json");
$form = $this->getForm('Frontend\Form\EnrollStructure');
//$form->addInputFilter();
$structure = $this->getServiceLocator()->get("Structure_Structure");
$viewModel = new ViewModel();
$request = $this->getRequest();
if ($request->isPost())
{
$post = array_merge_recursive
(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid())
{
$structure = $form->getObject();
$contact = $structure->getContact();
$this->getServiceLocator()->get('Structure_ContactService')->save($contact);
$files = $request->getFiles()->toArray();
if(isset($files['images']))
{
$count = 3;
foreach($files['images'] as $pos => $file)
{
$fpath = $this->getServiceLocator()->get('RdnUpload\Container')->upload($file);
if(!empty($fpath))
{
if(--$count ==0) break;
$asset = $this->getServiceLocator()->get("Application_AssetService")->fromDisk($fpath, $file['name']);
$this->getServiceLocator()->get("Application_AssetService")->save($asset);
$structure->addImage($asset);
}
}
}
$this->getServiceLocator()->get('Structure_StructureService')->save($structure);
$retCode = RetCode::success(array("iscrizione_struttura!" => array("form_submit_successfull")), true);
}
else
{
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
}
$viewModel->setVariable("retcode", $retCode);
return $viewModel;
}
} catch(Exception $e)
{
throw $e;
}
}
The strange thing is that if i remove from the field "images" the "multiple" attribute everything works fine, causing the form not to validate and i get this message:
[images] => Array
(
[fileUploadFileErrorFileNotFound] => File was not found
)
While, if i set the attribute multiple, and the user does not upload a file i get no error, but the form gets invalidated (this is the reason for this "bad" code in my controller:)
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
I found the problem was caused by the Jquery form plugin, without it it works fine. :( In case somebody needs, I think the correct action code can be found here (I haven't tryied it anyway)
https://github.com/cgmartin/ZF2FileUploadExamples/blob/master/src/ZF2FileUploadExamples/Controller/ProgressExamples.php

How to add both Form and List to $this [Plesk/Zend]

I have some sample code with 2 tabs. One shows a "form" and the other a "list" (Sample 1.5-1), I want to combine them.
I want to show the "form" tab with a "list" view at the bottom (after submit button). I am getting stuck on how to show this.
Inside IndexController, in the ->getRequest->isPost() area, I try to create and fill up the $list (same as the "list" tab example code):
$list=$this->_getListRandom();
$this->view->list = $list;
Then inside of form.phtml, I append:
<h1>My Report Data></h1>
<?php echo $this->list; ?>
I can see the "My Report Data" text in the web page, so I know I am getting to the right area in the code!
But, I get an error from pm_View_Helper_render::renderList() that it must be an instance of pm_View_List_Simple.
I am trying to create both a pm_Form_Simple and pm_View_List_Simple in the same $this, but not
sure if it is allowed or how to do it.
Thanks for any suggestions!
<?php
class IndexController extends pm_Controller_Action
{
public function init()
{
parent::init();
// Init title for all actions
$this->view->pageTitle = 'Example Module';
// Init tabs for all actions
$this->view->tabs = array(
array(
'title' => 'Form',
'action' => 'form',
),
array(
'title' => 'List',
'action' => 'list',
),
);
}
public function indexAction()
{
// Default action will be formAction
$this->_forward('form');
}
public function formAction()
{
// Init form here
$form = new pm_Form_Simple();
$form->addElement('text', 'exampleText', array(
'label' => 'Example Text',
'value' => pm_Settings::get('exampleText'),
'required' => true,
'validators' => array(
array('NotEmpty', true),
),
));
$form->addControlButtons(array(
'cancelLink' => pm_Context::getModulesListUrl(),
));
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
// Form proccessing here
pm_Settings::set('exampleText', $form->getValue('exampleText'));
$this->_status->addMessage('info', 'Data was successfully saved.');
# Create the LIST
$list = $this->_getListRandom();
$this->view->list = $list;
$this->_helper->json(array('redirect' => pm_Context::getBaseUrl()));
}
$this->view->form = $form;
}
public function listAction()
{
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
public function listDataAction()
{
$list = $this->_getListRandom();
// Json data from pm_View_List_Simple
$this->_helper->json($list->fetchData());
}
private function _getListRandom()
{
$data = array();
#$iconPath = pm_Context::getBaseUrl() . 'images/icon_16.gif';
for ($i = 0; $i < 15; $i++) {
$data[] = array(
'column-1' => '' . (string)rand() . '',
'column-2' => (string)rand(),
);
}
$list = new pm_View_List_Simple($this->view, $this->_request);
$list->setData($data);
$list->setColumns(array(
'column-1' => array(
'title' => 'Random with link',
'noEscape' => true,
),
'column-2' => array(
'title' => 'Random with image',
'noEscape' => true,
),
));
// Take into account listDataAction corresponds to the URL /list-data/
$list->setDataUrl(array('action' => 'list-data'));
return $list;
}
}
Please, try https://mega.co.nz/#!NxtyzbyS!JQqFdh7ruESQU_pgmhM6vi8yVFZQRTH-sPDeQcAOFws
Following files are changed:
\example-1.5-2\plib\views\scripts\index\form.phtml:
<?php echo $this->renderTabs($this->tabs); ?>
<?php echo $this->test; ?>
<?php echo $this->form; ?>
<?php echo $this->renderList($this->list); ?>
\example-1.5-2\plib\controllers\IndexController.php:
public function formAction() {
...
...
...
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
and here the result:

zend array[] element with validator

hello i have a form where the user can click on a button and dinamically add new elements(with Jquery)
<input name="sconto[]" type="text"><br>
<input name="sconto[]" type="text"><br>
<input name="sconto[]" type="text"><br>
...
I have a custom validator for float numbers in format with comma and dot separation like 20.50 and 20,50
The problem is i can't seem to find how to make zend apply it it to each element of the array.
So how should i declare this element and how to apply the validator? xD
this is my validator
protected $_messageTemplates = array(
self::NON_E_NUMERO => 'non sembra essere un numero'
);
public function isValid($value, $context = null)
{
$pos_virgola = strpos($value, ",");
if ($pos_virgola !== false)
$value = str_replace(",", ".", $value);
if (!is_numeric($value))
{
$this->_error(self::NON_E_NUMERO, $value);
return false;
}
else
return true;
}
}
the form i don't know how to do it, i use this but obviously it doesn't work
$sconto = $this->createElement('text','sconto')->setLabel('sconto');
//->setValidators(array(new Gestionale_Validator_Float()));
$this->addElement($sconto);
...
$sconto->setDecorators(array(//no ViewHelper
'Errors',
'Description',
array(array('data' => 'HtmlTag'), array('tag' => 'td', /*'class' => 'valore_campo', */'id'=>'sconto')),
array('TdLabel', array('placement' => 'prepend', 'class' => 'nome_campo'))
));
If Marcin comment is not what you want to do, then this is another way to create multi text element.
Create a custom decorator 'My_Form_Decorator_MultiText'. You will need to register your custom decorator class. Read Zend Framework doc for details http://framework.zend.com/manual/en/zend.form.decorators.html
class My_Form_Decorator_MultiText extends Zend_Form_Decorator_Abstract {
public function render($content) {
$element = $this->getElement();
if (!$element instanceof Zend_Form_Element_Text) {
return $content;
}
$view = $element->getView();
if (!$view instanceof Zend_View_Interface) {
return $content;
}
$values = $element->getValue();
$name = $element->getFullyQualifiedName();
$html = '';
if (is_array($values)) {
foreach ($values as $value) {
$html .= $view->formText($name, $value);
}
} else {
$html = $view->formText($name, $values);
}
switch ($this->getPlacement()) {
case self::PREPEND:
return $html . $this->getSeparator() . $content;
case self::APPEND:
default:
return $content . $this->getSeparator() . $html;
}
}
}
Now your validation class will validate each element value
class My_Validate_Test extends Zend_Validate_Abstract {
const NON_E_NUMERO = 'numero';
protected $_messageTemplates = array(
self::NON_E_NUMERO => 'non sembra essere un numero'
);
public function isValid($value, $context = null) {
if (!is_numeric($value)) {
$this->_error(self::NON_E_NUMERO, $value);
return false;
}
else
return true;
}
}
This is how you can use the new decorator
$element = new Zend_Form_Element_Text('sconto', array(
'validators' => array(
new My_Validate_Test(),
),
'decorators' => array(
'MultiText', // new decorator
'Label',
'Errors',
'Description',
array('HtmlTag', array('tag' => 'dl',))
),
'label' => 'sconto',
'isArray' => true // must be true
));
$this->addElement($element);
Hope this helps