Invalid type given. String expected - Zend Framework 2 - zend-form

Im working on Zend Framework 2 especially with Zend Forms. I have declared a Select dropdown box in
Form:
$selectElement = new Element\Select('selectElement');
$selectElement->setAttribute('title', 'Select a Value')
->setAttribute('id', 'id');
$data = array(
array(
//Fetching the values from database
),
);
$selectElement->setAttribute('multiple', 'multiple')
->setValueOptions($data);
$this->add($selectElement);
InputFilter:
$inputFilter->add($factory->createInput(array(
'name' => 'selectElement',
'required' => false,
'filters' => array(
array(
'name' => 'Int'
),
),
)));
I have used Zend Debug to get the values which are in the selectElement dropbox in this fashion:
$dataSelectElements = $this->getRequest()->getPost('selectElement');
\Zend\Debug\Debug::dump($dataSelectElements);
Debug Result:
array(4) {
[0] => string(2) "20"
[1] => string(2) "22"
[2] => string(2) "23"
[3] => string(2) "75"
}
Basically Im getting the id's from the selectElement form to store it in the database. Right now Im getting a notice and zend form error:
Notice Error:
Notice: Array to string conversion in ..\zendframework\zendframework\library\Zend\Filter\Int.php on line 29
And a form invalid error:
array(1) {
[0] => array(1) {
["selectElement "] => array(1) {
["explodeInvalid"] => string(35) "Invalid type given. String expected"
}
}
}
Is there a solution to over come this problem. Any help would be appreciated.

The Int filter will attempt to make an Integer out of your array of data, which is not going to work.
Previously I've used the Callback filter, which can be used to loop through the data and check if each value is an Int.
For example:
'filters' => array(
array(
'name' => 'Callback',
'options' => array(
'callback' => function($values) {
return array_filter($values, function($value) {
return ((int)$value == $value);
});
}
)
),
),

I did bit differently, something like this
form
class Companyform extends Form
{
public function __construct()
{
// we want to ignore the name passed
parent::__construct('company');
$this->setAttribute ('method', 'post');
$this->setAttribute ('class', 'form-horizontal');
$this->add ( array (
'name' => 'parentID',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'parentID',
'type' => 'select',
'placeholder' => "Parent Company",
),
'options' => array(
'label' => 'Parent Company'
)
));
$this->add(array(
'name' => 'btnsubmit',
'attributes' => array(
'id' => 'btnsubmit',
'type' => 'submit',
'value' => 'Add',
'class' => 'btn btn-primary'
),
));
}
}
controller
public function addAction()
{
$request = $this->getRequest();
$companyList = $this->_getCompanyList();
$form = new Companyform();
$form->get('parentID')->setAttribute('options',$companyList);
if ($request->isPost())
{
$company = new Company();
$form->setInputFilter($company->getInputFilter());
$form->setData($request->getPost());
if ($form->isvalid())
{
}
}
}
public function _getCompanyList()
{
$companies = $this->Em()->getEntityManager()->getRepository('XXXX\Entity\Company')->findBy(array('isDeleted'=>'0'));
$companyIDList = array();
$companyIDList[0] = "No Parent";
foreach ($companies as $company)
{
$companyIDList[$company->id] = $company->companyName;
}
return $companyIDList;
}
Entity class
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'companyName',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 255,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
You may need to add following library in entity
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

In ZendFramework 2, when you creating a (add) element from your Form file, Check the attribute: inarrayvalidator is true.
$this->add(array(
'name' => 'select_name',
'type' => 'select',
'id' => 'select_name',
'options' => array(
'label' => 'Select Name',
),
'attributes' => array(
'id' => 'select_id',
'inarrayvalidator' => true,
),
));
I hope, this works...

Related

Redirect user after saving data in admin controller Prestashop

I have an admin controller which displays the list of data on clicking edit on an entry or adding a new entry I am showing renderForm() but after saving the data (either by edit or add) I want to redirect the user to another controller in place of showing the same controller list.
Bellow is the code which I am currently using for example of my requirements I trying to do something which I have done below in initcontent() but that is not working so I want to know where should I call this in place of initcontent()
<?php
/**
* The file is controller. Do not modify the file if you want to upgrade the module in future
*
* #author Globo Jsc <contact#globosoftware.net>
* #copyright 2016 Globo., Jsc
* #link http://www.globosoftware.net
* #license please read license in file license.txt
*/
include_once(_PS_MODULE_DIR_ . 'cardelivery/classes/AdditionalServicesModel.php');
class AdminAdditionalServiceController extends ModuleAdminControllerCore {
public $name;
public function __construct() {
$this->name = 'AdminAdditionalService';
$this->className = 'AdditionalServicesModel';
$this->table = 'additional_service';
$this->meta_title = $this->l('Additional Services');
$this->deleted = false;
$this->explicitSelect = true;
$this->context = Context::getContext();
$this->bootstrap = true;
$this->_defaultOrderBy = 'id_additional_service';
$this->filter = true;
if (Shop::isFeatureActive()) {
Shop::addTableAssociation($this->table, array('type' => 'shop'));
}
$this->position_identifier = 'id_additional_service';
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_additional_service' => array(
'title' => $this->l('ID'),
'type' => 'int',
'width' => 'auto',
'orderby' => false),
'service_name' => array(
'title' => $this->l('Icon'),
'width' => 'auto',
'orderby' => false,
),
'service_desc' => array(
'title' => $this->l('service_desc'),
'type' => 'text'
),
'active' => array(
'title' => $this->l('Status'),
'width' => 'auto',
'active' => 'status',
'type' => 'bool',
'orderby' => false),
);
parent::__construct();
}
function initContent() {
parent::initContent();
if (Tools::isSubmit('submit')) {
Tools::redirectAdmin(self::$currentIndex . '&token=' . Tools::getAdminTokenLite('AdminCategories') . '&conf=7');
}
}
public function initPageHeaderToolbar() {
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => Context::getContext()->link->getAdminLink('AdminGCardeliverycity', true),
'desc' => $this->l('Back to list', null, null, false),
'icon' => 'process-icon-back'
);
parent::initPageHeaderToolbar();
}
public function renderForm() {
$id_citydelivery = (int) Tools::getValue('id_citydelivery');
if ($id_citydelivery == 0) {
$addSerModObj = new AdditionalServicesModel((int) Tools::getValue('id_additional_service'));
$id_citydelivery = $addSerModObj->id_citydelivery;
}
$fields_form_1 = array(
'form' => array(
'legend' => array('title' => $this->l('Additional Service'), 'icon' => 'icon-cogs'),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_citydelivery'
),
array(
'type' => 'text',
'label' => $this->l('Service_name'),
'name' => 'service_name',
'size' => 255,
'required' => true,
'desc' => $this->l('Enter name of Arrival port')
),
array(
'type' => 'text',
'label' => $this->l('service_desc'),
'name' => 'service_desc',
'size' => 255,
'required' => true,
'desc' => $this->l('Enter name of Arrival port')
),
array(
'type' => 'text',
'label' => $this->l('charge'),
'name' => 'charge',
'size' => 255,
'required' => true,
'desc' => $this->l('Enter name of Arrival port')
),
array(
'type' => 'switch',
'label' => $this->l('Active'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Active')), array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Inactive')))),
),
'submit' => array('title' => $this->l('Save')),
'buttons' => array(
array(
'href' => Context::getContext()->link->getAdminLink('AdminGCardeliverycity', true) . '&updatecitydelivery&id_citydelivery=' . $id_citydelivery,
'title' => $this->l('Cancle'),
'icon' => 'process-icon-cancel'
)
)
)
);
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->toolbar_scroll = true;
$lang = new Language((int) Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$this->fields_form = array();
$helper->identifier = $this->identifier;
$helper->submit_action = 'submit';
$helper->currentIndex = AdminController::$currentIndex;
$helper->token = Tools::getAdminTokenLite($this->name);
$id_additional_service = (int) Tools::getValue('id_additional_service');
$additionalServiceObj = new AdditionalServicesModel($id_additional_service);
$helper->tpl_vars = array(
'fields_value' => $this->getFormValues($additionalServiceObj),
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id
);
$_1 = $helper->generateForm(array($fields_form_1));
$return = $_1;
return $return;
}
function getFormValues($additionalServiceObj) {
return array(
'service_name' => Tools::getValue('service_name ', $additionalServiceObj->service_name),
'service_desc' => Tools::getValue('service_desc', $additionalServiceObj->service_desc),
'charge' => Tools::getValue('charge', $additionalServiceObj->charge),
'active' => Tools::getValue('active', $additionalServiceObj->active)
);
}
}
First of all, it seems that you redirect your page to the same URL. Try to use this
Tools::redirectAdmin($this->context->link->getAdminLink('AdminHome'));
where
AdminHome
is a redirect URL, you need to replace it with yours.
And second, try to use
Tools::getIsset('yourButtonName')
instead of
Tools::isSubmit('yourButtonName')
and the last, if nothing mentioned above will not help, try to move
parent::initContent();
and put it after your condition
Probably redirect_after may be useful
$this->redirect_after = 'Your custom address';

remove button from CGridView with condition

Hi I have CRUD generated CGridView in yii. I need to add a new button to CGridView rows and hide it if appointment_status(one of CGridView column) value equals 0
This is my code of CGridView,
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'bookings-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'name',
'email',
'telephone',
'time',
'employee',
'appointment_status',
'client_ip',
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => 'CHtml::button("$data->appointment_status",array("onclick"=>"document.location.href=\'".Yii::app()->controller->createUrl("controller/action",array("id"=>$data->id))."\'"))',
'visible'=>$data->appointment_status==1,
),
array(
'class' => 'CButtonColumn',
),
),
));
But all I'm getting is error stating,
Undefined variable: data
It would be great help if someone can look into it.
you can use like this:
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'bookings-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'name',
'email',
'telephone',
'time',
'employee',
'appointment_status',
'client_ip',
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => function ($data) {
if ($data->appointment_status == 1) {
return CHtml::button("$data->appointment_status", array("onclick" => "document.location.href=\'" . Yii::app()->controller->createUrl("controller/action", array("id" => $data->id)) . "\'"));
} else {
return;
}
}
),
array(
'class' => 'CButtonColumn',
),
),
));
Your 'visible' handling the column visibility and not the button, you can use custom attribute on model to create and handle the button visibility.
add to your model:
public function getConfirmationButton()
{
if ($data->appointment_status == 1) {
return CHtml::button($this->appointment_status,array("onclick"=>"document.location.href=\'".Yii::app()->controller->createUrl("controller/action",array("id"=>$this->id))."\'"));
} else {
return '';
}
}
and call it in your view:
..........
'link' => array(
'header' => 'Confirmation',
'type' => 'raw',
'value' => '$data->confirmationButton',
),
...........
visible is a boolean or a PHP expression that will be evaluated to give a boolean. During the evaluation $data is assigned to the current item from the dataProvider used. $data doesn't exist outside of the evaluation function evaluateExpression(). As such the implementation should be:
`visible` => '$data->appointment_status == 1',
You need to quote value of visible key in link array. So instead of this:
'visible'=>$data->appointment_status==1
It should be:
'visible'=>'$data->appointment_status==1'
it should work now.
You will get undefined variable because visible not allow any callback.
Try this solution, it's yii2 code and i don't know much of Yii.
'delete' => function ($url, $model) {
return ($model->isVisible($model)) ?
Html::a('<span class="glyphicon glyphicon-trash"></span>',
$url,
['title' => Yii::t('app', 'Delete')]) : '';
public static function isVisible($data)
{
return ($data->appointment_status == 1) ? true : false;
}

install.php is not being run during installation

My install.php is not being run during installation.I checked everywhere.To be sure,I ran the code in install.php elsewhere and it worked well. But during installation only the install.php is being skipped somehow.My module name is Hotelreservation, hence the code in install.php is as below. Why is there no error display during installation ?
<?php
class Hotelreservation_Installer extends Engine_Package_Installer_Module
{
public function onInstall()
{
$this->_hotelroomsBrowsePage();
parent::onInstall();
}
protected function _hotelroomsBrowsePage()
{
$db = $this->getDb();
// profile page
$page_id = $db->select()
->from('engine4_core_pages', 'page_id')
->where('name = ?', 'hotelreservation_index_browse')
->limit(1)
->query()
->fetchColumn();
if (!$page_id) {
// Insert page
$db->insert('engine4_core_pages', array(
'name' => 'hotelreservation_index_browse',
'displayname' => 'HotelRooms Browse Page',
'title' => 'Browse Rooms',
'description' => 'this page displays rooms',
'custom' => 0,
));
$page_id = $db->lastInsertId();
// Insert main
$db->insert('engine4_core_content', array(
'type' => 'container',
'name' => 'main',
'page_id' => $page_id,
));
$main_id = $db->lastInsertId();
// Insert middle
$db->insert('engine4_core_content', array(
'type' => 'container',
'name' => 'middle',
'page_id' => $page_id,
'parent_content_id' => $main_id,
'order' => 2,
));
$middle_id = $db->lastInsertId();
// Insert hotelreservation.browse-menu
$db->insert('engine4_core_content', array(
'type' => 'widget',
'name' => 'hotelreservation.browse-menu',
'page_id' => $page_id,
'parent_content_id' => $middle_id,
'order' => 1,
));
// Insert core content
$db->insert('engine4_core_content', array(
'type' => 'widget',
'name' => 'core.content',
'page_id' => $page_id,
'parent_content_id' => $middle_id,
'order' => 2,
));
// Insert left
$db->insert('engine4_core_content', array(
'type' => 'container',
'name' => 'left',
'page_id' => $page_id,
'parent_content_id' => $main_id,
'order' => 3,
));
$left_id = $db->lastInsertId();
}
return $this;
}
}// end class
Did you add info to mainfest file like this in packages array
'callback' => array(
'path' => 'Your path to php file',
'class' => 'Hotelreservation_Installer',
),
I agree with Arif. Check the file manifest.php inside of //settings:
(info of module Album)
'callback' => array(
'path' => 'application/modules/Album/settings/install.php',
'class' => 'Album_Installer',
),
I had this same issue and got it to work.
It turns out that the installer looks in application/packages/module-yourmodule-x.x.x.json first. around line 35 you'll find:
"callback": {
"path": null,
"class": "Engine_Package_Installer_Module",
"priority": 100
},
change that to:
"callback": {
"path": "application/modules/Yourmodule/settings/install.php",
"class": "Yourmodule_Installer",
"priority": 100
},
now, when you run the installer, your install.php will be called.

Zend - inputfilter get randomize name

Hello I'm trying ZF2 form with an input file.
I have a form with a file input and I want to insert the randomize name into my db.
How I can return the randomized name?
thanks.
This is the simple form class:
class OrdineForm extends Formhttp://stackoverflow.com/questions/ask
public function __construct($name = null)
{
parent::__construct('ordine');
$this->setAttribute('method', 'post');
$this->addElements();
$this->addInputFilter();
}
public function addElements(){
$this->add(array(
'name' => 'pdf',
'attributes' => array(
'type' => 'text',
'disabled' =>'true',
),
'options' => array(
'label' => 'PDF',
),
));
// FILE INPUT
$file = new File('file');
$file
->setLabel('PDF attach')
->setAttributes(array(
'id' => 'file',
));
$this->add($file);
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Add',
'id' => 'submitbutton',
'class' => 'btn btn-success'
),
));
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
$fileInput= new FileInput('file');
$fileInput->setRequired(false);
$fileInput->getFilterChain()->attachByName(
'filerenameupload',
array(
'target' => './public/tmpuploads/',
'randomize' => true,
"UseUploadname" => true,
)
);
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
After you have validated the form in your controller you can use $form->getData();
there should be a key 'file' as that is what you named your file element. Within that a key 'tmp_name'.
This will be the randomized name.
Eg:
public function uploadfileAction()
{
//get form and filter
$form = $this->getServiceLocator()->get('SomeModule\Form\UploadFileForm');
$filter = $this->getServiceLocator()->get('SomeModule\Form\UploadFileFilter');
$form->setInputFilter($filter->getInputFilter());
if ($this->getRequest()->isPost()) {
//merge files with post
$post = array_merge_recursive(
$this->getRequest()->getPost()->toArray(),
$this->getRequest()->getFiles()->toArray()
);
//set data in form
$form->setData($post);
//check is valid- form data will now contain new name
if ($form->isValid()) {
var_dump($form->getData());
}
}
}
The resulting array dump may look something like this:
array(13) {
["file"]=>
array(5) {
["name"]=>
string(14) "some-pdf.pdf"
["type"]=>
string(24) "application/pdf"
["tmp_name"]=>
string(46) "/public/tmpuploads/new-randomized-name.pdf"
["error"]=>
int(0)
["size"]=>
int(651264)
}
["submit"]=>
string(6) "Submit"
["csrf"]=>
string(32) "4df771bb2fb14e28992a408583745946"
}
You can then just do:
$formData = $form->getData();
$fileNewLocation = $formData['file']['tmp_name'];
//do what you want with $fileNewLocation

Populating CGridView one to many relation

In my project one of the model named types having multiple relation to other models the criteria with part is giving below its like
$criteria->with = array(
'category',
'subCategory',
'accountsSupplierPriceDetails' => array(
'with' => 'serviceLevel'
)
);
the relationship goes like
types - category - relation(1-1)
types - subcategory - relation(1-1)
types - accountsSupplierPriceDetails - relation(1-1)
accountsSupplierPriceDetails - serviceLevel - relation(1-n)
my problem is how to display the names from each table in a grid. the result of (1-n) should be displayed in a dropdownbox. when i try to access the data from column it shows the error Trying to get property of non-object ($data->accountsSupplierPriceDetails->serviceLevel ->name). can anyone please help me.
Thanks in advance.
in my view i create a cgridview with 5 rows in which one row data is populated using dropdownlist.
<div style="width:700px; height:auto;">
<?php
$widget = $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'response-grid',
'dataProvider' => $pickdataset->pickCategorylistingForMain(),
'cssFile' => Yii::app()->baseUrl . '/media/css/gridview.css',
'summaryText' => '',
'ajaxUpdate' => 'response-grid',
'enablePagination' => true,
'pager' => array(
'class' => 'LinkPager',
'cssFile' => false,
'header' => false,
'firstPageLabel' => 'First',
'prevPageLabel' => 'Previous',
'nextPageLabel' => 'Next',
'lastPageLabel' => 'Last',
),
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'type' => 'raw',
'name' => 'categoryExt',
'header' => 'Category',
),
array(
'type' => 'raw',
'header' => 'Sub Category',
'value' => '$data->subCategory->name',
),
array(
'type' => 'raw',
'name' => 'locationExt',
'header' => 'Location',
),
array(
'type' => 'raw',
'header' => 'Name',
'value' => 'CHtml::dropDownList($data->corporate_id."-".$data->category_id."-".$data->sub_category_id."-".$data->location_id,"",popDropBox($data->masterCategoryServiceLevels), array("class" => "listbox"), array("empty" => "Select a Location"))',
),
array(
'type' => 'raw',
'header' => 'Pick',
'value' => 'CHtml::image(Yii::app()->baseUrl . "/media/images/edit_icon.png",$data->corporate_id."-".$data->category_id."-".$data->sub_category_id."-".$data->location_id,array("title" => "Select this Combination"))',
),
),));
function popDropBox($data)
{
$list = array();
foreach ($data as $row)
{
$list[$row->serviceLevel->id] = $row->serviceLevel->name;
}
return $list;
}
?>
</div>
the relation in model is:
'masterCategoryServiceLevels' => array(self::HAS_MANY, 'MasterCategoryServiceLevel', 'category_template_id'),
'corporate' => array(self::BELONGS_TO, 'AccountsCorporate', 'corporate_id'),
'category' => array(self::BELONGS_TO, 'MasterCategory', 'category_id'),
'subCategory' => array(self::BELONGS_TO, 'MasterCategory', 'sub_category_id'),
'location' => array(self::BELONGS_TO, 'MasterLocation', 'location_id'),
the row is
array(
'type' => 'raw',
'header' => 'Name',
'value' => 'CHtml::dropDownList($data->corporate_id."-".$data->category_id."-".$data->sub_category_id."-".$data->location_id,"",popDropBox($data->masterCategoryServiceLevels), array("class" => "listbox"), array("empty" => "Select a Location"))',
),
and i use a function to create dropdown data is
function popDropBox($data)
{
$list = array();
foreach ($data as $row)
{
$list[$row->serviceLevel->id] = $row->serviceLevel->name;
}
return $list;
}
please comment if you have any doubt. i am free to share... have a nice day SO friends... wishes and prayers.