[英]Opencart Admin Cron Jobs
我了解 CRON 以及如何創建/管理它。 但這個問題不同。
我想開發一個模塊來刪除超過給定時間范圍的任何(未付款)訂單。 例如:我想刪除下訂單后 2 天內未付款的任何未付款訂單。
我想在 opencart 中使用現有模型(而不是使用新模型)。 假設模塊 URL 將是: http://www.yourstore.com/admin/index.php?route=module/modulename/function並且將從 CRON 調用,然后所有未支付的訂單都將消失。
但主要問題是:當 CRON 想要訪問該 URL 時,它需要一個安全令牌,否則它將永遠不會被執行。
我的問題是:如何在沒有安全令牌的情況下從 CRON 執行該模塊(以防僅用於該模塊)?
請幫助我,如果您有更好的主意或更干凈的方法,我會非常感謝您。
更新:對於 Opencart 版本 <= 1.5.6.4
對於與管理相關的 cron 作業,請這樣做。
將admin/index.php
復制到admin/index_for_cron.php
現在,在admin/index_for_cron.php
,搜索這兩行並將它們注釋掉,它們負責登錄和權限。
// Login // $controller->addPreAction(new Action('common/home/login')); // Permission // $controller->addPreAction(new Action('common/home/permission'));
現在將此 url 用於您的 cron 作業。
http://www.yourstore.com/admin/index_for_cron.php?route=module/modulename/function
注意:出於安全原因,強烈建議將index_for_cron.php
的名稱更改為丑陋的、不可預測的名稱。
希望這可以幫助 :)
我做過類似 IJas 的事情。 在管理員和目錄旁邊,我創建了一個名為“cli”的新文件夾。
該文件夾包含一個由 cli 執行的特定功能的 php 文件(通過 crontab 按設定的時間表執行腳本,或在命令行中手動執行),以及這些類型的腳本的各種“引導程序”。 引導程序本質上是在目錄或管理員中找到的“索引”的副本,包括一些檢查和刪除權限檢查和一些其他不必要的項目。 它調用在調用特定函數腳本中設置的任何控制器/操作(在下面的示例中,它調用 /admin/controller/common/cli_some_function.php 中定義的類的 index 方法)。
功能特定腳本:
<?php
$cli_action = 'common/cli_some_function';
require_once('cli_dispatch.php');
?>
CLI“引導程序”/調度程序:
<?php
// CLI must be called by cli php
if (php_sapi_name() != 'cli') {
syslog(LOG_ERR, "cli $cli_action call attempted by non-cli.");
http_response_code(400);
exit;
}
// Ensure $cli_action is set
if (!isset($cli_action)) {
echo 'ERROR: $cli_action must be set in calling script.';
syslog(LOG_ERR, '$cli_action must be set in calling script');
http_response_code(400);
exit;
}
// Handle errors by writing to log
function cli_error_handler($log_level, $log_text, $error_file, $error_line) {
syslog(LOG_ERR, 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line);
echo 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line;
}
set_error_handler('cli_error_handler');
// Configuration not present in CLI (vs web)
chdir(__DIR__.'/../admin');
set_include_path(get_include_path() . PATH_SEPARATOR . realpath(dirname(__FILE__)) . '../admin/');
$_SERVER['HTTP_HOST'] = '';
// Version
define('VERSION', '1.5.1');
// Configuration (note we're using the admin config)
require_once('../admin/config.php');
// Configuration check
if (!defined('DIR_APPLICATION')) {
echo "ERROR: cli $cli_action call missing configuration.";
$log->write("ERROR: cli $cli_action call missing configuration.");
http_response_code(400);
exit;
}
// Startup
require_once(DIR_SYSTEM . 'startup.php');
// Application Classes
require_once(DIR_SYSTEM . 'library/currency.php');
require_once(DIR_SYSTEM . 'library/user.php');
require_once(DIR_SYSTEM . 'library/weight.php');
require_once(DIR_SYSTEM . 'library/length.php');
// Registry
$registry = new Registry();
// Loader
$loader = new Loader($registry);
$registry->set('load', $loader);
// Config
$config = new Config();
$registry->set('config', $config);
// Database
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
// Settings
$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = '0'");
foreach ($query->rows as $setting) {
if (!$setting['serialized']) {
$config->set($setting['key'], $setting['value']);
} else {
$config->set($setting['key'], unserialize($setting['value']));
}
}
// Url
$url = new Url(HTTP_SERVER, HTTPS_SERVER);
$registry->set('url', $url);
// Log
$log = new Log($config->get('config_error_filename'));
$registry->set('log', $log);
function error_handler($errno, $errstr, $errfile, $errline) {
global $log, $config;
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
$error = 'Notice';
break;
case E_WARNING:
case E_USER_WARNING:
$error = 'Warning';
break;
case E_ERROR:
case E_USER_ERROR:
$error = 'Fatal Error';
break;
default:
$error = 'Unknown';
break;
}
if ($config->get('config_error_display')) {
echo "\n".'PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline."\n";
}
if ($config->get('config_error_log')) {
$log->write('PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline);
}
return true;
}
set_error_handler('error_handler');
$request = new Request();
$registry->set('request', $request);
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$registry->set('response', $response);
$cache = new Cache();
$registry->set('cache', $cache);
$session = new Session();
$registry->set('session', $session);
$languages = array();
$query = $db->query("SELECT * FROM " . DB_PREFIX . "language");
foreach ($query->rows as $result) {
$languages[$result['code']] = $result;
}
$config->set('config_language_id', $languages[$config->get('config_admin_language')]['language_id']);
$language = new Language($languages[$config->get('config_admin_language')]['directory']);
$language->load($languages[$config->get('config_admin_language')]['filename']);
$registry->set('language', $language);
$document = new Document();
$registry->set('document', $document);
$registry->set('currency', new Currency($registry));
$registry->set('weight', new Weight($registry));
$registry->set('length', new Length($registry));
$registry->set('user', new User($registry));
$controller = new Front($registry);
$action = new Action($cli_action);
$controller->dispatch($action, new Action('error/not_found'));
// Output
$response->output();
?>
使用此方案,我可以確保不會從網絡調用腳本,並且我可以使用 cron 作業從服務器本身自動觸發它(例如:0 1 0 0 0 /path/to/php /path /to/opencart/cli/cli_some_function.php)
請注意, error_handler 函數使用了一些非現成的配置選項。 您可以設置它們或將自己的支票放在那里。
編輯對錯誤處理進行了一些更改
在 2.3.0.2 中,我發現一種非常簡單的方法是將您的控制器函數路徑添加到登錄和權限限制的忽略路徑設置中。 然后只需在該控制器功能中添加一個 url 密碼或其他檢查來鎖定它。
所以首先在 admin/controller/startup/login.php 中將你的控制器函數路徑添加到 $ignore 數組中,例如 'common/cron/action'
然后在 admin/controller/startup/permissions.php 中你只需要控制器路徑,例如“common/cron”
然后最后在你的 action() 函數開始時這樣做:
if(!isset($_GET['pass']) || $_GET['pass'] != 'secretpassword')return;
然后我只是將它添加到我的 cron 中:
php-cli -r 'echo file_get_contents("https://www.website.com/admin/index.php?route=common/cron/action&pass=secretpassword");'
由於我多次有類似的需求,我將我的想法放入一個名為OCOK的輕量級命令行工具中。
特別是 Cli 任務命令允許您通過命令行調用 Opencart 控制器,從而讓您將它們稱為 cron 作業。 只需像這樣創建一個控制器並將其保存為admin/controller/task/example.php
:
class ControllerTaskExample extends Controller {
public function index() {
if (isset($this->is_cli) && $this->is_cli === true) {
// work done by the controller
if (isset($this->request->get['param1'])) {
echo "param1 is " . $this->request->get['param1'] . "\n";
}
if (isset($this->request->get['param2'])) {
echo "param2 is " . $this->request->get['param2'] . "\n";
}
}
}
}
通過命令行可以使用參數調用它:
ocok run task/example param1=foo param2=bar
上述命令將輸出:
param1 is foo
param2 is bar
將此添加到 crontab 就像將以下行添加到您的 cron 文件一樣簡單:
* * * * * (cd /path/to/opencart/folder; /path/to/ocok run task/example param1=foo param2=bar)
當然需要正確設置相應的路徑。
我知道這是一個非常古老的問題,但我花了很長時間試圖弄清楚如何在不同的 opencart 版本 2.x 中做同樣的事情。 所以我在這里分享我的解決方案。(基於 Mike T 方法)
1 - 在 admin 和 catalog 旁邊創建 cli 文件夾。
2 - 在同一個文件夾中創建一個文件,您將通過 cron 或命令行運行該文件,例如 runcron.php
#!/usr/bin/php
<?php
require_once('cli_dispatch.php');
3 - 在同一文件夾中創建 cli_dispatch.php 文件,該文件是 admin 文件夾中 index.php 文件的副本,並進行了一些更改(注意在此安裝中激活了 VQMOD,這可能不是您的情況)
<?php
// CLI must be called by cli php
if (php_sapi_name() != 'cli') {
syslog(LOG_ERR, "cli $cli_action call attempted by non-cli.");
http_response_code(400);
exit;
}
// Ensure $cli_action is set
if (!isset($cli_action)) {
echo 'ERROR: $cli_action must be set in calling script.';
syslog(LOG_ERR, '$cli_action must be set in calling script');
http_response_code(400);
exit;
}
// Handle errors by writing to log
function cli_error_handler($log_level, $log_text, $error_file, $error_line) {
syslog(LOG_ERR, 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line);
echo 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line;
}
set_error_handler('cli_error_handler');
// Configuration (note we're using the admin config)
require_once __DIR__.('/../admin/config.php');
// Configuration not present in CLI (vs web)
chdir(__DIR__.'/../admin');
set_include_path(get_include_path() . PATH_SEPARATOR . realpath(dirname(__FILE__)) . '../admin/');
$_SERVER['HTTP_HOST'] = '';
if (!defined('DIR_APPLICATION')) {
echo "ERROR: cli $cli_action call missing configuration.";
http_response_code(400);
exit;
}
// Version
define('VERSION', '2.3.0.3_rc');
// Configuration
if (is_file('config.php')) {
require_once('config.php');
}
// Install
if (!defined('DIR_APPLICATION')) {
header('Location: ../install/index.php');
exit;
}
//VirtualQMOD
require_once('../vqmod/vqmod.php');
VQMod::bootup();
// VQMODDED Startup
require_once(VQMod::modCheck(DIR_SYSTEM . 'startup.php'));
start('cli');
4 - 現在創建文件upload/system/config/cli.php,它將是opencart 用來從文件upload/system/framework.php 讀取新cli bootrasp 配置的文件
<?php
// Site
$_['site_base'] = HTTP_SERVER;
$_['site_ssl'] = HTTPS_SERVER;
// Database
$_['db_autostart'] = true;
$_['db_type'] = DB_DRIVER; // mpdo, mssql, mysql, mysqli or postgre
$_['db_hostname'] = DB_HOSTNAME;
$_['db_username'] = DB_USERNAME;
$_['db_password'] = DB_PASSWORD;
$_['db_database'] = DB_DATABASE;
$_['db_port'] = DB_PORT;
// Session
//$_['session_autostart'] = true;
// Autoload Libraries
$_['library_autoload'] = array(
'openbay'
);
// Actions
$_['action_pre_action'] = array(
'startup/startup',
'startup/error',
'startup/event',
'startup/sass',
// 'startup/login',
// 'startup/permission'
);
// Actions
$_['action_default'] = 'sale/croninvoices';
// Action Events
$_['action_event'] = array(
'view/*/before' => 'event/theme'
);
正如你所看到的,我已經評論了所有與權限相關的會話和操作行。
您將需要編輯該行
$_['action_default'] = 'sale/yourscript';
使用控制器的路徑和文件名更改“銷售/您的腳本”。
在示例中,runnunig runcron.php 文件將執行索引函數
upload/admin/controller/sale/yourscript.php file
在 opencart 2.1.0.2 中。 如果您在 cron 作業中需要 db ,但不需要任何 opencart 模型。 您可以創建文件 system/mycron/cron_task.php。 並將這樣的代碼添加到這個文件中:
// CLI
include_once 'config.php';
include_once DIR_SYSTEM.'library/db/mysqli.php';
include_once DIR_SYSTEM.'helper/general.php';
mb_internal_encoding('UTF-8');
if (php_sapi_name() != 'cli') { error_log('NOT CLI CALL');print 'NOT CLI CALL';http_response_code(400);exit; }
$db = new DB\MySQLi(DB_HOSTNAME,DB_USERNAME,DB_PASSWORD,DB_DATABASE,DB_PORT);
// END CLI
// Your actual code, and you CAN use opencart DB!
foreach ($db->query("SELECT * FROM oc_product")->rows as $row) {
//...
}
現在你可以從你的 cron 工作中運行它:
12 7 * * * cd /path/to/opencart/root/folder && php system/mycron/cron_task.php
默認情況下,opencart 不允許在未登錄的情況下訪問管理頁面。 在admin/controller/common/home.php
中的login()
方法中檢查登錄和令牌驗證。
it cant be set on frontend coz the model is in admin area.
- 您可以在管理面板中為前端創建一個具有相同功能的新控制器和模型,並將其用於 cronjob。
Opencart 有為用戶設置訪問權限的用戶組。 因此,未經許可,不會為用戶加載管理頁面。 因此,您可能需要大量修改核心文件以在管理面板中設置 cronjob,這可能會導致嚴重的安全問題。
我建議為 cronjob 使用前端控制器和模型文件。 為了獲得額外的安全性,您可以在 url 中傳遞一個特定的關鍵參數並編寫一個條件來驗證它。
祝你今天過得愉快 !!
“我想開發一個模塊來刪除任何超出給定時間范圍的(未付款)訂單。例如:我想刪除在下訂單后 2 天內未付款的任何未付款訂單。” “我想在 opencart 中使用現有模型(而不是使用新模型)。”
所以,我相信你知道,問題是你必須登錄到管理員才能訪問它的控制器和模型,但運行時不會登錄 cron 作業。
您可以查看目錄模型是否可以滿足您的需求,在這種情況下沒有問題:
catalog/model/checkout/order.php
您可以在此處遵循其他答案 - 即找到一些登錄方法。
或者您可以編寫一個獨立的 PHP 腳本來運行一個簡單的 SQL 查詢。
您是對的,使用系統模型通常是正確的做法,但是 OpenCart 非常簡單,它應該是一個非常簡單的查詢(只有幾行),可以滿足您的需要,因此這也是一個可以接受的選擇在我看來,在這種情況下。
include_once($_SERVER['DOCUMENT_ROOT'].'/admin/model/module/ModelYourModel.php');
$mym = new ModelYourModel($this->registry);
$mym->yourFunction();
對於 2.1 版,可能更高。 使用目錄文件夾中 admin 文件夾中的模型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.