Opencart Admin Cron Jobs

Ald*_*aya 4 php cron url-routing token opencart

我知道CRON以及如何创建/管理它.但这个问题不同.

我想开发一个模块来删除超过给定时间范围的任何(未付)订单.例如:我想删除订单下达后2天内尚未支付的任何未付订单.

我想在opencart中使用现有的模型(而不是使用新的模型).让我们说模块URL将是:http://www.yourstore.com/admin/index.php ? route = modules/modulelen/function并且将从CRON调用,然后所有任何未付的订单都将消失.

但主要问题是:当CRON想要访问该URL时,它需要一个安全令牌,否则它将永远不会被执行.

我的问题是:如何在没有安全令牌的情况下从CRON执行该模块(仅适用于该模块)?

请帮助我,如果你有更好的想法或更干净的方式,我会说非常感谢你.

Ija*_*een 12

更新:对于Opencart版本<= 1.5.6.4

对于管理员相关的cron作业,请这样做.

  1. 复制admin/index.phpadmin/index_for_cron.php

  2. 现在,在admin/index_for_cron.php搜索这两行并将其注释掉,这些行负责登录和权限.

    // Login
    // $controller->addPreAction(new Action('common/home/login'));
    
    // Permission
    // $controller->addPreAction(new Action('common/home/permission'));
    
    Run Code Online (Sandbox Code Playgroud)
  3. 现在使用此URL作为您的cron作业.

    http://www.yourstore.com/admin/index_for_cron.php?route=module/modulename/function

注意:index_for_cron.php出于安全原因,强烈建议将名称更改为难看的,不可预测的名称.

希望这可以帮助 :)

  • 如果 index_for_cron.php 不是从命令行执行的,我建议添加一个额外的安全层添加一个退出。这适用于第一行: (PHP_SAPI !== 'cli' || isset($_SERVER['HTTP_USER_AGENT'])) &amp;&amp; die('cli only'); (2认同)

Mik*_*e T 8

我做过类似于IJas的事情.在管理员和目录旁边,我创建了一个名为"cli"的新文件夹.

该文件夹包含一个php文件,用于cli执行的特定功能(通过crontab在设定的时间表上执行脚本,或在命令行中手动执行),以及这些类型脚本的"引导程序".自举基本上是在产品目录中或管理中发现的"索引"的副本,并且包括一些检查并删除权限检查和其他一些不必要的项目.它调用调用特定函数脚本中提出的任何控制器/操作(在下面的示例中,它调用/admin/controller/common/cli_some_function.php中定义的类的索引方法).

功能特定脚本:

<?php
$cli_action = 'common/cli_some_function';
require_once('cli_dispatch.php');
?>
Run Code Online (Sandbox Code Playgroud)

CLI"Bootstrap"/ Dispatcher:

<?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();
?>
Run Code Online (Sandbox Code Playgroud)

使用这个方案,我可以确保不会从Web调用脚本,我可以使用cron作业从服务器本身自动启动它(例如:0 1 0 0 0/path/to/php/path /to/opencart/cli/cli_some_function.php)

请注意,error_handler函数正在使用一些不是开箱即用的配置选项.您可以设置它们或在那里进行自己的检查.

EDIT对错误处理进行了一些更改


Hay*_*ing 6

在 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;
Run Code Online (Sandbox Code Playgroud)

然后我将其添加到我的 cron 中:

php-cli -r 'echo file_get_contents("https://www.website.com/admin/index.php?route=common/cron/action&pass=secretpassword");'
Run Code Online (Sandbox Code Playgroud)

  • 我仍然在几个客户端中使用 OC 2.3,并且这种方法是我一直采用的方法。 (2认同)