Prestashop filter date_add in webservice - prestashop

i'm new, and i've a problem with webservice.
when i try to retrieve customers filtering by date_add i get this error:
<message><![CDATA[This filter does not exist. Did you mean: "deleted"? The full list is: "id", "id_default_group", "id_lang", "newsletter_date_add", "ip_registration_newsletter", "last_passwd_gen", "secure_key", "deleted", "passwd", "lastname", "firstname", "email", "id_gender", "birthday", "newsletter", "optin", "website", "company", "siret", "ape", "outstanding_allow_amount", "show_public_prices", "id_risk", "max_payment_days", "active", "note", "is_guest", "id_shop", "id_shop_group"]]></message>
this is my code:
$yesterday = date("Y-m-d H:i:s", time() - 60 * 60 * 24);
$webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
// Qui imposto le opzion dell'array per il Webservice: in questo caso i clienti e setto che il formato รจ json
$opt = array( 'resource' => 'customers',
'filter[date_add]' => '['.$yesterday.']&date=1',
'display' => 'full',
'output_format' => 'JSON'
);
// faccio la chiamata
$xml = $webService->get($opt);
I'm stuck, I do not know what to do !!! any help is appreciated

Looking at the Customer class webservice parameters, there is no date_add:
protected $webserviceParameters = array(
'fields' => array(
'id_default_group' => array('xlink_resource' => 'groups'),
'id_lang' => array('xlink_resource' => 'languages'),
'newsletter_date_add' => array(),
'ip_registration_newsletter' => array(),
'last_passwd_gen' => array('setter' => null),
'secure_key' => array('setter' => null),
'deleted' => array(),
'passwd' => array('setter' => 'setWsPasswd'),
),
'associations' => array(
'groups' => array('resource' => 'group'),
)
);
If you have access to the server installation, you could add the date_add field to the webserviceParameters.
Or the function getWebserviceObjectList to change the behavour.
If you don't have access to the server installation, you can use the sort to get the latest customers until you reach the one you already have. You can use with limit to use in a foreach or while loop.
EDIT After some testing and inspecting what was going on:
First, it's we don't need to add the field date_add to the $webserviceParameters.
The request should be:
$opt = array( 'resource' => 'customers',
'filter[date_add]' => '['.$begin.','.$finish.']',
'date' => 1,
'display' => 'full',
'output_format' => 'JSON'
);
If you only add one date to the filter it will try to match only that date.
Then you need to change the PSWebServiceLibrary.php in line 284 and add the field 'date':
$params = array('filter', 'display', 'sort', 'limit', 'id_shop', 'id_group_shop', 'date');
Now it should work. I tested myself.
EDIT 2:
This is my full test, after changing the the line i mentioned in PSWebserviceLibrary.php, this retrieves my customers with date_add in the interval date.
<?php
require_once( 'PSWebServiceLibrary.php' );
echo 'starting<br />'.PHP_EOL;
try {
// creating web service access
$webService = new PrestaShopWebservice(MY_BASE_URL, WS_KEY, true);
$yesterday = date("Y-m-d", time() - 60 * 60 * 24);
$begin = date("Y-m-d", time() - 60 * 60 * 24 * 30);
$opt = array( 'resource' => 'customers',
'filter[date_add]' => '['.$begin.','.$yesterday.']',
'date' => 1,
'display' => 'full',
'output_format' => 'JSON'
);
//Retrieving the XML data
$xml = $webService->get($opt);
}
catch (PrestaShopWebserviceException $ex) {
// Shows a message related to the error
echo 'Other error: <br />' . $ex->getMessage();
}
?>

first of all: thanks
I modified as your indication, but the result does not change, still gives me the same error.
protected $webserviceParameters = array(
'fields' => array(
'id_default_group' => array('xlink_resource' => 'groups'),
'id_lang' => array('xlink_resource' => 'languages'),
'newsletter_date_add' => array(),
'ip_registration_newsletter' => array(),
'last_passwd_gen' => array('setter' => null),
'secure_key' => array('setter' => null),
'deleted' => array(),
'passwd' => array('setter' => 'setWsPasswd'),
/** inizio modifica aggiunta per il webservice */
'date_add' => array(),
/** fine della modifica */
),
'associations' => array(
'groups' => array('resource' => 'group'),
)
);
I can not understand

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';

Yii - Sort Error while using Join query in CDbCriteria with CActiveDataProvider

Model Search Method
$criteria->alias = 'c';
$criteria->select = 'c.*,max(ca.date) AS lastactivity';
$criteria->join = 'LEFT JOIN tbl_contact_action AS ca ON (ca.contact_id=c.contact_id)';
$criteria->condition = 'c.status<>"Deleted"';
$criteria->group = 'c.contact_id';
$criteria->order = 'lastactivity DESC';
$sort = new CSort;
$sort->defaultOrder = array('lastactivity' => CSort::SORT_DESC); //'name ASC';
$sort->attributes = array(
'name' => 'name',
'email' => 'email',
'status' => 'status',
'createdon' => 'createdon',
'lastactivity' => 'lastactivity',
);
$sort->applyOrder($criteria);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => $sort,
));
Basically, I have a 1:n relationship where in I need only latest record from child table. The parent table data will be displayed based on the comment that is done latest in child table. How to make this field sortable ?
Error
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'c.lastactivity' in 'order clause'.
Just a theory:
because you have a join with together sql, all the data will be together in 1 result. I am not sure if you can still use $data->ca->date because your data is not a known active record type.
Try putting
$criteria->select = 'maintable.*,ca.date as ca_date';
then you should be able to use
array(
'header' => 'Last Activity',
'class' => 'gridDataColumn',
'value' => '$data->ca_date',
),
Below is the Model which will allow to have a custom/computational field that will be SORTABLE. Instead of simply writing 'lastactivity'=>'lastactivity' in sort array, passing whole array did the trick for me. Hope it helps someone :)
class Contact extends CActiveRecord {
public $verifyCode;
public $lastactivity;
public static function model($className = __CLASS__) {
return parent::model($className);
}
public function tableName() {
return '{{contact}}';
}
public function rules() {
return array(
array('name, email, subject, message', 'required', 'message' => Yii::t('app', 'MSG_ATTRIBUTE_BLANK')),
array('email', 'email'),
array('verifyCode', 'CaptchaExtendedValidator', 'allowEmpty' => !CCaptcha::checkRequirements(), 'on' => 'fContact'),
array('name, email,subject,message,lastactivity', 'safe', 'on' => 'search'),
array('name, subject, email, message, status,createdon,updatedon,verifyCode,lastactivity', 'safe'),
);
}
public function relations() {
return array(
'ca' => array(self::HAS_MANY, 'ContactAction', 'contact_id'),
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('name', CommonFunctions::escapeOperator($this->name), true, 'OR');
$criteria->compare('subject', CommonFunctions::escapeOperator($this->subject), true, 'OR');
$criteria->compare('email', CommonFunctions::escapeOperator($this->email), true, 'OR');
$criteria->compare('status', CommonFunctions::escapeOperator($this->status), true,'OR');
$lastactivity_sql = '(select max(date) from tbl_contact_action ca where ca.contact_id=t.contact_id)';
$criteria->select = array('*', $lastactivity_sql . ' as lastactivity');
$criteria->addCondition('status<>"Deleted"');
$criteria->compare($lastactivity_sql, $this->lastactivity);
$sort = new CSort;
$sort->defaultOrder = array('lastactivity' => CSort::SORT_DESC); //'title ASC';
$sort->attributes = array(
'name' => 'name',
'email' => 'email',
'status' => 'status',
'createdon' => 'createdon',
'lastactivity' => array(
'asc' => 'lastactivity ASC',
'desc' => 'lastactivity DESC',
),
);
$sort->applyOrder($criteria);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => $sort,
'pagination' => array(
'pageSize' => Yii::app()->user->getState('contactPageSize', Yii::app()->params['RECORDPERPAGE_ADMIN']),
'currentPage' => Yii::app()->user->getState('Contact_page', 0),
),
));
}
}

Rename nama in upload ZF2 + AWS S3

How can I rename the name of a file before to upload zf2 and Amazon S3?
This is my code:
$files = $request->getFiles();
$bucketname = 'mybucket';
$result = $aws->putObject(array(
'Bucket' => $bucketname,
'Key' => 'user/5/'.$files['image-file']['name'],
'Body' => EntityBody::factory(fopen($files['image-file']['tmp_name'], 'r')),
'ACL' => CannedAcl::PUBLIC_READ,
'ContentType' => 'image/jpeg'
));
I can not use the module https://github.com/aws/aws-sdk-php-zf2
This is a working example t upload the image in zf2,rename it and save to database
namespace Admin\Form;
use Zend\Form\Form;
class SubcategoryimageForm extends Form
{
public function __construct($name = null)
{
parent::__construct('Subcategoryimage');
$this->setAttribute('method', 'post');
$this->setAttribute('enctype','multipart/form-data');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden',
),
));
$this->add(array(
'name' => 'subcategory_link_id',
'attributes' => array(
'type' => 'hidden',
),
));
$this->add(array(
'name' => 'alt',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Alt Text',
),
));
$this->add(array(
'name' => 'fileupload',
'attributes' => array(
'type' => 'file',
),
'options' => array(
'label' => 'File Upload',
),
));
$this->add ( array (
'name' => 'detail',
'attributes' => array (
'type' => 'textarea'
),
'options' => array (
'label' => 'Detail'
)
) );
$this->add ( array (
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'active',
'tabindex' => 3,
'options' => array (
'label' => 'Active',
'use_hidden_element' => true,
'checked_value' => '1',
'unchecked_value' => '0'
)
) );
$this->add(array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'location',
'options' => array(
'label' => 'Please choose one of the choices',
'value_options' => array(
'1' => 'flag',
'2' => 'landing',
'3' => 'home page',
),
),
'attributes' => array(
'value' => '1' //set checked to '1'
)
));
$this->add ( array (
'name' => 'submit',
'type' => 'Submit',
'tabindex' => 5,
'size' => 20,
'required' => false,
'attributes' => array (
'value' => 'Upload File',
'id' => 'submitbutton'
)
) );
}
}
In your controller
//inculde the imagine modules
use Zend\Validatior\File\Size;
use Imagine\Gd\Imagine;
use Imagine\Image\Box;
use Imagine\Image\Point;
public function imageAction()
{
$id = ( int ) $this->params ()->fromRoute ( 'id', 0 );
if (! $id) {
return $this->redirect ()->toRoute ( 'category' );
}
$form = new SubcategoryimageForm();
$form->get ( 'subcategory_link_id' )->setAttribute ( 'value', $id );
$request = $this->getRequest();
if ($request->isPost()) {
// Make certain to merge the files info!
$image = new Subcategoryimage();
$form->setInputFilter($image->getInputFilter());
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$size = new \Zend\Validator\File\ImageSize(array(
'minWidth' => 30, 'minHeight' => 30,
'maxWidth' => 1024, 'maxHeight' => 920,
)); //minimum bytes filesize
$isImage = new \Zend\Validator\File\IsImage();
$mimeType = new \Zend\Validator\File\MimeType(array('image/gif', 'image/jpg','image/jpeg','image/png','enableHeaderCheck' => true));
$adapter = new \Zend\File\Transfer\Adapter\Http();
$adapter->setValidators(array($size), $post['fileupload']['name']);
$adapter->setValidators(array($isImage), $post['fileupload']['name']);
$adapter->setValidators(array($mimeType), $post['fileupload']['name']);
if (!$adapter->isValid()){
$dataError = $adapter->getMessages();
$error = array();
foreach($dataError as $key=>$row)
{
$error[] = $row;
}
$form->setMessages(array('fileupload'=>$error ));
$messages = $form->getMessages();
return $this->redirect ()->toRoute ( 'category' );
// print_r($messages);die('file errors');
} else {
//$adapter->setDestination(dirname(__DIR__).'imageurltosaveimage/');
$adapter->setDestination('imagepathtosave');
if ($adapter->receive($post['fileupload']['name'])) {
$image->exchangeArray($form->getData());
switch(strtolower($_FILES['fileupload']['type']))
{
case 'image/jpeg':
$filename = imagecreatefromjpeg('imagepath/'.$post['fileupload']['name']);
break;
case 'image/png':
$filename = imagecreatefrompng('imagepath/'.$post['fileupload']['name']);
break;
case 'image/gif':
$filename = imagecreatefromgif('imagepath/'.$post['fileupload']['name']);
break;
default:
exit('Unsupported type: '.$_FILES['fileupload']['type']);
}
ob_start();
imagejpeg($filename);
// large image
$large = base64_encode(ob_get_contents()); // returns output
$mainimgWidth = imagesx($filename);
$mainimgHeight = imagesy($filename);
$thumbWidth = intval($mainimgWidth / 4);
$thumbHeight = intval($mainimgHeight / 4);
$new = imagecreatetruecolor($thumbWidth, $thumbHeight);
$backgroundColor = imagecolorallocate($new, 255, 255, 255);
imagefill($new, 0, 0, $backgroundColor);
imagecopyresampled($new, $filename, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $mainimgWidth, $mainimgHeight);
/** Catch the imagedata */
ob_start();
imagejpeg($new);
$data = ob_get_clean();
// Destroy resources
imagedestroy($filename);
imagedestroy($new);
// Set new content-type and status code
$thumb = base64_encode($data);
// imagine library was intsalled by the composer in the test server by amarjit
ob_end_clean();
$imagine = new Imagine();
//rename files
$filedata = array(
'id' => $post ['id'],
'subcategory_link_id' => $post ['subcategory_link_id'],
'alt' => $post ['alt'],
'detail' => $post ['detail'],
'active' => $post ['active'],
'location' => $post ['location'],
'thumb' => $thumb,
'large' => $large,
'created' => date('Y-m-d H:i:s'),
'createdby' => 1,
);
$id = $this->getImageTable ()->save ( $filedata );
$imagine->open('ipathofimage/'.$post['fileupload']['name'])
->save('pathtosaveimages/newnameofimage-'.$id.'.jpg');
/**
* delete the origional uploaded file;
*/
unlink('pathtoimage/'.$post['fileupload']['name']);
return $this->redirect ()->toRoute ( 'category' );
}
}
}else{
$messages = $form->getMessages();
}
}
return array (
'id' => $id,
'form' => $form,
'entities' => $this->getImageTable ()->getImageContents($id),
);
}
To get the image from database
use below code in your action
public function getlandingimageAction()
{
$id = ( int ) $this->params ()->fromRoute ( 'id', 0 );
if (! $id) {
return $this->redirect ()->toRoute ( 'category' );
}
try {
$thumb = $this->getImageTable ()->getImage ( $id );
} catch ( \Exception $ex ) {
return $this->redirect ()->toRoute ( 'category', array (
'action' => 'index'
) );
}
$image = base64_decode($thumb);
/** check if the image is db */
if($image!=null)
{
$db_img = imagecreatefromstring($image);
Header("Content-type: image/jpeg");
imagejpeg($db_img);
}
else
{
/** check if the image is upload dir */
$url= "path/imagename".$id.'.jpg';
if(file_exists($url))
{
$db_img = imagecreatefromjpeg($url);
Header("Content-type: image/jpeg");
imagejpeg($db_img);
exit;
}
/** handle if the image does not exit */
/**
* This needs to be changed from t
*/
$imgurl= "paaathofimage/";
Header("Content-type: image/gif");
$i=imagecreatefromgif($imgurl."/images/noimg.gif");
imagegif($i);
}
exit;
}

Invalid type given. String expected - Zend Framework 2

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...

Drupal 7 Form Invalid foreach with tableselect EDIT - How to delete selected rows from tableselect

What I am trying to do is create a selectlist using the form API, where a user can select rows and press a delete button that deletes the selected rows from the database and reloads the table with a conformation that those selected had been deleted. With my current code, when I hit the delete button I get this error:
Warning: Invalid argument supplied for foreach() in form_execute_handlers() (line 1431 of C:\xampp\htdocs\amaware\includes\form.inc).
Here is the code:
/**
* Implements hook_menu().
*/
function smsfeed_menu() {
$items = array();
$items['admin/config/content/smsfeed'] = array(
'title' => 'SMS Messages and Newsletters',
'description' => 'Edit the Setting for the SMS Feed and Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('smsfeed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/content/smsfeed/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/config/content/smsfeed/newsletter'] = array(
'title' => 'Newsletter',
'page callback' => 'drupal_get_form',
'page arguments' => array('newsletter_table_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 2,
);
$items['admin/config/content/smsfeed/feed'] = array(
'title' => 'SMS Feed',
'page callback' => 'drupal_get_form',
'page arguments' => array('feed_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['admin/config/content/smsfeed/questions'] = array(
'title' => 'Questions',
'page callback' => 'drupal_get_form',
'page arguments' => array('questions_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_LOCAL_TASK,
'weigth' => 4,
);
return $items;
}
/**
* Page callback: SMS Settings
*
* #see smsfeed_menu()
*/
function smsfeed_form($form, &$form_state) {
$form['response_time'] = array(
'#type' => 'textfield',
'#title' => t('Response Time (In Days)'),
'#default_value' => variable_get('response_time', 3),
'#size' => 2,
'#maxlength' => 2,
'#description' => t('The response time, in days, that users should expect.'),
);
$form['feed_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Feed Keyword'),
'#default_value' => variable_get('feed_keyword', 'FEED'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to have their message moderated and added to the website feed.'),
);
$form['join_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Join Keyword'),
'#default_value' => variable_get('join_keyword', 'JOIN'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be added to the newsletter list.'),
);
$form['quit_keyword'] = array(
'#type' => 'textfield',
'#title' => t('Quite Keyword'),
'#default_value' => variable_get('quit_keyword', 'QUIT'),
'#size' => 10,
'#maxlength' => 10,
'#description' => t('The keyword users should text to be removed from the newsletter list.'),
);
return system_settings_form($form);
}
/**
* Page Callback Newsletter
*/
function newsletter_table_form($form, $form_state) {
$rows = array();
$header = array(t('User Name'), t('User Number'), t('User E-mail'),);
$query = db_select('sms_newsletter');
$query->fields('sms_newsletter', array('name', 'number', 'email',))
->orderBy('name', 'ASC');
$results = $query->execute();
foreach ($results as $line) {
$rows[] = array(
$line->name,
$line->number,
$line->email,
);
}
$form['table'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('No users found'),
);
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
return $form;
}
function newsletter_table_form_delete ($form, &$form_state) {
foreach ($form_state['values']['collections'] as $key => $value) {
if ($value) {
$delete = db_delete('sms_newsletter')
-> execute();
}
}
}
Any help is deeply appreciated.
EDIT:
I've edited my news_letter_table_form to read:
function newsletter_table_form_delete ($form, $form_state) {
foreach (($form_state['values']['table']) as $rows) {
//$delete = db_delete('sms_newsletter')
//-> execute();
drupal_set_message ('' . $rows . '');
//drupal_set_message ('' . $form_state['values']['table'] . '');
}
}
And the new output leaves me puzzled as to how I'd identify selected rows, and delete them from the database. Using the above newsletter_table_form_delete I get the following output:
If I select the top row nothing happens
If I select the second row the output is 1
If I select the third row the output is 2 and so on
If I select multiple rows the output is an unordered html list of the selected rows.
I'm curious now how I could take what I have now and change it so I can delete selected rows from the database.
Thanks again!
Try changing
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => 'newsletter_table_form_delete'
);
to
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delect Selected'),
'#submit' => array('newsletter_table_form_delete') // <-- make this an array
);
Based on the additional info added in your question edit, I noticed that your tableselect is built without specifying array keys like:
foreach ($results as $line) {
$rows[] = array( // <-- No array keys specified here
$line->name,
$line->number,
$line->email,
);
}
Since there were no keys specified, the default by PHP is a 0-based index. That is why you are getting no results for the top row, 1 for the second row, and so on.
See the documentation for the tableselect element for an example.
I don't know what your database table structure looks like but you will probably need to query the Primary Key for the table and include it as array keys to your $rows array. That way, when you process the data in your delete function, you have the Primary Key of the row you want to delete and delete it.
For me this wasn't clear straight away so.
I would just like to add that in the end what nmc was saying is you should construct your rows like this, where you add a key to row.
foreach ($results as $line) {
$rows[$line->name] = array(
$line->name,
$line->number,
$line->email,
);