您好我想弄清楚我什么时候可以让我的产品在预定日期上线,然后以禁用方式关闭。基本上我每天都会列出一种产品。而不是我每天午夜熬夜,我想要一个更简单的解决方案。
我被告知要创建一个日期属性“发布日期”,然后放一个cron作业来更新产品。我不知道如何开发一个cron job新手。请帮忙!一步一步的指示......这对许多Magento用户来说是一个很好的帮助。
答案 0 :(得分:3)
从www.ecomdev.org(页面不再存在)
<强>简介强> 本文将帮助您了解目录产品的基本自定义以及在Magento中执行自定义cron作业。
<强>功能强> 在开始开发之前,您应该想象它的作用并选择适合所有要求的功能。
该模块的要求如下:
应允许管理员用户指定产品的激活日期和到期日期。
应检查指定日期的产品,并根据日期类型执行以下操作:
因此模块开发应遵循以下步骤:
创建自定义属性后端模型以允许存储datetime属性的日期(Magento native eav实现从日期时间字符串中删除时间部分)
为产品创建两个属性,可以通过激活和到期日期来实现,并为其分配自定义属性后端模型 创建一个应该处理产品编辑块渲染的事件观察器,以便为日期字段启用时间指定 创建一个cron作业,检查产品的激活和到期日期并启用/禁用它们
基本结构
现在你知道它应该如何工作,所以你可以创建一个基本的模块结构。
模块的结构应包含以下内容:
您应该在创建结构之前命名模块。模块名称由模块名称空间和由下划线符号分隔的内部模块名称组成。所以这个模块的名称将是“EcomDev_ScheduledProduct”,其中“EcomDev”是我的扩展命名空间。
首先,您应该创建模块引导程序配置文件以启用您的模块。 Bootstrap文件位于“app / etc / modules”文件夹中。文件名应与模块名相同。 因此,您应该创建文件“EcomDev_ScheduledProduct.xml”,文件结构应包含模块名称,其代码池,活动状态和依赖节点,以指定所需的模块。所以它应该如下:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<EcomDev_ScheduledProduct>
<active>true</active> <!-- the module activity state -->
<codePool>community</codePool> <!-- the module code pool -->
<depends>
<Mage_Catalog /> <!-- the module depends on Mage_Catalog module, so it mentioned here -->
</depends>
</EcomDev_ScheduledProduct>
</modules>
</config>
该模块被指定放置在社区代码池中,因此它应放在“app / code / community”文件夹中,其路径应为“app / code / community / EcomDev / ScheduledProduct”。
现在您应该创建模块配置文件,您将在其中指定模型命名空间和设置脚本初始化语句。
让我们创造它: “应用程序/代码/小区/ EcomDev / ScheduledProduct的/ etc / config.xml中”
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<EcomDev_ScheduledProduct>
<version>1.0.0</version>
</EcomDev_ScheduledProduct>
</modules>
<global>
<models>
<ecomdev_scheduledproduct>
<!-- specification of model name space,
so we can call models like Mage::getModel('ecomdev_scheduledproduct/somemodelname') -->
<class>EcomDev_ScheduledProduct_Model</class>
</ecomdev_scheduledproduct>
</models>
<resources>
<!-- specifying of setup model and setup script path in sql folder -->
<ecomdev_scheduledproduct_setup>
<setup>
<module>EcomDev_ScheduledProduct</module>
<class>EcomDev_ScheduledProduct_Model_Mysql4_Setup</class>
</setup>
<connection>
<!-- use catalog connection to modify products -->
<use>catalog_setup</use>
</connection>
</ecomdev_scheduledproduct_setup>
</resources>
</global>
</config>
属性后端模型 在创建安装脚本之前,您需要注意datetime属性后端模型以在安装程序中指定它。在模块“Model”文件夹中创建它。在此模块中,您应将其称为“EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime”,路径“Attribute_Backend_Datetime”说明模型的作用。在其中你应该覆盖“beforeSave($ object)”,“afterLoad($ object)”和“formatDate($ date)”方法来改变属性存储的逻辑。您可能还希望在产品保存之前添加“compareDateToCurrent($ date)”方法来检查激活或到期日期。该模型应该从“Mage_Eav_Model_Entity_Attribute_Backend_Datetime”扩展。 “应用程序/代码/小区/ EcomDev / ScheduledProduct /型号/属性/后端/ Datetime.php”
<?php
/**
* Expiry and Activation dates custom backend model
*
*/
class EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime extends Mage_Eav_Model_Entity_Attribute_Backend_Datetime
{
/**
* Activation date attribute code
*
* @var string
*/
const ATTRIBUTE_ACTIVATION_DATE = 'ecomdev_activation_date';
/**
* Expiry date attribute code
*
* @var string
*/
const ATTRIBUTE_EXPIRY_DATE = 'ecomdev_expiry_date';
/**
* Status attribute code
*
* @var string
*/
const ATTRIBUTE_STATUS = 'status';
/**
* Checks date to update product status
* on the save in the admin panel
*
* @param Mage_Catalog_Model_Product $object
* @return EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime
*/
public function beforeSave($object)
{
parent::beforeSave($object);
$code = $this->getAttribute()->getAttributeCode();
$compareResult = $this->compareDateToCurrent($object->getData($code));
if ($compareResult !== false) {
// If the date is set
if (($compareResult < 0 && $code == self::ATTRIBUTE_ACTIVATION_DATE) ||
($compareResult >= 0 && $code == self::ATTRIBUTE_EXPIRY_DATE)) {
// If the date is in the past and it's activation date
// or the date is in the future and it's expiry date,
// so the product should be deactivated
$object->setData(
self::ATTRIBUTE_STATUS,
Mage_Catalog_Model_Product_Status::STATUS_DISABLED
);
}
}
return $this;
}
/**
* Magento native function doesn't save
* the time part of date so the logic of retrieving is changed
*
* @param string|int $date
* @return string|null
*/
public function formatDate($date)
{
if (empty($date)) {
return null;
} elseif (!($date instanceof Zend_Date)) {
// Parse locale representation of the date, eg. parse user input from date field
$dateString = $date;
$usedDateFormat = Mage::app()->getLocale()->getDateTimeFormat(
Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
);
// Instantiate date object in current locale
$date = Mage::app()->getLocale()->date();
$date->set($dateString, $usedDateFormat);
}
// Set system timezone for date object
$date->setTimezone(Mage_Core_Model_Locale::DEFAULT_TIMEZONE);
return $date->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
}
/**
* Compare date to current date
*
* Returns -1 if the date is in the past, and 1 if it's in the future,
* returns 0 if the dates are equal.
*
* @param string $date
* @return int
*/
public function compareDateToCurrent($date)
{
if (empty($date)) {
return false;
}
$compareDate = Mage::app()->getLocale()->date($date, Varien_Date::DATETIME_INTERNAL_FORMAT);
$currentDate = Mage::app()->getLocale()->date();
return $currentDate->compare($compareDate);
}
/**
* Converts timezone after object load, fixes issue in the core form element
*
* @param Mage_Core_Model_Abstract $object
* @return EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime
*/
public function afterLoad($object)
{
$code = $this->getAttribute()->getAttributeCode();
if ($object->getData($code) && !($object->getData($code) instanceof Zend_Date)) {
$date = Mage::app()->getLocale()->date();
$dateString = $object->getData($code);
$currentTimezone = $date->getTimezone();
$date->setTimezone(Mage_Core_Model_Locale::DEFAULT_TIMEZONE);
$date->set($dateString, Varien_Date::DATETIME_INTERNAL_FORMAT);
$date->setTimezone($currentTimezone);
$object->setData($code, $date);
}
return parent::afterLoad($object);
}
}
<强>设置强> 现在您需要创建设置模型和设置脚本。在配置文件中,安装模型类名称为“EcomDev_ScheduledProduct_Model_Mysql4_Setup”。该模块扩展了目录功能,因此模块设置模型从目录设置模型扩展而来。 “应用程序/代码/小区/ EcomDev / ScheduledProduct /型号/ Mysql4 / Setup.php”
<?php
/**
* Setup model for scheduled product module, extended from catalog module setup
*/
class EcomDev_ScheduledProduct_Model_Mysql4_Setup extends Mage_Catalog_Model_Resource_Eav_Mysql4_Setup
{
}
您需要在“sql / ecomdev_scheduledproduct_setup”文件夹中创建安装脚本。模块版本是1.0.0,它实际上是第一个版本,因此您需要将其命名为“mysql4-install-1.0.0.php”。此脚本应包含向EAV添加属性。此外,对于此模块,我们应该在“catalog_product_entity”表中添加列,因为它将加快产品批量状态更新过程。 “应用程序/代码/小区/ EcomDev / ScheduledProduct / SQL / ecomdev_scheduledproduct_setup / mysql4安装-1.0.0.php”
<?php
/* @var $this EcomDev_ScheduledProduct_Model_Mysql4_Setup */
$this->startSetup();
// For performance reasons we should add this fields to main entity table
// Activation date column adding to product entity table
$this->getConnection()->addColumn(
$this->getTable('catalog/product'),
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_ACTIVATION_DATE,
'DATETIME DEFAULT NULL'
);
// Expiry date column adding to product entity table
$this->getConnection()->addColumn(
$this->getTable('catalog/product'),
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_EXPIRY_DATE,
'DATETIME DEFAULT NULL'
);
// Activation date attribute information adding to the product entity
$this->addAttribute(
'catalog_product',
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_ACTIVATION_DATE,
array(
'type' => 'static',
'input' => 'date',
'label' => 'Activation Date',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
'backend' => 'ecomdev_scheduledproduct/attribute_backend_datetime',
'visible' => 1,
'required' => 0,
'position' => 10,
'group' => 'Schedule Settings'
)
);
// Expiry date attribute information adding to the product entity
$this->addAttribute(
'catalog_product',
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_EXPIRY_DATE,
array(
'type' => 'static',
'input' => 'date',
'label' => 'Expiry Date',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
'backend' => 'ecomdev_scheduledproduct/attribute_backend_datetime',
'visible' => 1,
'required' => 0,
'position' => 20,
'group' => 'Schedule Settings'
)
);
$this->endSetup();
事件观察员 在创建安装脚本和后端模型之后,您需要注意属性的输入字段呈现,这就是您需要观察“adminhtml_catalog_product_edit_prepare_form”事件的原因。因此,您应该使用“observeProductEditFortInitialization(Varien_Event_Observer $ observer)”方法创建“EcomDev_ScheduledProduct_Model_Observer”类。它应检查具有日期属性代码的元素的表单对象,并在找到任何时候为它们添加日期时间格式。
<?php
/**
* Observer for core events handling
*
*/
class EcomDev_ScheduledProduct_Model_Observer
{
/**
* Observes event 'adminhtml_catalog_product_edit_prepare_form'
* and adds custom format for date input
*
* @param Varien_Event_Observer $observer
* @return void
*/
public function observeProductEditFortInitialization(Varien_Event_Observer $observer)
{
$form = $observer->getEvent()->getForm();
$elementsToCheck = array(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_ACTIVATION_DATE,
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_EXPIRY_DATE
);
foreach ($elementsToCheck as $elementCode) {
$element = $form->getElement($elementCode);
if (!$element) {
continue;
}
$element->setFormat(
Mage::app()->getLocale()->getDateTimeFormat(
Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
)
);
$element->setTime(true);
}
}
}
您还需要在模块配置文件(config.xml)中定义事件观察器:
<config>
<!-- here goes the code you've created before
...
...
-->
<adminhtml>
<events>
<adminhtml_catalog_product_edit_prepare_form>
<observers>
<ecomdev_scheduledproduct>
<type>singleton</type>
<model>ecomdev_scheduledproduct/observer</model>
<method>observeProductEditFortInitialization</method>
</ecomdev_scheduledproduct>
</observers>
</adminhtml_catalog_product_edit_prepare_form>
</events>
</adminhtml>
</config>
Cron Job 完成为属性设置管理界面后,您需要创建一个自动激活/停用产品的cron作业。您可以将逻辑放在“EcomDev_ScheduledProduct_Model_Observer”类中,因为cron作业处理调用的实现类似于事件处理,除非您不会获得$ observer参数。
<?php
/**
* Observer for core events handling and cron jobs processing
*
*/
class EcomDev_ScheduledProduct_Model_Observer
{
/*
* here goes the code you've created before
* ............
* ............
*/
/**
* Cron job for processing of scheduled products
*
* @return void
*/
public function cronProcessScheduledProducts()
{
$currentDate = Mage::app()->getLocale()->date()->toString(
Varien_Date::DATETIME_INTERNAL_FORMAT
);
$productModel = Mage::getModel('catalog/product');
/* @var $expiredProductsCollection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
// Prepare collection of scheduled for expiry but haven't yet deactivated products
$expiredProductsCollection = $productModel->getCollection()
// Add filter for expired but products haven't yet deactivated
->addFieldToFilter(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_EXPIRY_DATE,
array(
'nnull' => 1, // Specifies that date shouldn't be empty
'lteq' => $currentDate // And lower than current date
)
)
->addFieldToFilter(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_STATUS,
Mage_Catalog_Model_Product_Status::STATUS_ENABLED
);
// Retrieve product ids for deactivation
$expiredProductIds = $expiredProductsCollection->getAllIds();
unset($expiredProductsCollection);
if ($expiredProductIds) {
Mage::getSingleton('catalog/product_action')
->updateAttributes(
$expiredProductIds,
array('status' => Mage_Catalog_Model_Product_Status::STATUS_DISABLED),
Mage_Core_Model_App::ADMIN_STORE_ID
);
}
/* @var $expiredProductsCollection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
// Prepare collection of scheduled for activation but haven't yet activated products
$activatedProductsCollection = $productModel->getCollection()
->addFieldToFilter(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_ACTIVATION_DATE,
array(
'nnull' => 1, // Specifies that date shouldn't be empty
'lteq' => $currentDate // And lower than current date
)
)
// Exclude expired products
->addFieldToFilter(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_EXPIRY_DATE,
array(
array('null' => 1), // Specifies that date shouldn't be empty
array('gt' => $currentDate) // And greater than current date
)
)
->addFieldToFilter(
EcomDev_ScheduledProduct_Model_Attribute_Backend_Datetime::ATTRIBUTE_STATUS,
Mage_Catalog_Model_Product_Status::STATUS_DISABLED
);
// Retrieve product ids for activation
$activatedProductIds = $activatedProductsCollection->getAllIds();
unset($activatedProductsCollection);
if ($activatedProductIds) {
Mage::getSingleton('catalog/product_action')
->updateAttributes(
$activatedProductIds,
array('status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED),
Mage_Core_Model_App::ADMIN_STORE_ID
);
}
}
}
当然,您应该在配置文件(config.xml)中定义您的cron作业:
<config>
<!-- here goes the code you've created before
...
...
-->
<crontab>
<jobs>
<ecomdev_scheduledproduct_process_schedule>
<schedule>
<!-- Schedule for every 5 minutes -->
<cron_expr>*/5 * * * *</cron_expr>
</schedule>
<run>
<model>ecomdev_scheduledproduct/observer::cronProcessScheduledProducts</model>
</run>
</ecomdev_scheduledproduct_process_schedule>
</jobs>
</crontab>
</config>
<强>结果强> 现在您应该登录管理面板,导航“系统 - &gt;缓存管理 - &gt;刷新Magento Cache“以启用您的扩展程序。 您可以在“目录 - &gt;中找到您创建的字段。管理产品 - &gt;在“计划设置”选项卡中编辑/添加产品“页面。 并且不要忘记在系统crontab中设置Magento cron。
<强>结论强> 现在,您知道如何使用Magento中的cron作业为目录创建简单的自定义。 此处提供的模块可在Magento Connect上以免费社区扩展名获取:Scheduled Products
答案 1 :(得分:0)
我认为Product Scheduler最适合您的要求。