Jadi setelah menghabiskan hampir satu hari berjuang dengan masalah yang sama dalam ekstensi saya sendiri, saya pikir saya akan membagikan solusi saya di sini. Sesuatu yang perlu diperhatikan adalah bahwa entitas saya tidak menggunakan sistem EAV, setiap entitas memiliki tabel sendiri dengan kolom untuk setiap atribut. Entitas saya memiliki empat atribut datetime - dua di antaranya diisi dari input pengguna ( open_date
, close_date
), dan dua di antaranya diisi secara otomatis oleh kode sumber ( create_date
, close_date
).
Kelas Model Entitas
Di kelas model entitas saya sertakan yang berikut:
- Cara untuk mendefinisikan dan mengambil atribut apa dari tipe datetime dan diisi melalui data yang dimasukkan pengguna yang disediakan dalam waktu lokal toko.
- Metode yang mengonversi hanya bidang ini dari waktu GMT ke waktu lokal toko (lebih lanjut tentang ini nanti).
- Metode _beforeSave () yang menetapkan atribut 'edit_date' dan 'create_date' (yang tidak diisi melalui input pengguna) dalam GMT untuk saya secara otomatis disimpan.
Kode sumber:
/**
* Model's datetime attributes that are populated with user data supplied
* in the store's local time.
*
* @var array
*/
protected $_dateFields = array(
'open_date',
'close_date',
);
/**
* Return the model's datetime attributes that are populated with user
* data supplied in the store's local time.
*
* @return array
*/
public function getDateFields()
{
return $this->_dateFields;
}
/**
* (non-PHPdoc)
* @see Mage_Core_Model_Abstract::_beforeSave()
*/
protected function _beforeSave()
{
parent::_beforeSave();
$date = Mage::getModel('core/date')->gmtDate();
if (!$this->getId()) {
$this->setData('create_date', $date);
}
$this->setData('edit_date', $date);
return $this;
}
The saveAction dari Pengontrol Admin Entitas
Dalam metode saveAction milik pengontrol, saya menggunakan metode getDateFields () yang didefinisikan dalam kelas model untuk mengetahui atribut mana yang perlu saya ubah dari waktu lokal toko (yang dimasukkan pengguna) ke waktu GMT sebelum menyimpan ke basis data. Perhatikan bahwa ini hanya sebagian potongan dari metode simpan saya:
....
$data = $this->getRequest()->getPost()
// Convert user input time from the store's local time to GMT time
$dateFields = $model->getDateFields();
if (is_array($dateFields) && count($dateFields)) {
$data = $this->_filterDateTime($data, $dateFields);
$store_timezone = new DateTimeZone(Mage::getStoreConfig('general/locale/timezone'));
$gmt_timezone = new DateTimeZone('Europe/London');
foreach ($dateFields as $key) if (isset($data[$key])) {
$dateTime = new DateTime($data[$key], $store_timezone);
$dateTime->setTimezone($gmt_timezone);
$data[$key] = $dateTime->format('Y-m-d H:i:s');
}
}
$model->addData($data);
try {
$model->save();
....
Blok Formulir Admin untuk mengedit Entitas
Tidak seperti widget kisi admin Magento, yang mengharapkan nilai datetime dari koleksi yang akan disediakan dalam GMT, dengan niat untuk mengkonversi nilai-nilai ini ke waktu lokal toko sebelum menampilkan halaman, widget formulir admin Magento tidak mengikuti perilaku ini. Sebagai gantinya, widget bentuk akan menerima nilai datetime apa adanya, dan menampilkannya tanpa secara otomatis menyesuaikan waktu. Oleh karena itu, karena nilai disimpan dalam database dalam GMT, pertama-tama kita harus mengonversi atribut datetime yang dimasukkan pengguna ke waktu lokal toko sebelum memasok data tersebut ke formulir. Di sinilah # 2 kami di Kelas Model Entity ikut bermain.
Berikut ini adalah PORTION dari metode _prepareForm () dari kelas blok formulir admin saya (yang meluas Mage_Adminhtml_Block_Widget_Form). Saya telah menghilangkan sebagian besar fungsi saya, mencoba untuk hanya memasukkan minimum yang relevan dengan pertanyaan ini, dan masih memberikan metode kelas yang valid:
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$model = Mage::registry('YOUR_MODEL_CLASS');
$date_format = Mage::app()->getLocale()->getDateTimeFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM);
$time_zone = $this->__('Time Zone: %s', Mage::getStoreConfig('general/locale/timezone'));
$calendar_img = $this->getSkinUrl('images/grid-cal.gif');
$fieldset = $form->addFieldset('base_fieldset', array('legend'=> $this->__('General Information')));
$fieldset->addField('open_date', 'datetime', array(
'name' => 'open_date',
'label' => $this->__('Open Date'),
'title' => $this->__('Open Date'),
'time' => 'true',
'image' => $calendar_img,
'format' => $date_format,
'style' => 'width:160px',
'required' => true,
'note' => $time_zone
));
$fieldset->addField('close_date', 'datetime', array(
'name' => 'close_date',
'label' => $this->__('Close Date'),
'title' => $this->__('Close Date'),
'time' => 'true',
'image' => $calendar_img,
'format' => $date_format,
'style' => 'width:160px',
'required' => true,
'note' => $time_zone
));
if ($model->getId()) {
$form->setValues($model->getAdminFormData());
}
$this->setForm($form);
return parent::_prepareForm();
}
Sebagian besar dari ini mengikuti bentuk widget lainnya untuk Magento. Namun satu hal kunci yang penting untuk dicatat di sini adalah bahwa alih-alih menelepon, $form->setValues($model->getData())
kita memanggil $form->setValues($model->getAdminFormData())
. Yang mana, jika kami meninjau kode saya dari segmen pertama dari jawaban ini, metode ini akan mengkonversi semua atribut datetime, yang dimasukkan pengguna, dari GMT ke waktu lokal toko.
Hasil akhir:
- Semua nilai disimpan ke DB dalam waktu GMT.
- Nilai yang dimasukkan pengguna dikonversi dari GMT ke waktu lokal store, sebelum memberikannya untuk diedit
- Admin Grid berfungsi seperti biasanya, mengambil nilai GMT dan mengonversi ke waktu lokal toko sebelum merender kisi pada halaman.
Semoga ini terbukti sebagai sumber daya berharga untuk membantu orang lain di luar sana suatu hari nanti. Saat Anda bekerja pada pengembangan front-end, perlu diingat bahwa nilai-nilai datetime dalam GMT dalam DB!