This function sets up the Magento Grid to display a list of filenames with a corresponding 'Delete' action.
The problem is the Delete action never passes the parameter, 'filename.' (See http://www.premasolutions.com/content/magento-manage-category-product-grid-edit-link) I have TESTDUMP for verification but it never prints on the next page.
Is 'params' a legitimate action of 'addColumn->actions->url'?
Update: Added the construct and prepare collection for controller. Maybe it's because of the type of Collection I'm using?
class Rogue_Googlemerchant_Block_Adminhtml_Exporter_Grid
Rogue_Googlemerchant_Block_Adminhtml_Exporter_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
public function __construct()
{
parent::__construct();
$this->setId('googlemerchantGrid');
// This is the primary key of the database
$this->setDefaultSort('filename');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
}
protected function _prepareCollection()
{
$basePath = Mage::getBaseDir('base');
$feedPath = $basePath . '/opt/googlemerchant/';
$errPath = $basePath . '/var/log/googlemerchant/';
$flocal = new Varien_Io_File();
$flocal->open(array('path' => $feedPath));
$dataCollection = new Varien_Data_Collection();
foreach ($flocal->ls() as $item) {
$dataObject = new Varien_Object();
$dataObject->addData(
array(
'filename' => $item['text'],
'size' => $item['size'] / 1000 . ' kb',
'date_modified'=> $item['mod_date']
)
);
$dataCollection->addItem($dataObject);
}
$this->setCollection($dataCollection);
return parent::_prepareCollection();
}
protected function _prepareColumns()
{
$this->addColumn('filename', array(
'header' => Mage::helper('googlemerchant')->__('File'),
'align' =>'left',
'index' => 'filename',
'width' => '200px',
));
$this->addColumn('action', array(
'header' => Mage::helper('googlemerchant')->__('Action'),
'width' => '50px',
'type' => 'action',
// 'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('googlemerchant')->__('Delete'),
'url' =>
array(
'base' => '*/*/delete',
'params' => array('filename' => 'TESTDUMP')
),
'field' => 'filename'
)
),
'filter' => false,
'sortable' => false,
// 'index' => 'filename',
// 'is_system' => true,
));
}
}
class Rogue_Googlemerchant_Adminhtml_ExporterController
class Rogue_Googlemerchant_Adminhtml_ExporterController extends Mage_Adminhtml_Controller_Action
{
public function deleteAction()
{
$filename = $this->getRequest()->getParam('filename');
$basePath = Mage::getBaseDir('base');
$feedPath = $basePath . '/opt/googlemerchant/';
$errPath = $basePath . '/var/log/googlemerchant/';
$flocal = new Varien_Io_File();
$flocal->open(array('path' => $feedPath));
d($filename);
if ($filename) {
try{
$flocal->rm($filename);
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('googlemerchant')->__('The file has been deleted.'));
$this->_redirect('*/*/');
}
catch (Mage_Core_Exception $e) {
$this->log($e);
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
$this->_redirect('*/*/index');
return;
}
}
die('here');
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Unable to find the file to delete.'));
$this->_redirect('*/*/');
}
}
The getter of the action column is used on the collection items to retrieve the argument value for the field parameter.
I'm not sure why you are specifying the filename hardcoded or if that should work, but if you add the column configuration
'getter' => 'getFilename'
and remove the params from the action it should work.
Related
Here is my route:
'router' => array(
'routes' => array(
'upload' => array(
'type' => 'segment',
'options' => array(
'route' => '/products/upload[/:products]',
'defaults' => array(
'controller' => 'Products\Controller\Upload',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'uploadsuccessful' => array(
'type' => 'literal',
'options' => array(
'route' => '/uploadsuccessful',
'defaults' => array(
'controller' => 'Products\Controller\Upload',
'action' => 'successful'
),
),
),
),
),
),
);
I am trying to call this route several times from different view scripts giving different [/:products] parameter.
Upload Shoes Product Image
Upload Trainers Product Image
Upload Hat Product Image
Here is my Controller code.
<?php
namespace Products\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Products\Form\UploadForm;
class UploadController extends AbstractActionController
{
protected $_dir = null;
public function indexAction()
{
$products = $this->params()->fromRoute('products');
$config = $this->getServiceLocator()->get('Config');
$fileManagerDir =$config['file_manager']['dir'];
$this->_dir = realpath($fileManagerDir) .
DIRECTORY_SEPARATOR .
$products;
if (!is_dir($this->_dir)) {
//read, write, execute
mkdir($this->_dir, 0777);
}
$form = new UploadForm($this->_dir, 'upload-form');
$request = $this->getRequest();
if ($request->isPost()) {
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$data = $form->getData();
$this->setFileNames($data);
return $this->redirect()->toRoute('upload/uploadsuccessful', array('products' =>$products));
}
}
return new ViewModel(array('form' => $form));
}
public function successfulAction()
{
$file = array();
$flashMessenger = $this->flashMessenger();
if ($flashMessenger->hasMessages()) {
foreach($flashMessenger->getMessages() as $key => $value) {
$file = $value;
}
}
return new ViewModel(array('file' => $file));
}
protected function setFileNames($data)
{
unset($data['submit']);
foreach ($data['image-file'] as $key => $file) {
rename($file['tmp_name'], $this->_dir . DIRECTORY_SEPARATOR . $file['name']);
}
}
}
I think the idea is clear: for each [/:products] parameter I tried to make separate folder with given name in $fileManagerDir.
But, there is a problem. When I click on button upload ($request->isPost() == true) parameter $products becomes null and uploaded files don't go to appropriate folders. Also I am not able to redirect to successful action - the error appears "missing parameter" because $products is null.
In your view script the upload buttons are href links. This will result in a GET REQUEST being sent to the controller and not a POST and no FILES will be present either. Unless that is, you are intercepting the click event with external JS which you haven't mentioned here. The route url's should be in the form action attribute. The submit buttons should be buttons not links (unless you are using JS not mentioned here). Make sure the form method is set to POST.
Something like:
<form action="<?php echo $this->url('upload', array('products' =>'shoes')); ?>" method="post" enctype="multipart/form-data">
You'll need to deal with the dynamic action using JS or redesign your routing.
I am a Magento beginner so please bear with me...
I am creating a simple extension for my site to add a custom field to my Tags in adminhtml. The custom field is just a number which I need to identify a specific Z-block (cms block extension) so that I can access it as a widget and show it on the frontend in the Tag "category".
I have created a custom module which is working: I set a field in the form using $fieldset and have extended TagController.php, both of which are being used (I made a simple trial to see whether or not they had been recognized). However, I do not know how to go about saving my custom field to DB (whether amending saveAction is enough, and I haven't done it properly, or if I need to add a custom Model or sql install).
Sorry for the "basic" question but I'm new at this, and have mostly done frontend dev (so my extension knowledge is simply limited).
Thank you to anyone who can help...
Claudia
NEW TAG FORM:
public function __construct()
{
parent::__construct();
$this->setId('tag_form');
$this->setTitle(Mage::helper('tag')->__('Block Information'));
}
/**
* Prepare form
*
* #return Mage_Adminhtml_Block_Widget_Form
*/
protected function _prepareForm()
{
$model = Mage::registry('tag_tag');
$form = new Varien_Data_Form(
array('id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post')
);
$fieldset = $form->addFieldset('base_fieldset',
array('legend'=>Mage::helper('tag')->__('General Information')));
if ($model->getTagId()) {
$fieldset->addField('tag_id', 'hidden', array(
'name' => 'tag_id',
));
}
$fieldset->addField('form_key', 'hidden', array(
'name' => 'form_key',
'value' => Mage::getSingleton('core/session')->getFormKey(),
));
$fieldset->addField('store_id', 'hidden', array(
'name' => 'store_id',
'value' => (int)$this->getRequest()->getParam('store')
));
$fieldset->addField('name', 'text', array(
'name' => 'tag_name',
'label' => Mage::helper('tag')->__('Tag Name'),
'title' => Mage::helper('tag')->__('Tag Name'),
'required' => true,
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('zblock', 'text', array(
'name' => 'zblock_id',
'label' => Mage::helper('tag')->__('Z-Block Id'),
'title' => Mage::helper('tag')->__('Z-Block Id'),
'required' => true,
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('status', 'select', array(
'label' => Mage::helper('tag')->__('Status'),
'title' => Mage::helper('tag')->__('Status'),
'name' => 'tag_status',
'required' => true,
'options' => array(
Mage_Tag_Model_Tag::STATUS_DISABLED => Mage::helper('tag')->__('Disabled'),
Mage_Tag_Model_Tag::STATUS_PENDING => Mage::helper('tag')->__('Pending'),
Mage_Tag_Model_Tag::STATUS_APPROVED => Mage::helper('tag')->__('Approved'),
),
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('base_popularity', 'text', array(
'name' => 'base_popularity',
'label' => Mage::helper('tag')->__('Base Popularity'),
'title' => Mage::helper('tag')->__('Base Popularity'),
'after_element_html' => ' ' . Mage::helper('tag')->__('[STORE VIEW]'),
));
if (!$model->getId() && !Mage::getSingleton('adminhtml/session')->getTagData() ) {
$model->setStatus(Mage_Tag_Model_Tag::STATUS_APPROVED);
}
if ( Mage::getSingleton('adminhtml/session')->getTagData() ) {
$form->addValues(Mage::getSingleton('adminhtml/session')->getTagData());
Mage::getSingleton('adminhtml/session')->setTagData(null);
} else {
$form->addValues($model->getData());
}
$this->setForm($form);
return parent::_prepareForm();
}
NEW CONTROLLER:
public function saveAction()
{
if ($postData = $this->getRequest()->getPost()) {
if (isset($postData['tag_id'])) {
$data['tag_id'] = $postData['tag_id'];
}
$data['name'] = trim($postData['tag_name']);
$data['zblock'] = $postData['zblock_id'];
$data['status'] = $postData['tag_status'];
$data['base_popularity'] = (isset($postData['base_popularity'])) ? $postData['base_popularity'] : 0;
$data['store'] = $postData['store_id'];
if (!$model = $this->_initTag()) {
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Wrong tag was specified.'));
return $this->_redirect('*/*/index', array('store' => $data['store']));
}
$model->addData($data);
if (isset($postData['tag_assigned_products'])) {
$productIds = Mage::helper('adminhtml/js')->decodeGridSerializedInput(
$postData['tag_assigned_products']
);
$model->setData('tag_assigned_products', $productIds);
}
try {
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('The tag has been saved.'));
Mage::getSingleton('adminhtml/session')->setTagData(false);
if (($continue = $this->getRequest()->getParam('continue'))) {
return $this->_redirect('*/tag/edit', array('tag_id' => $model->getId(), 'store' => $model->getStoreId(), 'ret' => $continue));
} else {
return $this->_redirect('*/tag/' . $this->getRequest()->getParam('ret', 'index'));
}
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setTagData($data);
return $this->_redirect('*/*/edit', array('tag_id' => $model->getId(), 'store' => $model->getStoreId()));
}
}
return $this->_redirect('*/tag/index', array('_current' => true));
}
The custom field I'm trying to add is "zblock"...thanks and, again, bear with me! :)
First add the field in database table.
For example if you want to add in your custom table.
ALTER TABLE myCustomModuleTable ADD COLUMN 'myCustomField' int(10);
Thenafter, In your controller action take the model object of that table and set the field.
If you are adding data in existing table row:
$value = 6;
$rowInWhichIWantToSave = Mage:getModel('companyname/modulename')->load($rowId);
$rowInWhichIWantToSave->setData('myCustomField',$value)->save();
If you are adding a new row:
$value = 6;
$rowInWhichIWantToSave = Mage:getModel('companyname/modulename');
$rowInWhichIWantToSave->setData('myCustomField',$value)->save();
Hope this helps!!
I have a Form which contains a formCollection with a select element that I want to populate with values (from SQL) depending on a POST param.
Passing this param from controller to form wasn't a problem but now I can't find a way to set/read that param in target_element of formCollection. Any ideas on how make that work?
Here's my code:
Controller
class MyController extends AbstractActionController{
public function indexAction()
{
$form = $this->serviceLocator->get('FormElementManager')->get('Module\Form\myForm');
$form->init([
'param' => $this->params()->fromPost('param')
]);
}
}
Form
class myForm extends Form
{
private $sm;
public function __construct($sm = null)
{
parent::__construct();
$this->sm = $sm;
}
public function init($params=[])
{
$this->add([
'name' => 'choices',
'type' => 'Zend\Form\Element\Collection',
'options' => [
'label' => 'SelectLabel',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'template_placeholder' => '__placeholder__',
'target_element' => [
'type' => 'Module\Form\choicesFieldset',
'options' => [
'param' => isset($params['param']) ? $params['param'] : 0,
]
],
],
]);
}
}
Fieldset
class choicesFieldset extends Fieldset{
private $sm;
public function __construct($sm = null){
parent::__construct();
$this->sm = $sm;
}
public function init(){
$param = $this->getOption('param');
$availableChoices = /* SQL_QUERY_BASED_ON_PARAM; */
$this->add([
'name' => 'choice_1',
'type' => 'Select',
'options' => [
'label' => 'First choice',
'value_options' => $availableChoices,
]
]);
}
}
Thanks in advance for your help.
All you would need to do is fetch the Request instance from the service manager; check the parameter you want and then 'inject' it into the form.
It would make more sense to do so in the form factory; rather than repeat yourself within controllers.
For example:
public function getFormElementConfig()
{
return array(
'factories' => array(
'MyModule\Form\MyForm' => function($formElementManager) {
$serviceManager = $formElementManager->getServiceLocator();
$request = $serviceManager->get('Request');
// defaults to 0 if not set
$param = $request->getPost('the_posted_variable_name', 0);
$options = array(
'my_custom_option_name' => $param,
);
// You should maintain the Zend\Form\Element::__construct() method signuture
// as it allows for the 'options' to be passed in.
// Alternatively you could use $form->setOption('param', $options)
// and inject the options as a soft dependency
$form = new Form\MyForm('my_form', $options, $serviceManager);
// ... other form stuff here
return $form;
},
),
);
}
Now you can use the option within the form using:
$param = $this->getOption('my_custom_option_name');
I'd like to be able to have a date/calendar selector in one of my admin grids when editing/adding an item. How do I code a calendar-style format?
I've tried changing the "format" parameter to "date" with no success.
I will include code and snapshots for clarification. Some of the code comes from the existing project, some comes from tutorials. I don't feel like a master of this code by any means, so any suggestions are welcome.
PHP 5.4.25 Magento 1.8.1.0
The search section on my index seems to be working:
But I'd like to change the text field for "close date" to a calendar-picker:
Here is my code for ../Party/Block/Adminhtml/Party/Edit/Tab/Form.php:
class Foobar_Party_Block_Adminhtml_Party_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm() {
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset("party_form", array("legend" => Mage::helper("party")->__("Party information")));
/* Code for other columns */
$fieldset->addField("party_close_date", "date", array(
"label" => Mage::helper("party")->__("Close Date"),
'format' => 'date',
'name' => 'party_close_date',
'time' => 'true',
));
if (Mage::getSingleton("adminhtml/session")->getPartyData()) {
$form->setValues(Mage::getSingleton("adminhtml/session")->getPartyData());
Mage::getSingleton("adminhtml/session")->setPartyData(null);
} elseif (Mage::registry("party_data")) {
$form->setValues(Mage::registry("party_data")->getData());
}
return parent::_prepareForm();
}
}
Here is my code for ../Party/Block/Adminhtml/Party/Edit/Form.php:
<?php
class Foobar_Party_Block_Adminhtml_Party_Edit_Form extends Mage_Adminhtml_Block_Widget_Form {
protected function _prepareForm() {
$form = new Varien_Data_Form(array(
"id" => "edit_form",
"action" => $this->getUrl("*/*/save", array("id" => $this->getRequest()->getParam("id"))),
"method" => "post",
"enctype" => "multipart/form-data",
)
);
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
Here is my code for ../Party/Block/Adminhtml/Party/Grid.php:
<?php
class Foobar_Party_Block_Adminhtml_Party_Grid extends Mage_Adminhtml_Block_Widget_Grid {
public function __construct() {
parent::__construct();
$this->setId("partyGrid");
$this->setDefaultDir("ASC");
$this->setSaveParametersInSession(true);
}
protected function _prepareCollection() {
$collection = Mage::getModel("party/party")->getCollection();
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns() {
/* Code for other columns */
$this->addColumn("party_close_date", array(
"header" => Mage::helper("party")->__("Close Date"),
"type" => "datetime",
"index" => "party_close_data",
));
$this->addExportType('*/*/exportCsv', Mage::helper('party')->__('CSV'));
$this->addExportType('*/*/exportExcel', Mage::helper('party')->__('Excel'));
return parent::_prepareColumns();
}
public function getRowUrl($row) {
return $this->getUrl("*/*/edit", array("id" => $row->getId()));
}
}
I found the answer to my question!
I added 3 lines to my ..Edit/Tab/Form.php file.
I changed these lines...
$fieldset->addField("party_close_date", "date", array(
"label" => Mage::helper("party")->__("Close Date"),
'format' => Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
'name' => 'party_close_date',
'time' => 'true',
));
...to this:
$fieldset->addField("party_close_date", "date", array(
"label" => Mage::helper("party")->__("Close Date"),
'format' => Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT),
'after_element_html' => '<small>Comments</small>',
'tabindex' => 1,
'image' => $this->getSkinUrl('images/grid-cal.gif'),
'name' => 'party_close_date',
'time' => 'true',
));
There's a handy tutorial here that helped me out loads.
I have overridden the Mage_Adminhtml_Block_Sales_Order_Grid to add additionl 3 columns as follows.
Customer Email
Payment Type
Products ordered
My extended grid class is as follows.
<?php
class Wowmall_ExtendedGrid_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid
{
protected function _getCollectionClass()
{
return 'sales/order_grid_collection';
}
protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()
->joinLeft('sales_flat_order_payment', 'main_table.entity_id = sales_flat_order_payment.parent_id','method')
->join('customer_entity', 'main_table.customer_id = customer_entity.entity_id','email')
->join('sales_flat_order_item', 'main_table.entity_id = sales_flat_order_item.order_id','name')->distinct(true);
$collection->getSelect()->group('main_table.entity_id');
$this->setCollection($collection);
return $this;
}
protected function _prepareColumns()
{
// rest code...
$this->addColumn('email', array(
'header' => Mage::helper('sales')->__('Customer Email'),
'index' => 'email',
'type' => 'text',
));
$this->addColumn('method', array(
'header' => Mage::helper('sales')->__('Payment Type'),
'index' => 'method',
'type' => 'options',
'options' => array('verisign' => 'Credit Card', 'checkmo' => 'Check', 'purchaseorder' => 'Purchase Order'),
));
$this->addColumn('name', array(
'header' => Mage::helper('sales')->__('Product(s) Ordered'),
'index' => 'name',
'type' => 'text',
));
// rest code...
But the pagination is not working. All the records are loading in a single page.
Please any suggestions?
Found the solution.
The issue occurred due to the following statement.
$collection->getSelect()->group('main_table.entity_id');
I edited the lib/Varien/Data/Collection/Db.php
My Db.php file located in app/code/local/Varien/Data/Collection/Db.php
Following is the code.
.....//rest code
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->distinct(true);
$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
$countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
} else {
$countSelect->columns('COUNT(*)');
}
return $countSelect;
}
....//rest code
Then after clearing the cache and session it worked .. :)