Хобрук: Ваш путь к мастерству в программировании

Magento - создание новой формы Adminhtml, но saveAction() не работает

Я использую Magento 1.9.0.1 и в настоящее время работаю над собственным расширением Magento!

Вот скриншот формы:

введите здесь описание изображения

Когда я нажал Save Item, я получил это:

введите здесь описание изображения

Как видите, saveAction() не сохранил изменения.

Когда я помещаю: Mage::log($this->getRequest()->getPost());, чтобы увидеть, работает ли форма, я получаю это:

2015-02-17T13:25:08+00:00 DEBUG (7): Array
(
    [form_key] => zj9E8FpNOCyFIqaT
    [Receiver] => Veni
    [Phone] => 359884685063
    [Date] => 2015-02-05 19:06:44
)

По этому я думаю, что форма в порядке.

Позвольте мне показать вам весь код, который у меня есть в моем расширении!

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Block/Adminhtml/Sms/Status.php:

<?php

class VivasIndustries_SmsNotification_Block_Adminhtml_Sms_Status extends Mage_Adminhtml_Block_Widget_Grid_Container


{
    public function __construct()
    {
        $this->_controller = 'adminhtml_sms_status';
        $this->_blockGroup = 'smsnotification';
        $this->_headerText = Mage::helper('smsnotification')->__('Item Manager');
        $this->_addButtonLabel = Mage::helper('smsnotification')->__('Add Item');
        parent::__construct();
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Block/Adminhtml/Sms/Status/Grid.php:

<?php

class VivasIndustries_SmsNotification_Block_Adminhtml_Sms_Status_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
    public function __construct()
    {
        parent::__construct();
        $this->setId('smsnotification_grid');
        $this->setDefaultSort('id');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
        $this->setUseAjax(true);
    }


    protected function _prepareCollection()
    {
        $collection = Mage::getResourceModel('smsnotification/smsnotification_collection');
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }


    protected function _prepareColumns()
    {
          $this->addColumn('id', array(
              'header'    => Mage::helper('smsnotification')->__('ID'),
              'align'     =>'right',
              'width'     => '50px',
              'index'     => 'id',
          ));

          $this->addColumn('Receiver', array(
              'header'    => Mage::helper('smsnotification')->__('Receiver'),
              'align'     =>'left',
              'index'     => 'Receiver',
          ));

        $this->addColumn('Phone', array(
            'header'    => Mage::helper('smsnotification')->__('Phone'),
            'align'     =>'left',
            'index'     => 'Phone',
        ));

        $this->addColumn('Date', array(
            'header'    => Mage::helper('smsnotification')->__('Date'),
            'align'     =>'left',
            'index'     => 'Date',

        ));


        return parent::_prepareColumns();
    }

    public function getRowUrl($row)
    {
        return $this->getUrl('*/*/edit', array('id'=>$row->getId()));
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Block/Adminhtml/Sms/Status/Edit.php:

<?php
class VivasIndustries_SmsNotification_Block_Adminhtml_Sms_Status_Edit extends Mage_Adminhtml_Block_Widget_Form_Container

{
    public function __construct()
    {
        parent::__construct();

        $this->_objectId = 'id';
        $this->_blockGroup = 'smsnotification';
        $this->_controller = 'adminhtml_sms_status';

        $this->_updateButton('save', 'label', Mage::helper('smsnotification')->__('Save Item'));
        $this->_updateButton('delete', 'label', Mage::helper('smsnotification')->__('Delete Item'));
    }

    public function getHeaderText()
    {
        if( Mage::registry('smsnotification_data') && Mage::registry('smsnotification_data')->getId() ) {
            return Mage::helper('smsnotification')->__("Edit Item '%s'", $this->htmlEscape(Mage::registry('smsnotification_data')->getReceiver()));
        } else {
            return Mage::helper('smsnotification')->__('Add Item');
        }
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Block/Adminhtml/Sms/Status/Edit/Form.php:

<?php

class VivasIndustries_SmsNotification_Block_Adminhtml_Sms_Status_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',
                                 ));

                $fieldset = $form->addFieldset('edit_form', array('legend'=>Mage::helper('smsnotification')->__('Item information')));

                $fieldset->addField('Receiver', 'text', array(
                    'label'     => Mage::helper('smsnotification')->__('Receiver'),
                    'class'     => 'required-entry',
                    'required'  => true,
                    'name'      => 'Receiver',
                     ));

                $fieldset->addField('Phone', 'text', array(
                    'label'     => Mage::helper('smsnotification')->__('Phone'),
                    'class'     => 'required-entry',
                    'required'  => true,
                    'name'      => 'Phone',
                    ));

                $fieldset->addField('Date', 'text', array(
                    'label'     => Mage::helper('smsnotification')->__('Date'),
                    'class'     => 'required-entry',
                    'required'  => true,
                    'name'      => 'Date',
                    ));

                if ( Mage::getSingleton('adminhtml/session')->getsmsnotificationData() )
                    {
                        $form->setValues(Mage::getSingleton('adminhtml/session')->getsmsnotificationData());
                        Mage::getSingleton('adminhtml/session')->setsmsnotificationData(null);
                    } elseif ( Mage::registry('smsnotification_data') ) {
                        $form->setValues(Mage::registry('smsnotification_data')->getData());
                    }
                // Add these two lines


                $form->setUseContainer(true);
                $this->setForm($form);

                ////

                return parent::_prepareForm();
            }
    }

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/controllers/Adminhtml/SmsorderstatusesController.php:

<?php

class VivasIndustries_SmsNotification_Adminhtml_SmsorderstatusesController extends Mage_Adminhtml_Controller_Action
{
    public function indexAction()
    {
        $this->_title($this->__('SMS Center'))->_title($this->__('SMS Center'));
        $this->loadLayout();
        $this->_setActiveMenu('vivassms');
        $this->_addContent($this->getLayout()->createBlock('smsnotification/adminhtml_sms_status'));
        $this->renderLayout();
    }

    public function editAction()
    {
        $smsnotificationId     = $this->getRequest()->getParam('id');
        $smsnotificationModel  = Mage::getModel('smsnotification/smsnotification')->load($smsnotificationId);

        if ($smsnotificationModel->getId() || $smsnotificationId == 0) {

            Mage::register('smsnotification_data', $smsnotificationModel);

            $this->loadLayout();
            $this->_setActiveMenu('vivassms');

            $this->_addBreadcrumb(Mage::helper('adminhtml')->__('Item Manager'), Mage::helper('adminhtml')->__('Item Manager'));
            $this->_addBreadcrumb(Mage::helper('adminhtml')->__('Item News'), Mage::helper('adminhtml')->__('Item News'));

            $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);

            $this->_addContent($this->getLayout()->createBlock('smsnotification/adminhtml_sms_status_edit'));

            $this->renderLayout();
        } else {
            Mage::getSingleton('adminhtml/session')->addError(Mage::helper('smsnotification')->__('Item does not exist'));
            $this->_redirect('*/*/');
        }
    }

    public function newAction()
    {
        $this->_forward('edit');
    }

    public function saveAction()
    {
        if ( $this->getRequest()->getPost() ) {
            try {
                Mage::log($this->getRequest()->getPost());
                $postData = $this->getRequest()->getPost();
                $smsnotificationModel = Mage::getModel('smsnotification/smsnotification')->load($this->getRequest()->getParam('id'));

                $smsnotificationModel->setReceiver($postData['Receiver'])
                ->setPhone($postData['Phone'])
                ->setDate($postData['Date'])
                ->save();

                Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Item was successfully saved'));
                Mage::getSingleton('adminhtml/session')->setsmsnotificationData(false);

                $this->_redirect('*/*/');
                return;
            } catch (Exception $e) {
                Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
                Mage::getSingleton('adminhtml/session')->setsmsnotificationData($this->getRequest()->getPost());
                $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
                return;
            }
        }

        $this->_redirect('*/*/');
    }

    public function deleteAction()
    {
        if( $this->getRequest()->getParam('id') > 0 ) {
            try {
                $smsnotificationModel = Mage::getModel('smsnotification/smsnotification');

                $smsnotificationModel->setId($this->getRequest()->getParam('id'))
                    ->delete();

                Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Item was successfully deleted'));
                $this->_redirect('*/*/');
            } catch (Exception $e) {
                Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
                $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
            }
        }
        $this->_redirect('*/*/');
    }
    /**
     * Product grid for AJAX request.
     * Sort and filter result for example.
     */
    public function gridAction()
    {
        $this->loadLayout();
        $this->getResponse()->setBody(
               $this->getLayout()->createBlock('smsnotification/adminhtml_smsnotification_grid')->toHtml()
        );
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/etc/config.xml:

<?xml version="1.0"?>
<config>
  <modules>
    <VivasIndustries_SmsNotification>
      <version>0.1.0</version>
    </VivasIndustries_SmsNotification>
  </modules>
  <global>
    <models>
        <smsnotification>
            <class>VivasIndustries_SmsNotification_Model</class>
            <resourceModel>vivasindustries_smsnotification_resource</resourceModel>
        </smsnotification>
        <vivasindustries_smsnotification_resource>
        <class>VivasIndustries_SmsNotification_Model_Resource</class>
        <entities>
            <smsnotification>
            <table>VivasIndustries_SmsNotification</table>
            </smsnotification>
        </entities>
        </vivasindustries_smsnotification_resource>
    </models>
    <resources>
        <smsnotification_setup>
            <setup>
                <module>VivasIndustries_SmsNotification</module>
            </setup>
            <connection>
                 <use>core_setup</use>
             </connection>
        </smsnotification_setup>
        <smsnotification_read>
            <connection>
                <use>core_read</use>
            </connection>
        </smsnotification_read>
        <smsnotification_write>
            <connection>
                <use>core_write</use>
            </connection>
        </smsnotification_write>
    </resources>    
    <events>
        <sales_order_save_after>
            <observers>
                <vivasindustries_smsnotification>
                    <class>smsnotification/observer</class>
                    <method>orderSaved</method>
                </vivasindustries_smsnotification>
            </observers>
        </sales_order_save_after>
    </events>
    <helpers>
        <smsnotification>
            <class>VivasIndustries_SmsNotification_Helper</class>
        </smsnotification>
    </helpers>
    <blocks>
        <smsnotification>
             <class>VivasIndustries_SmsNotification_Block</class>
        </smsnotification>
    </blocks>
  </global>
  <adminhtml>
    <acl>
        <resources>
            <all>
                <title>Allow Everything</title>
            </all>
            <admin>
                <children>
                    <system>
                        <children>
                            <config>
                                <children>
                                    <vivas>
                                        <title>Vivas - All</title>
                                    </vivas>
                                </children>
                            </config>
                        </children>
                    </system>
                </children>
            </admin>
        </resources>
    </acl>
    <layout>
        <updates>
            <smsnotification>
                <file>smsnotification.xml</file>
            </smsnotification>
        </updates>
    </layout>   
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <VivasIndustries_SmsNotification before="Mage_Adminhtml">VivasIndustries_SmsNotification_Adminhtml</VivasIndustries_SmsNotification>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>  

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Model/Resource/Smsnotification.php:

<?php
class VivasIndustries_SmsNotification_Model_Resource_Smsnotification extends Mage_Core_Model_Resource_Db_Abstract
{
    /**
     * Initialize resource model
     *
     * @return void
     */
    public function _construct()
    {
        $this->_init('smsnotification/smsnotification','id');
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Model/Resource/Smsnotification/Collection.php:

<?php 
class VivasIndustries_SmsNotification_Model_Resource_Smsnotification_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract{
    protected function _construct(){
        $this->_init('smsnotification/smsnotification');    
    }
}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/Model/

<?php
class VivasIndustries_SmsNotification_Model_Smsnotification extends Mage_Core_Model_Abstract
{
    public function _construct()
    {
        parent::_construct();
        $this->_init('smsnotification/smsnotification');
    }

}

У меня есть в: /app/code/community/VivasIndustries/SmsNotification/sql/smsnotification_setup/install-1.0.0.php:

<?php
$installer=$this;
$installer->startSetup();

$installer->run("
CREATE TABLE IF NOT EXISTS `VivasIndustries_SmsNotification` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Receiver` varchar(500) NOT NULL,
  `Phone` varchar(500) NOT NULL,
  `Date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
    ");
$installer->endSetup();
?>

Это все файлы, которые у меня есть в моем расширении, кроме adminhtml.xml и system.xml. Если вы считаете, что их важно показать, я покажу их.

Итак, вы видите проблему, почему он не делает сохранения должным образом? Можете ли вы помочь мне решить эту проблему?

Заранее спасибо!

17.02.2015

Ответы:


1

Я предполагаю, что идентификатор отсутствует в данных сообщения. Таким образом, он не загружает необходимые данные модели, а создает новую запись. Вероятно, $this->getRequest()->getParam('id') возвращает null.

Добавьте в форму скрытое поле id с идентификатором записи.

17.02.2015
  • Итак, если я создам Mage::log($this->getRequest()->getParam('id'));, он должен вернуть null в моем файле журнала, если ваше предположение верно? 17.02.2015
  • да. Если это так, просто добавьте скрытое поле с идентификатором, как в примере JonaPk ниже. 17.02.2015
  • @TonyStark, что касается БД, в данном случае это не имеет значения, имхо. Если вы добавили это поле, убедитесь, что в исходном коде html его значение было заполнено из модели и отправлено в POST на ваш контроллер. 17.02.2015
  • Как я могу проверить, отправляет ли он его на контроллер? 17.02.2015
  • 1. Используйте отладчик 2. Сделайте print_r($_POST) в контроллере. 18.02.2015

  • 2

    xpoback верен, вам нужно добавить скрытое поле в форму, если вы находитесь в действии редактирования:

    Итак, в _prepareForm() добавьте перед полем Receiver:

    $model = Mage::registry('smsnotification_data');
    if ($model->getId()) {
                $fieldset->addField('id', 'hidden', array(
                    'name' => 'id',
                ));
            }
    
    17.02.2015
  • Я думаю, что, возможно, это не проблема. Взгляните на файл формы после вашего предложения: pastebin.com/fXrS3ja4 И все же он не вносит изменения . Также взгляните на этот ответ: magento.stackexchange.com/questions/57473/ Как вы думаете, это тоже может быть проблемой? 17.02.2015
  • Да, это тоже может быть проблемой ... Вы всегда должны писать db ralted в нижнем регистре (имена полей, имена таблиц, ...), потому что Magento ORM выполняет преобразования из подчеркивания в верблюжий регистр и наоборот ... Так что это может быть проблема, и, кроме того, ее трудно отладить 17.02.2015
  • Итак, вы предлагаете мне изменить имя таблицы с VivasIndustries_SmsNotification на vivasindustries_smsnotification и все имена строк таблицы? 17.02.2015
  • Нет, в этом нет необходимости, так как для имени таблицы magento будет искать внутри вашего config.xml, но вы должны делать это систематически, это соглашение, которому нужно следовать (лучшие практики), но для имен полей, да, вы должны это сделать... 17.02.2015
  • Я сделал это, и я получаю эту ошибку, когда пытаюсь отправить изменения, нажав Save Item -> SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE (id='13')' at line 1 Можете ли вы дать мне какой-либо совет по этому поводу? 17.02.2015
  • Вам действительно нужно трижды проверить все имена полей формы, просто чтобы быть уверенным (и сделать это правильно...)... Поместите все в нижний регистр, в именах полей БД, в именах полей формы... И сделайте это : $smsnotificationModel->setData($postData)->save(); в вашем контроллере saveAction(). Если все поля правильно сопоставлены (таким образом, их имена везде одинаковы, и Magento может использовать свои волшебные методы), это должно просто работать... Так что здесь много комментариев... нам скоро нужно будет перейти в чат, если это продолжается 17.02.2015
  • Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..