Magento saving multiselect in controller? - magento

$fieldset->addField('brand_id', 'multiselect', array(
'label' => Mage::helper('expertbrand')->__('Merk:'),
'name' => 'brand_id[]',
'values' => $aOptionsMerk,
));
I have this multiselect box with some 600 options. I would like to know how to save this in the controller?
I have tried everything and worked on this problem for 3 days now. Also on the internet I cannot find a correct anwser to this problem. Hoping someone here is able to help me because I'd really like to know!
My controller code:
public function saveAction() {
if ($data = $this->getRequest()->getPost()) {
if(isset($_FILES['filename']['name']) && $_FILES['filename']['name'] != '') {
try {
/* Starting upload */
$uploader = new Varien_File_Uploader('filename');
// Any extention would work
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
$uploader->setAllowRenameFiles(false);
// Set the file upload mode
// false -> get the file directly in the specified folder
// true -> get the file in the product like folders
// (file.jpg will go in something like /media/f/i/file.jpg)
$uploader->setFilesDispersion(false);
// We set media as the upload dir
$path = Mage::getBaseDir('media') . DS ;
$uploader->save($path, $_FILES['filename']['name'] );
} catch (Exception $e) {
}
//this way the name is saved in DB
$data['filename'] = $_FILES['filename']['name'];
}
/*
$brands=$data['brand_id'];
$t=count($brands);
$inhoud="";
$i=1;
foreach ($brands as $brand){
if ($t == $i){
$inhoud.=$brand;
} else {
$inhoud.=$brand." , ";
}
$i++;
}
//echo $inhoud;
// $br=array('brand_id');
$br=$inhoud;
$data['brand_id']=$br;
*/
//hier moet de loop komen
$id= $data['expert_id'];
$db1 = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $db1->query("SELECT name FROM expert where expert_id=$id");
$rows = $result->fetch(PDO::FETCH_ASSOC);
$data['name']=$rows['name'];
//$data['brand_id']=$_POST['brand_id'];
$model = Mage::getModel('expertbrand/expertbrand');
$model->setData($data)
->setId($this->getRequest()->getParam('id'));
try {
if ($model->getCreatedTime == NULL || $model->getUpdateTime() == NULL) {
$model->setCreatedTime(now())
->setUpdateTime(now());
} else {
$model->setUpdateTime(now());
}
$model->save();
//hier is het einde van de loop..
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('expertbrand')->__('Item was successfully saved'));
Mage::getSingleton('adminhtml/session')->setFormData(false);
if ($this->getRequest()->getParam('back')) {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
return;
}
$this->_redirect('*/*/');
return;
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setFormData($data);
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
return;
}
}
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('expertbrand')->__('Unable to find item to save'));
$this->_redirect('*/*/');
}
How should I save the optionsArray that is sent through the $_POST? Thanks in advance.

Add this to your saveAction in your Controller to convert the data to a string:
foreach ($data as $key => $value)
{
if (is_array($value))
{
$data[$key] = implode(',',$this->getRequest()->getParam($key));
}
}

To start:
You've declared the input as "brand_id[]", so you are looking for $data['brand_id'], which should be an array. In the commented code, you appear to use that data, but your current code only looks for $data['expert_id'], which doesn't seem to be the same thing.
Even if you change that line to $data['brand_id'], keep in mind that it is an array, so you'll need to be cognizant of that in queries.
You've got a bunch of logic in the controller that doesn't belong there. In an MVC app (of which Magento is a canonical example), most of that SQL logic (as well as the createdtime/updatedtime stuff) belongs in the model (probably expertbrand/expertbrand).
It's not clear how you defined expertbrand/expertbrand. Is this an EAV model? What is its definition? This is most likely the root of your problem, as you have to tell Magento about your EAV model for it to save like that.
Please fix those things (and clarify on the model code) and we can debug further if necessary.
Thanks,
Joe

its clear to me that the data is sent in an array. In order to fix that i created function that rewrites the array.
$brands=$data['brand_id'];
$t=count($brands);
$inhoud="";
$i=1;
foreach ($brands as $brand){
if ($t == $i){
$inhoud.=$brand;
}
else {
$inhoud.=$brand." , ";
}
$i++;
}
//echo $inhoud;
// $br=array('brand_id');
$br=$inhoud;
$data['brand_id']=$br;
the DATA saved in the database would look something like this:
104 , 106 , 107 , 108
i do this cos i read somewhere that this was necessary to do so.
How ever when i open my edit field the only one which shows :
selected="selected" is the brand with the value 108 (the last one)
this is a problem because i need all 4 of them to be shown as selected.
Has this something to do in the way how i save this data ...not sure if the data should be saved as an array to show all selected="selected" fields in the edit
by the way the expert_id is something else and not an issue here i know the sql should be somewhere else but since i am still learning magento this was a quick a dirty method to fix a problem i had earlier...
all i want to know is how to store the array to show all values as an selected="selected" field in the edit form...Txs....
Ok i fixed the problem the data should be saved as
106,108,114,99
now everything is selected in the edit field strange nothing of this is to be found here on the internet hopefully it will be helpfull to other people dealing with the same problem

Related

Create or update rows Laravel

I try to update or create a table with data from request, on update it works, but on create I can do just for 1. So, if I have 4 new items, just 1 is saved, not sure why, and no errors. If I dump the request I have all values.
$answers = new LkpAnswer;
foreach ($request->items as $key => $item) {
if (isset($item['id'])) {
$answers->where('id', $item['id'])->update($item);
} else {
$answers->fill($item)->save();
}
}
Please Try the following code:
foreach ($request->items as $key => $item) {
if (isset($item['id'])) {
LkpAnswer::where('id', $item['id'])->update($item);
} else {
$answers = new LkpAnswer; //new up an empty model(object) then fill it with your array of data, and finally save it.
$answers->fill($item)->save();
}
}
This should be achievable neatly with built in methods:
foreach ($request->items as $item) {
LkpAnswer::updateOrCreate($item['id'],$item);
}
Make sure that the relevant fields are fillable - see mass assignment protection.

delete uploaded image in custom module

UPDATE
I'm updating the question as I solved one of the problem in this question. The original question is below the line.
I'm now able to see the preview of the image as the problem was with the below code
$fieldset->addField('banner', 'image', array(
'label' => Mage::helper('designer')->__('Banner'),
'required' => false,
'name' => 'banner',
));
where instead of image, file was written for the type of field. But now the problem is, I'm unable to delete the previous image. I do check the delete image checkbox but the file still remains there. Why its not deleting?
I'd created a module with module creator and able to save images. But when the next time I do want to edit the record it does not show the preview of the uploaded image or the delete checkbox.
Do I need to write additional code in my adminhtml tab form?
In your saveAction of you controller you need to check if the delete image checkbox is checked.
Eg.
if (isset($_FILES['checkcsv']['name']) && $_FILES['checkcsv']['name'] != '') {
try {
...
$uploader->save($path, $logoName);
save path to database
} catch (Exception $e) {
}
}
else if((isset($data['banner']['delete']) && $data['banner']['delete'] == 1)){
//can also delete file from fs
unlink(Mage::getBaseDir('media') . DS . $data['banner']['value']);
//set path to null and save to database
$data['banner'] = '';
}
Below code write in your save action of your controller
if (isset($data['image']['delete'])) {
Mage::helper('your_helper')->deleteImageFile($data['image']['value']);
}
$image = Mage::helper('your_helper')->uploadBannerImage();
if ($image || (isset($data['image']['delete']) && $data['image']['delete'])) {
$data['image'] = $image;
} else {
unset($data['image']);
}
Write below code in your helper
public function deleteImageFile($image) {
if (!$image) {
return;
}
try {
$img_path = Mage::getBaseDir('media'). "/" . $image;
if (!file_exists($img_path)) {
return;
}
unlink($img_path);
} catch (Exception $exc) {
echo $exc->getTraceAsString();
}
}
Replace your_helper to your actual helper class

Search is not working for callback_column function in grocery crud

I have one table users in this i store 1 for website and 2 for domain and i display this table my code is,
$this->load->library('grocery_CRUD');
$crud = new grocery_CRUD();
$crud->set_table('users');
$crud->callback_column('listing_type',array($this,'type_change'));
$output = $crud->render();
return $output;
and my callback_column function,
public function type_change($value, $row)
{
if($value == 1)
{
return 'Website';
}
if($value == 2)
{
return 'Domain Name';
}
}
so,for this search is not working for listing type if anyone have solution for this please help me , thank you.
You can change the theme use ex: datatables the search is client-side on visible data.
Attention: This solutions maybe not be good for a big number of row.

Magento Custom Sort Option

How do I add custom sort option in Magento. I want to add Best Sellers, Top rated and exclusive in addition to sort by Price. Please help
For Best Sellers
haneged in code/local/Mage/Catalog/Block/Product/List/Toolbar.php method setCollection to
public function setCollection($collection) {
parent::setCollection($collection);
if ($this->getCurrentOrder()) {
if($this->getCurrentOrder() == 'saleability') {
$this->getCollection()->getSelect()
->joinLeft('sales_flat_order_item AS sfoi', 'e.entity_id = sfoi.product_id', 'SUM(sfoi.qty_ordered) AS ordered_qty')
->group('e.entity_id')->order('ordered_qty' . $this->getCurrentDirectionReverse());
} else {
$this->getCollection()
->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
}
}
return $this;
}
After setCollection I added this method:
public function getCurrentDirectionReverse() {
if ($this->getCurrentDirection() == 'asc') {
return 'desc';
} elseif ($this->getCurrentDirection() == 'desc') {
return 'asc';
} else {
return $this->getCurrentDirection();
}
}
And finally I changed mehod setDefaultOrder to
public function setDefaultOrder($field) {
if (isset($this->_availableOrder[$field])) {
$this->_availableOrder = array(
'name' => $this->__('Name'),
'price' => $this->__('Price'),
'position' => $this->__('Position'),
'saleability' => $this->__('Saleability'),
);
$this->_orderField = $field;
}
return $this;
}
for Top rated
http://www.fontis.com.au/blog/magento/sort-products-rating
try above code.
for date added
Magento - Sort by Date Added
i am not associate with any of the above link for any work or concern it is just for knowledge purpose and to solve your issue.
hope this will sure help you.
Thanks for your answer, Anuj, that was the best working module I could find so far.
Just add an extra bit to your code in order to solve no pagination caused by 'group by'
Copy '/lib/varien/data/collection/Db.php'
To 'local/varien/data/collection/Db.php'.
Change the getSize function to
public function getSize()
{
if (is_null($this->_totalRecords)) {
$sql = $this->getSelectCountSql();
//$this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams); //============================>change behave of fetchOne to fetchAll
//got array of all COUNT(DISTINCT e.entity_id), then sum
$result = $this->getConnection()->fetchAll($sql, $this->_bindParams);
foreach ($result as $row) {//echo'<pre>'; print_r($row);
$this->_totalRecords += reset($row);
}
}
return intval($this->_totalRecords);
}
Hope it could help anyone.
update
The filter section need to be updated as well, otherwise just showing 1 item on all filter.
and the price filter will not be accurate.
What you need to do it to modify core/mage/catalog/model/layer/filter/attribute.php and price.php
attribute.php getCount() on bottom
$countArr = array();
//print_r($connection->fetchall($select));
foreach ($connection->fetchall($select) as $single)
{
if (isset($countArr[$single['value']]))
{
$countArr[$single['value']] += $single['count'];
}
else
{
$countArr[$single['value']] = $single['count'];
}
}
//print_r($countArr);//exit;
return $countArr;
//return $connection->fetchPairs($select);
Price.php getMaxPrice
$maxPrice = 0;
foreach ($connection->fetchall($select) as $value)
{
if (reset($value) > $maxPrice)
{
$maxPrice = reset($value);
}
}
return $maxPrice;
If you are having the same problem and looking for the question, you will know what I meant.
Good luck, spent 8 hours on that best sell function.
Update again,
just found another method to implement
using cron to collect best sale data daily saved in a table that includes product_id and calculated base sale figure.
then simply left join, without applying 'group by'
that means core functions do not need to changed and speed up the whole sorting process.
Finally finished! hehe.
To sort out pagination issue for custom sorting collection rewrite the resource model of it's collection from
app\code\core\Mage\Catalog\Model\Resource\Product\Collection.php
And modify below method from core
protected function _getSelectCountSql($select = null, $resetLeftJoins = true)
{
$this->_renderFilters();
$countSelect = (is_null($select)) ?
$this->_getClearSelect() :
$this->_buildClearSelect($select);
/*Added to reset count filters for Group*/
if(count($countSelect->getPart(Zend_Db_Select::GROUP)) > 0) {
$countSelect->reset(Zend_Db_Select::GROUP);
}
/*Added to reset count filters for Group*/
$countSelect->columns('COUNT(DISTINCT e.entity_id)');
if ($resetLeftJoins) {
$countSelect->resetJoinLeft();
}
return $countSelect;
}
Above will solve count issue for custom sorting collection.

How do I split my HABTM tags?

I want to take a field in the add form of the Post, explode it at the spaces, and save each word as a Tag, which HasAndBelongsToMany Post. So, for each unrecognized tag, it will create a new one, but if the Tag already exists, it will only create a new reference in the posts_tags tables. I've tried using saveAll, saveAssociated, and few foreach hacks, and I am not exactly sure where it went wrong, but I cannot figure out how to save the associate data. Any sort of outline of how to get the tag data from the form to the database would be appreciated.
//in model
public function parseTags($data) {
$str = $data['Tag'][0]['title'];
$tags = explode('',$str);
for ($i=0; $i<count($tags); $i++) {
$data['Tag'][$i]['title'] = $tags[$i];
}
return $data;
}
//in view
echo $this->Form->input('Tag.0.title',array('label'=>'Tags'));
//in controller
public function add() {
if ($this->request->is('post')) {
$this->Question->create();
$this->request->data['Question']['user_id'] = $this->Auth->user('id');
$this->request->data = $this->Question->parseTags($this->request->data);
if ($this->Question->saveAll($this->request->data)) {
$this->Session->setFlash(__('The question has been saved'), 'default', array('class' => 'success'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The question could not be saved. Please, try again.'));
}
}
$users = $this->Question->User->find('list');
$this->set(compact('users'));
}
You must first check if Tag saved before or not, if not saved, You can save it. So before you save your model ,all of your tags is saved before.
something like this:
/* $tag_list is exploded tags*/
foreach ($tag_list as $tag) {
$res = $this->Tag->find('first', array('conditions' => array('Tag.name' => $tag)));
if ($res != array()) {
$tag_info[] = $res['Tag']['id'];
} else {
$this->Tag->create();
$this->Tag->save(array('Tag.name' => $tag));
$tag_info[] = sprintf($this->Tag->getLastInsertID());
}
}
$this->model->data['Tag']['Tag'] = $tag_info;

Resources