运行 Magento 1.9.1.0 数据流以编程方式导入配置文件
Run Magento 1.9.1.0 Dataflow Import Profile Programmatically
我试过让它正常工作,但似乎找不到解决方案。我正在寻找 运行 一个 ID = 3 且已配置导入文件名的现有数据流配置文件。
我所做的所有研究导致了以下代码的一些变化:
public function importProducts($profile_id = 3)
{
require_once('../app/Mage.php');
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
// Instantiate a session for the "root" user.
$userModel = Mage::getModel('admin/user');
$userModel->setUserId(0);
Mage::getSingleton('admin/session')->setUser($userModel);
// Load the dataflow profile.
$profile = Mage::getModel('dataflow/profile');
$profile->load($profile_id);
if (!$profile->getId()) {
exit("Profile with id #{$profile_id} does not exist.");
}
$profile->run();
$batchModel = Mage::getSingleton('dataflow/batch');
// Reporting.
$direction = ucwords($profile->getDirection());
$success = "{$direction} with id #{$batchModel->getId()} completed succesfully.\n";
echo $success;
return true;
}
运行 来自 Magento 后端的相关配置文件 (ID = 3) 工作完美,只是似乎无法从上面的 PHP 函数触发它。
我正在寻找一种以编程方式触发 "Import All Products" 数据流配置文件的方法。
我遇到但没有成功的其他帖子、问题和网站:
- http://phpmysqltalk.com/1718-magento-dataflow-exportimport-form-the-command-line.html
- https://www.variux.com/magento-1-8-ce-importexport-from-shell-on-bitnami/
- Run multiple Magento DataFlow profiles in sequence
- https://gist.github.com/ameenross/91b85beb45f1ff0a23c6
我们将不胜感激任何帮助!
谢谢!
经过多次挫折后,以下是有效的答案:
请注意,在这种情况下,我已经为 导入所有产品 (ID: 3) 配置了默认的 Magento 数据流配置文件以读取 XML 导入格式,来自预定义的文件。这是我在 运行 导入操作之前根据需要创建的文件。 (参考上题中的截图)
创建个人资料后,您需要 2 个文件:
- importer.php
- batch_importer_processor.php
您可以将文件放在 /magento/root/shell/ 目录中,或者如果您要包含在单独的位置,则可以根据需要调整路径。进入目录后,您可以使用以下命令通过 cron 调用触发操作:
php -f /path/to/magento/root/directory/shell/importer.php
上面的-f参数是"parse and execute"被调用的文件
每个文件的来源是:
importer.php
<?php
require_once '../app/Mage.php';
set_time_limit(0);
ini_set('memory_limit', '128M');
$root = "/path/to/your/magento/root/directory/";
$logFile = 'magento_import.log';
umask(0);
$app = Mage::app('default');
Mage::log("========================== BEGIN IMPORT ==========================", null, $logFile);
//echo "========================== BEGIN IMPORT ==========================\n";
// Login Admin User
Mage::getSingleton('core/session', array('name' => 'adminhtml'));
$user = Mage::getModel('admin/user')->loadByUsername($username);
if (Mage::getSingleton('adminhtml/url')->useSecretKey()) {
Mage::getSingleton('adminhtml/url')->renewSecretUrls();
}
$session = Mage::getSingleton('admin/session');
$session->setIsFirstVisit(true);
$session->setUser($user);
$session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());
Mage::dispatchEvent('admin_session_user_login_success',array('user'=>$user));
if ($session->isLoggedIn()) {
Mage::log("User '" . $username . "' logged in.", null, $logFile);
//echo "User '" . $username . "' logged in.\n";
} else {
Mage::log("ERROR: Could not login as user '" . $username . "'.", null, $logFile);
//echo "ERROR: Could not login as user '" . $username . "'.\n";
}
// Load DataFlow Profile
$profile_id = 3;
$profile = Mage::getModel('dataflow/profile');
$profile->load($profile_id);
if (!$profile->getId()) {
Mage::log("ERROR: Profile with ID #{$profile_id} does not exist.", null, $logFile);
//echo "ERROR: Profile with ID #{$profile_id} does not exist.\n";
exit;
}
Mage::register('current_convert_profile', $profile);
$profile->run();
// Begin Bactch Processing
// Limit of products per batch (max: 50)
$batchLimit = 50;
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
$batchModel = Mage::getSingleton('dataflow/batch');
if (!$batchModel->getId()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Can't get batchModel", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Can't get batchModel\n";
exit;
}
if (!$batchModel->getAdapter()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Can't getAdapter", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Can't getAdapter\n";
exit;
}
$batchId = $batchModel->getId();
$batchImportModel = $batchModel->getBatchImportModel();
$importIds = $batchImportModel->getIdCollection();
$recordCount = null;
$totalproducts = count($importIds);
$saved = 0;
$batchArrayIds = array();
foreach ($importIds as $importId) {
$recordCount++;
$batchArrayIds[] = $importId;
if ($recordCount%$batchLimit == 0 || $recordCount == $totalproducts) {
$paramsArr = array('batchid' => $batchId, 'ids' => $batchArrayIds);
$params = json_encode($paramsArr);
$result = array();
exec("php -f {$root}shell/batch_import_processor.php '{$params}'", $result);
$saved += $result[0];
Mage::log(convert(memory_get_usage()) . " - processed {$recordCount}/$totalproducts. Saved {$result[0]} products.", null, $logFile);
//echo convert(memory_get_usage()) . " - processed {$recordCount}/$totalproducts. Saved {$result[0]} products.\n";
$batchArrayIds = array();
}
}
$batchModel = Mage::getModel('dataflow/batch')->load($batchId);
try {
$batchModel->beforeFinish();
} catch (Mage_Core_Exception $e) {
Mage::log(convert(memory_get_usage()) . " - ERROR: ". $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: ". $e->getMessage() . "\n";
} catch (Exception $e) {
Mage::log(convert(memory_get_usage()) . " - ERROR: An error occurred while finishing process. Please refresh the cache" . $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: An error occurred while finishing process. Please refresh the cache" . $e->getMessage() . "\n";
}
$batchModel->delete();
// Output Debugging Info
foreach ($profile->getExceptions() as $e) {
Mage::log(convert(memory_get_usage()) . " - " . $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - " . $e->getMessage() . "\n";
}
Mage::log("IMPORT COMPLETE.", null, $logFile);
//echo "IMPORT COMPLETE.\n";
?>
batch_import_processor.php
<?php
$root = '/your/path/to/magento/root/directory/';
$logFile = 'magento_import.log';
require_once $root . 'app/Mage.php';
set_time_limit(0);
ini_set('memory_limit', '128M');
ob_implicit_flush();
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$params = $argv[1];
$paramsArray = json_decode($params, true);
$batchId = $paramsArray['batchid'];
$importIds = $paramsArray['ids'];
$saved = 0;
$batchModel = Mage::getModel('dataflow/batch')->load($batchId);
$batchImportModel = $batchModel->getBatchImportModel();
$adapter = Mage::getModel($batchModel->getAdapter());
$adapter->setBatchParams($batchModel->getParams());
foreach ($importIds as $importId) {
$batchImportModel->load($importId);
if (!$batchImportModel->getId()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Skip undefined row {$importId}", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Skip undefined row {$importId}\n";
continue;
}
try {
$importData = $batchImportModel->getBatchData();
$adapter->saveRow($importData);
} catch (Exception $e) {
Mage::log("Exception : " . $e, null, $logFile);
//echo "Exception : " . $e;
continue;
}
$saved ++;
}
if (method_exists($adapter, 'getEventPrefix')) {
// Event to process rules relationships after import
Mage::dispatchEvent($adapter->getEventPrefix() . '_finish_before', array(
'adapter' => $adapter
));
// Clear affected ids for possible reuse
$adapter->clearAffectedEntityIds();
}
Mage::log("Total Products to Import: " . $saved, null, $logFile);
echo $saved;
?>
添加到此代码中并不难,因此如果您需要,您可以按顺序 运行 多个配置文件。否则,请务必从 Magento 后端获取配置文件 ID 并将 $profile_id 变量设置为所需的值。
如果您喜欢这条路线,我已经在下面的相应回显语句中包含了对 Magento 日志 (Mage::log) 的调用。根据需要进行编辑。日志应保存在 /magento/root/var/log/ 目录中。请务必通过以下方式在 Magento 后端启用此功能:
- 系统 > 配置 > 高级 > 开发人员 > 日志设置
并启用设置 "Yes" 见下文:
在 运行 更新 importer.php 文件后,您应该在 /magento/root/var/log/目录:
- system.log
- magento_import.log
您可能还拥有始终启用的 exception.log 文件。
这是我发现与 Magento 1.9.1.0 一起使用的唯一解决方案,感谢 Andrey 的启发。
随时欢迎任何想法或改进。
我试过让它正常工作,但似乎找不到解决方案。我正在寻找 运行 一个 ID = 3 且已配置导入文件名的现有数据流配置文件。
我所做的所有研究导致了以下代码的一些变化:
public function importProducts($profile_id = 3)
{
require_once('../app/Mage.php');
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
// Instantiate a session for the "root" user.
$userModel = Mage::getModel('admin/user');
$userModel->setUserId(0);
Mage::getSingleton('admin/session')->setUser($userModel);
// Load the dataflow profile.
$profile = Mage::getModel('dataflow/profile');
$profile->load($profile_id);
if (!$profile->getId()) {
exit("Profile with id #{$profile_id} does not exist.");
}
$profile->run();
$batchModel = Mage::getSingleton('dataflow/batch');
// Reporting.
$direction = ucwords($profile->getDirection());
$success = "{$direction} with id #{$batchModel->getId()} completed succesfully.\n";
echo $success;
return true;
}
运行 来自 Magento 后端的相关配置文件 (ID = 3) 工作完美,只是似乎无法从上面的 PHP 函数触发它。
我正在寻找一种以编程方式触发 "Import All Products" 数据流配置文件的方法。
我遇到但没有成功的其他帖子、问题和网站:
- http://phpmysqltalk.com/1718-magento-dataflow-exportimport-form-the-command-line.html
- https://www.variux.com/magento-1-8-ce-importexport-from-shell-on-bitnami/
- Run multiple Magento DataFlow profiles in sequence
- https://gist.github.com/ameenross/91b85beb45f1ff0a23c6
我们将不胜感激任何帮助!
谢谢!
经过多次挫折后,以下是有效的答案:
请注意,在这种情况下,我已经为 导入所有产品 (ID: 3) 配置了默认的 Magento 数据流配置文件以读取 XML 导入格式,来自预定义的文件。这是我在 运行 导入操作之前根据需要创建的文件。 (参考上题中的截图)
创建个人资料后,您需要 2 个文件:
- importer.php
- batch_importer_processor.php
您可以将文件放在 /magento/root/shell/ 目录中,或者如果您要包含在单独的位置,则可以根据需要调整路径。进入目录后,您可以使用以下命令通过 cron 调用触发操作:
php -f /path/to/magento/root/directory/shell/importer.php
上面的-f参数是"parse and execute"被调用的文件
每个文件的来源是:
importer.php
<?php
require_once '../app/Mage.php';
set_time_limit(0);
ini_set('memory_limit', '128M');
$root = "/path/to/your/magento/root/directory/";
$logFile = 'magento_import.log';
umask(0);
$app = Mage::app('default');
Mage::log("========================== BEGIN IMPORT ==========================", null, $logFile);
//echo "========================== BEGIN IMPORT ==========================\n";
// Login Admin User
Mage::getSingleton('core/session', array('name' => 'adminhtml'));
$user = Mage::getModel('admin/user')->loadByUsername($username);
if (Mage::getSingleton('adminhtml/url')->useSecretKey()) {
Mage::getSingleton('adminhtml/url')->renewSecretUrls();
}
$session = Mage::getSingleton('admin/session');
$session->setIsFirstVisit(true);
$session->setUser($user);
$session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());
Mage::dispatchEvent('admin_session_user_login_success',array('user'=>$user));
if ($session->isLoggedIn()) {
Mage::log("User '" . $username . "' logged in.", null, $logFile);
//echo "User '" . $username . "' logged in.\n";
} else {
Mage::log("ERROR: Could not login as user '" . $username . "'.", null, $logFile);
//echo "ERROR: Could not login as user '" . $username . "'.\n";
}
// Load DataFlow Profile
$profile_id = 3;
$profile = Mage::getModel('dataflow/profile');
$profile->load($profile_id);
if (!$profile->getId()) {
Mage::log("ERROR: Profile with ID #{$profile_id} does not exist.", null, $logFile);
//echo "ERROR: Profile with ID #{$profile_id} does not exist.\n";
exit;
}
Mage::register('current_convert_profile', $profile);
$profile->run();
// Begin Bactch Processing
// Limit of products per batch (max: 50)
$batchLimit = 50;
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
$batchModel = Mage::getSingleton('dataflow/batch');
if (!$batchModel->getId()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Can't get batchModel", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Can't get batchModel\n";
exit;
}
if (!$batchModel->getAdapter()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Can't getAdapter", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Can't getAdapter\n";
exit;
}
$batchId = $batchModel->getId();
$batchImportModel = $batchModel->getBatchImportModel();
$importIds = $batchImportModel->getIdCollection();
$recordCount = null;
$totalproducts = count($importIds);
$saved = 0;
$batchArrayIds = array();
foreach ($importIds as $importId) {
$recordCount++;
$batchArrayIds[] = $importId;
if ($recordCount%$batchLimit == 0 || $recordCount == $totalproducts) {
$paramsArr = array('batchid' => $batchId, 'ids' => $batchArrayIds);
$params = json_encode($paramsArr);
$result = array();
exec("php -f {$root}shell/batch_import_processor.php '{$params}'", $result);
$saved += $result[0];
Mage::log(convert(memory_get_usage()) . " - processed {$recordCount}/$totalproducts. Saved {$result[0]} products.", null, $logFile);
//echo convert(memory_get_usage()) . " - processed {$recordCount}/$totalproducts. Saved {$result[0]} products.\n";
$batchArrayIds = array();
}
}
$batchModel = Mage::getModel('dataflow/batch')->load($batchId);
try {
$batchModel->beforeFinish();
} catch (Mage_Core_Exception $e) {
Mage::log(convert(memory_get_usage()) . " - ERROR: ". $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: ". $e->getMessage() . "\n";
} catch (Exception $e) {
Mage::log(convert(memory_get_usage()) . " - ERROR: An error occurred while finishing process. Please refresh the cache" . $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: An error occurred while finishing process. Please refresh the cache" . $e->getMessage() . "\n";
}
$batchModel->delete();
// Output Debugging Info
foreach ($profile->getExceptions() as $e) {
Mage::log(convert(memory_get_usage()) . " - " . $e->getMessage(), null, $logFile);
//echo convert(memory_get_usage()) . " - " . $e->getMessage() . "\n";
}
Mage::log("IMPORT COMPLETE.", null, $logFile);
//echo "IMPORT COMPLETE.\n";
?>
batch_import_processor.php
<?php
$root = '/your/path/to/magento/root/directory/';
$logFile = 'magento_import.log';
require_once $root . 'app/Mage.php';
set_time_limit(0);
ini_set('memory_limit', '128M');
ob_implicit_flush();
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$params = $argv[1];
$paramsArray = json_decode($params, true);
$batchId = $paramsArray['batchid'];
$importIds = $paramsArray['ids'];
$saved = 0;
$batchModel = Mage::getModel('dataflow/batch')->load($batchId);
$batchImportModel = $batchModel->getBatchImportModel();
$adapter = Mage::getModel($batchModel->getAdapter());
$adapter->setBatchParams($batchModel->getParams());
foreach ($importIds as $importId) {
$batchImportModel->load($importId);
if (!$batchImportModel->getId()) {
Mage::log(convert(memory_get_usage()) . " - ERROR: Skip undefined row {$importId}", null, $logFile);
//echo convert(memory_get_usage()) . " - ERROR: Skip undefined row {$importId}\n";
continue;
}
try {
$importData = $batchImportModel->getBatchData();
$adapter->saveRow($importData);
} catch (Exception $e) {
Mage::log("Exception : " . $e, null, $logFile);
//echo "Exception : " . $e;
continue;
}
$saved ++;
}
if (method_exists($adapter, 'getEventPrefix')) {
// Event to process rules relationships after import
Mage::dispatchEvent($adapter->getEventPrefix() . '_finish_before', array(
'adapter' => $adapter
));
// Clear affected ids for possible reuse
$adapter->clearAffectedEntityIds();
}
Mage::log("Total Products to Import: " . $saved, null, $logFile);
echo $saved;
?>
添加到此代码中并不难,因此如果您需要,您可以按顺序 运行 多个配置文件。否则,请务必从 Magento 后端获取配置文件 ID 并将 $profile_id 变量设置为所需的值。
如果您喜欢这条路线,我已经在下面的相应回显语句中包含了对 Magento 日志 (Mage::log) 的调用。根据需要进行编辑。日志应保存在 /magento/root/var/log/ 目录中。请务必通过以下方式在 Magento 后端启用此功能:
- 系统 > 配置 > 高级 > 开发人员 > 日志设置
并启用设置 "Yes" 见下文:
在 运行 更新 importer.php 文件后,您应该在 /magento/root/var/log/目录:
- system.log
- magento_import.log
您可能还拥有始终启用的 exception.log 文件。
这是我发现与 Magento 1.9.1.0 一起使用的唯一解决方案,感谢 Andrey 的启发。
随时欢迎任何想法或改进。