Админ В OpenCart Хрон Рабочих Мест


Я знаю о CRON и как создать / управлять им. Но этот вопрос был другим.

Я хочу разработать модуль для удаления любого (неоплаченного) Заказа, который превышает заданные временные рамки. Например: я хочу удалить любой неоплаченный заказ, который не был оплачен в течение 2 дней после размещения заказа.

Я хочу использовать существующую модель в opencart (а не использовать новую). Допустим, URL модуля будет следующим: http://www.yourstore.com/admin/index.php?route=module/modulename/function И будет позвоните из Крона, и тогда все неоплаченные заказы исчезнут.

Но главная проблема заключается в следующем: когда CRON хочет получить доступ к этому URL, ему нужен маркер безопасности, иначе он никогда не будет выполнен.

Мой вопрос: Как выполнить этот модуль из CRON без маркера безопасности (в случае только для этого модуля)?

Пожалуйста, помогите мне, если у вас есть идея получше или более чистый способ, я бы сказал Вам большое спасибо.
5 4

5 ответов:

Для заданий cron, связанных с администратором, выполните следующее.

  1. Копировать admin/index.php Чтобы admin/index_for_cron.php

  2. Теперь, в admin/index_for_cron.php, найдите эти 2 строки и закомментируйте их, которые отвечают за вход и разрешения.

    // In line 181
    // Login
    // $controller->addPreAction(new Action('common/home/login'));
    
    // In line 184
    // Permission
    // $controller->addPreAction(new Action('common/home/permission'));
    
  3. Теперь используйте этот url-адрес для задания cron.

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

Примечание: это настоятельно рекомендуется изменить название index_for_cron.php в уродливое, непредсказуемое имя из соображений безопасности.

Надеюсь, это поможет :)

Я сделал нечто подобное с Иджасом. Рядом с admin и catalog я создал новую папку под названием "cli".

Эта папка содержит php-файл для конкретной функции, выполняемой cli (выполнение скриптов через crontab по заданному расписанию или вручную в командной строке), а также своего рода "bootstrap" для этих типов скриптов. Загрузчик по сути является копией "индекса", найденного в каталоге или администраторе, и включает в себя некоторые проверки и удаляет проверку разрешений, а некоторые другие ненужные предметы. Он вызывает любой контроллер / действие, заданное в вызывающем скрипте конкретной функции (в примере ниже он вызывает метод индекса класса, определенного в /admin / controller / common / cli_some_function.РНР).

Функциональный Сценарий:

<?php
$cli_action = 'common/cli_some_function';
require_once('cli_dispatch.php');
?>

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();
?>

Используя эту схему, я могу гарантировать, что скрипт не будет вызван из интернета, и я могу запустить его автоматически с самого сервера использование задания cron (например: 0 1 0 0 0 /path / to / php / path/to / opencart / cli / cli_some_function.php)

Обратите внимание , что функция error_handler использует некоторые параметры конфигурации, которые не являются готовыми. Вы можете либо установить их, либо поставить свой собственный чек.

EDIT внес некоторые изменения в обработку ошибок

Поскольку у меня было подобное требование несколько раз, я поместил свои идеи в легкий инструмент командной строки под названием OCOK.

Особенно команда Cli Task позволяет вызывать контроллеры 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)

Соответствующие пути, конечно, должны быть установлены правильно.

Установка доступна с composer. Вся дальнейшая документация может быть найдена внутри docs: OCOK

По умолчанию opencart не разрешает доступ к страницам администратора без логина. Проверка логина и токена производится методом login() в admin/controller/common/home.php.

it cant be set on frontend coz the model is in admin area. - Вы можете создать новый контроллер и модель для frontend с тем же функционалом в админ панели и использовать его для cronjob.

В Opencart есть группы пользователей, которые устанавливают права доступа для пользователей. Таким образом, страницы администратора не будут загружаться для пользователей без разрешения. Следовательно, вам может потребоваться очень сильно изменить основные файлы для установки cronjob в админ-панели, что может привести к серьезным проблемам безопасности.

Я предлагаю интерфейс контроллера и файл модели для cronjob. Для дополнительной безопасности вы можете передать определенный ключевой параметр в url и написать условие для его проверки.

Хорошего вам дня !!

Я знаю, что это очень старый вопрос, но я потратил довольно много времени, пытаясь понять, как сделать то же самое в opencart версии 2.x, который работает по-другому. Поэтому я делюсь здесь своим решением.(на основе подхода Майка Т)

1-создайте папку cli рядом с admin и catalog.
2-в этой же папке создайте файл, который вы будете запускать через cron или comandline, например runcron.php

#!/usr/bin/php
<?php
require_once('cli_dispatch.php');

3-в той же папке создайте cli_dispatch.php файл, который является копией индекса.PHP-файл в папке admin с некоторыми изменениями (обратите внимание, что в этой установке есть активированный 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 для чтения конфигурации вашего нового загрузчика cli из файла upload / system / framework.php

    <?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';  

Изменение 'sale/yourscript' с указанием пути и имени файла контроллера.

В Примере runnunig The runcron.php-файл будет выполнять функцию индекса в

upload/admin/controller/sale/yourscript.php file