<?php

//namespace cab\system;

class i_crontab
{
    public static function panel_crontab_status($crontab_cmd,$options=[])
    {   $rec_cron=execSQL_van('select * from '.TM_CRONTAB.' where cmd=:crontab_cmd limit 1',[':crontab_cmd'=>$crontab_cmd]); ;
        if ($rec_cron['pkey'])
        {
            if ($options['show_button_manual_start']) {?><button class="button left v1" cmd="exec_crontab" crontab_id="<?echo $rec_cron['pkey']?>">Запустить вручную</button><?}
            $cron_enabled=($rec_cron['enabled'])? 1:0 ;
            echo $rec_cron['obj_name'].': ' ;
            $cur_status=($cron_enabled)? '<span class="green">Включено</span>, '.$rec_cron['intr']:'<span class="red">Выключено</span>';
            echo '<span id="cron_status_'.$rec_cron['pkey'].'"><strong>'.$cur_status.'</strong></span>' ;
            ?><label class="ios7-switch" style="font-size: 15px;"><input type="checkbox" class="v2" cmd="setting/change_cron_work_status" id="<?echo $rec_cron['pkey'];?>" <?if ($cron_enabled) echo 'checked'?>><span class="switch"></span></label><br><?

            if ($_POST['cmd']=='exec_crontab' and $_POST['crontab_id']==$rec_cron['pkey'])
            {
                echo '<h2>Выполняем задание "'.$rec_cron['obj_name'].'"</h2>' ;
                echo 'Выполняем задание <strong>'.$rec_cron['obj_name'].'</strong>'.' ['.$rec_cron['cmd'].']'.'<br>' ;
                static::exec_cmd($rec_cron,['show_debug'=>1]);
            }
        }
    }

    public static function get_cron_by_code($code)
    {
        $rec=execSQL_van('SELECT * FROM ' . TM_CRONTAB . ' WHERE cmd="' . $code . '" ');
        return $rec;
    }

    public static function reg_cron($name, $cmd, $intr, $options=array())
    {
        include_once(_DIR_TO_MODULES . '/engine/i_setup.php');
        SETUP()->reg_cron($name, $cmd, $intr, $options);
    }

    public static function cron_exec()
    {
        set_time_point('cron_exec start');
        $t_start=fixed_time();
        if (!$GLOBALS['LS_cron_active'] && !$_GET['id']) return;
        if ($GLOBALS['LS_cron_block']) return;
        $now=($_GET['to_time']) ? getdate(strtotime($_GET['to_time'])) : getdate();
        $cur_time=mktime($now['hours'], $now['minutes'], 0, $now['mon'], $now['mday'], $now['year']);

        ob_start();

        // Сбрасываем задания, которые висят более часа
        $check_time=mktime($now['hours'], $now['minutes'] - 60, $now['seconds'], $now['mon'], $now['mday'], $now['year']);
        $recs=execSQL('SELECT * FROM ' . TM_CRONTAB . ' WHERE status=1 AND last_exec<' . $check_time);
        if (!empty($recs))
        {
            ob_start();
            echo 'Зависшие задания от ' . date('d.m.Y H:i:s', $check_time) . '<br>';
            echo 'Текущее время ' . date('d.m.Y H:i:s') . '<br>';
            print_2x_arr($recs);
            $cnt=execSQL_update('UPDATE ' . TM_CRONTAB . ' SET last_exec_end=0, time_exec=0, status=0 WHERE status=1 AND last_exec<' . $check_time, array('debug'=>2));
            echo 'Было сброшено <strong>' . $cnt . '</strong> зависших заданий<br>';
            $text=ob_get_clean();
            echo $text . '<br>';
            $fname=LOGS()->reg_file_log('crontab_init', $text);
            LOGS()->reg_log('crontab_init', '<a target=_blank href="' . $fname . '">Отчет</a>');
            update_site_setting('LS_last_cron_status', 0, array('no_log'=>1));
            $GLOBALS['LS_last_cron_status']=0;
        }
        set_time_point('проверка зависших заданий');

        if (!$GLOBALS['LS_last_cron_status_dontuse'] && $GLOBALS['LS_last_cron_status'])
        {
            LOGS()->reg_log('exec_crontab', 'Выполняется сеанс планировщика от ' . date('d.m.Y H:i:s', $GLOBALS['LS_last_cron_status']) . ', выполнение текущего сеанса отменено');
        }
        else
        {
            update_site_setting('LS_last_cron_status', time(), array('no_log'=>1));
            $usl_id=($_GET['id']) ? ' AND pkey=' . (int)$_GET['id'] : '';
            $debug=($usl_id) ? 2 : 0;
            $list_crontab=execSQL('SELECT pkey, c_data, cmd, obj_name, last_exec, last_exec_end, time_exec, intr, status
                                      FROM ' . TM_CRONTAB . '
                                      WHERE enabled=1 AND status=0 ' . $usl_id . '
                                      ORDER BY intr', $debug);
            if (!empty($list_crontab))
            {
                foreach ($list_crontab as $rec_cron)
                {
                    $result=array();
                    $last_exec=($rec_cron['last_exec']) ? $rec_cron['last_exec'] : mktime(23, 59, 0, $now['mon'], $now['mday'] - 1, $now['year']);
                    $ii=0;
                    do
                    {
                        $plan_exec=static::crontab_exec_next_time($rec_cron['intr'], $last_exec, $now);
                        if ($ii > 100000) break; // защита от зацикливания
                        $ii++;
                        if ($plan_exec < $cur_time) $last_exec=$plan_exec;
                    } while ($plan_exec < $cur_time);

                    $result['ID']=$rec_cron['pkey'];
                    $result['Расписание']=$rec_cron['intr'];
                    $result['Операция']=$rec_cron['cmd'];
                    $result['Последнее время запуска']=($rec_cron['last_exec']) ? date('d.m.Y H:i:s', $rec_cron['last_exec']) : '-';
                    $result['Следущее время запуска']=date('d.m.Y H:i:s', $plan_exec);
                    $result['Текущее время']=date('d.m.Y H:i:s', $cur_time);
                    $result['Пройдено интервалов']=$ii;

                    if ( date('Y-m-d H:i', $plan_exec) == date('Y-m-d H:i', $cur_time) && $plan_exec > $rec_cron['last_exec'])
                    {
                        echo '<span class="green">Выполняем задание <strong>' . $rec_cron['obj_name'] . '</strong></span>';

                        static::exec_cmd($rec_cron);

                        $result['process']='Старт';
                    }
                    else if ($plan_exec > $cur_time)
                    {
                        if ($GLOBALS['LS_crontab_log_full'])
                        {
                            echo '<div style="color:#b94a48">Задание <strong>' . $rec_cron['obj_name'] . '</strong> - еще рано, будет выполнено ' . date('d.m.Y H:i', $plan_exec) . '</div>';
                        }
                    }
                    else if ($plan_exec < $rec_cron['last_exec'])
                    {
                        if ($GLOBALS['LS_crontab_log_full'])
                        {
                            echo '<div style="color:#0D9EDF">Задание <strong>' . $rec_cron['obj_name'] . '</strong> - уже выполнено ' . date('d.m.Y H:i', $rec_cron['last_exec']) . '</div>';
                        }
                    }
                    else if ($plan_exec < $cur_time)
                    {
                        if ($GLOBALS['LS_crontab_log_full'])
                        {
                            echo '<div style="color:#b94a48">Задание <strong>' . $rec_cron['obj_name'] . '</strong> - уже поздно, должно было быть выполнено в ' . date('d.m.Y H:i', $plan_exec) . '</div>';
                        }
                    }
                    $cron_result[$rec_cron['obj_name']]=$result;
                }
            }
            $text=ob_get_clean();
            ob_start();
            ?>
            <link rel="stylesheet" type="text/css" href="/<?php echo _CLASS_; ?>/style.css" charset="utf-8">
            <?php
            print_2x_arr($cron_result);
            $text_arr=ob_get_clean();
            echo $text_arr . '<br>' . $text;
            set_time_point('Все задания выполнены');
            LOGS()->reg_log('exec_crontab', $text, array('start'=>$t_start, 'save_to_file'=>$text_arr));
            update_site_setting('LS_last_cron_time', $cur_time, array('no_log'=>1));
            update_site_setting('LS_last_cron_status', 0, array('no_log'=>1));
            set_time_point('Переменные обновлены');
        }
    }

    public static function exec_cmd($rec_cron,$options=[])
    {
        if (stripos($rec_cron['cmd'],'\\')!==false) static::exec_cmd_by_namespace_chema($rec_cron,$options) ;
        else static::exec_cmd_by_modul_chema($rec_cron,$options) ;
    }

    public static function exec_cmd_by_namespace_chema($rec_cron,$options=[])
    {
        ob_start();
        set_time_point('Выполнение задания ' . $rec_cron['obj_name'] . ' - start');
        execSQL_update('UPDATE ' . TM_CRONTAB . ' SET last_exec=' . time() . ', last_exec_end=0, time_exec=0, status=1 WHERE pkey=' . $rec_cron['pkey'], array('debug'=>0));
        $t1=fixed_time();
        $result_exec=$rec_cron['cmd']() ; // выполняем команду
        $t2=fixed_time($t1, 'Выполнено задание "' . $rec_cron['obj_name'] . '"');
        set_time_point('Выполнение задания ' . $rec_cron['obj_name'] . ' - end');
        execSQL_update('UPDATE ' . TM_CRONTAB . ' SET last_exec_end=' . time() . ', time_exec="' . $t2 . '", status=0 WHERE pkey=' . $rec_cron['pkey'], array('debug'=>0));
        if (!empty($result_exec)) damp_array($result_exec, 1, -1);

        $text_debug=ob_get_clean();
        if ($options['show_debug']) echo $text_debug;
        $log_fname=LOGS()->reg_file_log('exec_crontab', $text_debug);
        set_time_point('Сохранен файловый лог задания ' . $rec_cron['obj_name'] . ' - end');
        //echo ' <a href="/logs/' . str_replace(array('[fname=', ']'), '', basename($log_fname)) . '" target="_blank">Отчет</a>, ' . round($t2, 4) . ' сек.<br>';
        echo ' <a href="'.$log_fname.'" target="_blank">Отчет</a>, ' . round($t2, 4) . ' сек.<br>';
    }

    public static function exec_cmd_by_modul_chema($rec_cron,$options=[])
    {
        $arr=explode('/', $rec_cron['cmd']);
        if (count($arr) == 2 || count($arr) == 3)
        {
            if (is_object($arr[0]()))
            {
                if (method_exists($arr[0](), $arr[1]))
                {
                    ob_start();

                    set_time_point('Выполнение задания ' . $rec_cron['obj_name'] . ' - start');
                    execSQL_update('UPDATE ' . TM_CRONTAB . ' SET last_exec=' . time() . ', last_exec_end=0, time_exec=0, status=1 WHERE pkey=' . $rec_cron['pkey'], array('debug'=>0));
                    $t1=fixed_time();
                    $func_name=$arr[0];
                    $method_name=$arr[1];
                    if ($func_name and $method_name) $result_exec=$func_name()->$method_name();
                    $t2=fixed_time($t1, 'Выполнено задание "' . $rec_cron['obj_name'] . '"');
                    set_time_point('Выполнение задания ' . $rec_cron['obj_name'] . ' - end');
                    execSQL_update('UPDATE ' . TM_CRONTAB . ' SET last_exec_end=' . time() . ', time_exec="' . $t2 . '", status=0 WHERE pkey=' . $rec_cron['pkey'], array('debug'=>0));
                    if (!empty($result_exec)) damp_array($result_exec, 1, -1);

                    $text_debug=ob_get_clean();
                    if ($options['show_debug']) echo $text_debug.'<br>';
                    $log_fname=LOGS()->reg_file_log('exec_crontab', $text_debug);
                    set_time_point('Сохранен файловый лог задания ' . $rec_cron['obj_name'] . ' - end');
                    echo ' <a href="/logs/' . str_replace(array('[fname=', ']'), '', basename($log_fname)) . '" target="_blank">Отчет</a>, ' . round($t2, 4) . ' сек.<br>';
                }
                else
                {
                    echo '<div class="alert">В модуле <strong>' . $arr[0] . '</strong> не найден метод <strong>' . $arr[1] . '</strong></div>';
                }
            }
            else
            {
                echo '<div class="alert">Не найден модуль <strong>' . $arr[0] . '</strong> с методом <strong>' . $arr[1] . '</strong></div>';
            }
        }

    }

    /**
     * Вычисляет время следующего запуска задания на основе строки расписания crontab.
     *
     * Поддерживается упрощённый crontab-синтаксис:
     *   - допускается либо фиксированное значение (например, "15" — конкретная минута),
     *   - либо выражение с шагом, например: "*\/N" (каждые N минут/часов/дней).
     *
     * Распознаются и поддерживаются следующие форматы расписания:
     *
     *   0 – каждые X минут      (*\/N * * * *)   — например, каждые 15 минут
     *   1 – раз в час           (M * * * *)     — например, каждый час в 20 минут
     *   2 – каждые X часов      (0 *\/N * * *)   — например, каждые 3 часа в 00 минут
     *   3 – раз в сутки         (M H * * *)     — например, ежедневно в 04:00
     *   5 – раз в месяц         (M H D * *)     — например, 5-го числа каждого месяца в 10:15
     *
     * В режимах с шагами (типы 0, 2 и т.п.) расчёт выполняется от времени последнего запуска (`$last_exec`).
     * В режимах с фиксированными значениями (например, "15 10 5 * *") используется текущая дата,
     * но учитываются явно заданные значения дня, часа и минуты.
     *
     * !!! Внимание: решение о необходимости запуска принимает внешний код (например, cron_exec),
     *               поэтому функция может вернуть время, равное или чуть раньше текущего.
     *
     * @param string $interval   Строка расписания crontab (например, "15 10 5 * *")
     * @param int    $last_exec  Время последнего запуска задания (UNIX timestamp)
     * @param array  $now        Ассоциативный массив с текущими значениями времени:
     *                           ['hours', 'minutes', 'mday', 'mon', 'year']
     *
     * @return int               Планируемое время следующего запуска (UNIX timestamp)
     */
    public static function crontab_exec_next_time($interval, $last_exec, $now)
    {
        $last_exec_parse=getdate($last_exec);
        $arr = explode(' ', $interval);
        // Инициализация значений для минут, часов, дня месяца
        $m_fix=-1;
        $m_every =-1;
        $h_fix=-1;
        $h_every =-1;
        $d_fix=-1;
        $d_every =-1;

        // Минуты
        $arr2=explode('/', $arr[0]);
        if ($arr2[0] != '*')
        {
            $m_fix=$arr2[0];
        }
        else if (isset($arr2[1]))
        {
            $m_every=$arr2[1];
        }
        else
        {
            $m_fix = $now['minutes'];
        }

        // Расчет часов
        $arr2=explode('/', $arr[1]);
        if ($arr2[0] != '*')
        {
            $h_fix=$arr2[0];
        }
        else if (isset($arr2[1]))
        {
            $h_every=$arr2[1];
        }
        else
        {
            $h_fix = $now['hours'];
        }

        // Расчет дня месяца
        $arr2=explode('/', $arr[2]);
        if ($arr2[0] != '*')
        {
            $d_fix=$arr2[0];
        }
        else if (isset($arr2[1]))
        {
            $d_every=$arr2[1];
        }
        else
        {
            $d_fix=$now['mday'];
        }

        // Если есть интервалы — считаем от времени последнего запуска
        if ($m_every > 0 || $h_every > 0 || $d_every > 0) {
            $next_exec_m=($m_every > 0) ? $last_exec_parse['minutes'] + $m_every : $last_exec_parse['minutes'];
            $next_exec_h=($h_every > 0) ? $last_exec_parse['hours'] + $h_every : $last_exec_parse['hours'];
            $next_exec_d=($d_every > 0) ? $last_exec_parse['mday'] + $d_every : $last_exec_parse['mday'];
            $plan_exec = mktime($next_exec_h, $next_exec_m, 0, $last_exec_parse['mon'], $next_exec_d, $last_exec_parse['year']);
        } else {
            // Фиксированное расписание — используем указанный день (если задан)
            $use_day = ($d_fix > 0) ? $d_fix : $now['mday'];
            $plan_exec = mktime($h_fix, $m_fix, 0, $now['mon'], $use_day, $now['year']);
        }

        return $plan_exec;
    }

    /**
    * Разбирает строку crontab и возвращает массив настроек.
    * Поддерживаемые типы:
    * 0 – каждые X минут (*\/N * * * *)<br>
    * 1 – раз в час (M * * * *)<br>
    * 2 – каждые X часов (0 *\/N * * *)<br>
    * 3 – раз в сутки (M H * * *)<br>
    * 4 – раз в неделю (M H * * D)<br>
    * 5 – раз в месяц (M H D * *)<br>
    * 6 – раз в год (M H D M *)<br>
    *
    * @param string $intr Строка crontab
    * @return array Массив настроек с ключами: type, min, hour, dom, month, dow (при наличии)
    */
    public static function crontab_get_type_and_time($intr)
    {
        $parts=explode(' ', trim($intr));
        // Ожидается 5 полей: мин, час, день месяца, месяц, день недели
        $min=$parts[0];
        $hour=$parts[1];
        $dom=$parts[2];
        $month=$parts[3];
        $dow=$parts[4];

        if (strpos($min, '/') !== false)
        {
            // Каждые X минут
            $interval=trim($min, '*/');
            return array('type'=>0, 'min'=>$interval);
        }
        if ($min != '*' && $hour == '*')
        {
            // Раз в час
            return array('type'=>1, 'min'=>$min);
        }
        if (strpos($hour, '/') !== false)
        {
            // Каждые X часов
            $interval=trim($hour, '*/');
            return array('type'=>2, 'hour'=>$interval);
        }
        // Различаем варианты по оставшимся полям
        if ($dom == '*' && $month == '*' && $dow == '*')
        {
            return array('type'=>3, 'min'=>$min, 'hour'=>$hour);
        }
        elseif ($dom == '*' && $month == '*' && $dow != '*')
        {
            return array('type'=>4, 'min'=>$min, 'hour'=>$hour, 'dow'=>$dow);
        }
        elseif ($dom != '*' && $month == '*' && $dow == '*')
        {
            return array('type'=>5, 'min'=>$min, 'hour'=>$hour, 'dom'=>$dom);
        }
        elseif ($dom != '*' && $month != '*' && $dow == '*')
        {
            return array('type'=>6, 'min'=>$min, 'hour'=>$hour, 'dom'=>$dom, 'month'=>$month);
        }
        else
        {
            return array('type'=>3, 'min'=>$min, 'hour'=>$hour);
        }
    }

    /**
     * Возвращает читаемое расписание на основе строки crontab.
     *
     * @param string $intr Строка crontab
     * @return string Читаемое расписание
     */
    public static function crontab_get_timetable($intr)
    {
        $data=static::crontab_get_type_and_time($intr);
        $hour=isset($data['hour']) ? str_pad($data['hour'], 2, '0', STR_PAD_LEFT) : '00';
        $min=isset($data['min']) ? str_pad($data['min'], 2, '0', STR_PAD_LEFT) : '00';

        switch ($data['type'])
        {
            case 0:
                $timetable=get_case_by_count_1_2_5($min, 'каждую минуту,каждые ' . $min . ' минуты,каждые ' . $min . ' минут') . ' ';
                break;
            case 1:
                $timetable='каждый час, в ' . $min . ' минут';
                break;
            case 2:
                $timetable=get_case_by_count_1_2_5($data['hour'], 'каждый час,каждые ' . $data['hour'] . ' часа,каждые ' . $data['hour'] . ' часов') . ' ';
                break;
            case 3:
                $timetable='раз в сутки, в ' . $hour . ':' . $min;
                break;
            case 4:
                $dow=isset($data['dow']) ? $data['dow'] : '1';
                $timetable='раз в неделю, в ' . $hour . ':' . $min . ', в день недели ' . $dow;
                break;
            case 5:
                $dom=isset($data['dom']) ? $data['dom'] : '1';
                $timetable='раз в месяц, в ' . $hour . ':' . $min . ', ' . $dom . '-е число месяца';
                break;
            case 6:
                $dom=isset($data['dom']) ? $data['dom'] : '1';
                $month=isset($data['month']) ? $data['month'] : '1';
                $timetable='раз в год, в ' . $hour . ':' . $min . ', ' . $dom . '-е число ' . $month . '-го месяца';
                break;
            default:
                $timetable='неопределённое расписание';
                break;
        }
        return $timetable;
    }

    /**
     * Сохраняет новое расписание crontab, учитывая все варианты настроек.
     *
     * @param array $post_data Данные из формы (filter[type_period], filter[hour], filter[min],
     *                         filter[dow], filter[dom], filter[month_day] и filter[id])
     */
    public static function save_cron_time($post_data)
    {
        $type=$post_data['filter']['type_period'];
        $time='';

        switch ($type)
        {
            case 0: // Каждые X минут
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $time='*/' . $min . ' * * * *';
                break;
            case 1: // Раз в час
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $time=$min . ' * * * *';
                break;
            case 2: // Каждые X часов
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $time='0 */' . $hour . ' * * *';
                break;
            case 3: // Раз в сутки
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $time=$min . ' ' . $hour . ' * * *';
                break;
            case 4: // Раз в неделю
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $dow=!empty($post_data['filter']['dow']) ? $post_data['filter']['dow'] : '1';
                $time=$min . ' ' . $hour . ' * * ' . $dow;
                break;
            case 5: // Раз в месяц
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $dom=!empty($post_data['filter']['dom']) ? $post_data['filter']['dom'] : '1';
                $time=$min . ' ' . $hour . ' ' . $dom . ' * *';
                break;
            case 6: // Раз в год
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                if (!empty($post_data['filter']['month_day']))
                {
                    list($month, $dom)=explode('-', $post_data['filter']['month_day']);
                }
                else
                {
                    $month='1';
                    $dom='1';
                }
                $time=$min . ' ' . $hour . ' ' . $dom . ' ' . $month . ' *';
                break;
            default:
                $hour=!empty($post_data['filter']['hour']) ? $post_data['filter']['hour'] : '0';
                $min=!empty($post_data['filter']['min']) ? $post_data['filter']['min'] : '0';
                $time=$min . ' ' . $hour . ' * * *';
                break;
        }

        $intr=execSQL_van('SELECT intr, default_intr FROM ' . TM_CRONTAB . ' WHERE pkey=' . $post_data['filter']['id']);

        if ($intr['default_intr'])
        {
            $old_data=static::crontab_get_type_and_time($intr['default_intr']);
        }
        else
        {
            $old_data=static::crontab_get_type_and_time($intr['intr']);
        }

        // Формируем массив новых данных для проверки
        $new_data=array('type'=>$type);
        if ($type == 0 || $type == 1)
        {
            $new_data['min']=$post_data['filter']['min'];
        }
        elseif ($type == 2)
        {
            $new_data['hour']=$post_data['filter']['hour'];
        }
        elseif ($type == 3)
        {
            $new_data['hour']=$post_data['filter']['hour'];
            $new_data['min']=$post_data['filter']['min'];
        }
        elseif ($type == 4)
        {
            $new_data['hour']=$post_data['filter']['hour'];
            $new_data['min']=$post_data['filter']['min'];
            $new_data['dow']=$post_data['filter']['dow'];
        }
        elseif ($type == 5)
        {
            $new_data['hour']=$post_data['filter']['hour'];
            $new_data['min']=$post_data['filter']['min'];
            $new_data['dom']=$post_data['filter']['dom'];
        }
        elseif ($type == 6)
        {
            $new_data['hour']=$post_data['filter']['hour'];
            $new_data['min']=$post_data['filter']['min'];
            if (!empty($post_data['filter']['month_day']))
            {
                list($new_data['month'], $new_data['dom'])=explode('-', $post_data['filter']['month_day']);
            }
        }

        $correct_cron=static::checking_for_correct_cron($old_data, $new_data);

        if (!$correct_cron)
        {
            echo '<div class="red">Частота запуска задания не должна превышать заданное по умолчанию значение. Частый запуск может привести к падению сервера.</div>';
        }
        if ($intr['intr'] == $time)
        {
            echo '<div class="green">Изменений не обнаружено</div>';
        }
        else
        {
            $new_intr=[];
            if (!$intr['default_intr'])
            {
                $new_intr['default_intr']=$intr['intr'];
            }
            else if ($intr['default_intr'] == $time)
            {
                $new_intr['default_intr']='';
            }
            $new_intr['intr']=$time;
            $result=update_rec_in_table(TM_CRONTAB, $new_intr, 'pkey=' . $post_data['filter']['id']);
            if (!$result['found'])
            {
                echo '<div class="red">Не удалось изменить данные по крону</div>';
            }
            else if ($result['update'])
            {
                echo '<div class="green">Данные изменены</div>';
            }
        }
    }

    /**
     * Проверяет, что новое расписание не запускается чаще, чем рекомендовано.
     *
     * @param array $old_data Старые настройки (из default_intr или intr)
     * @param array $new_data Новые настройки из формы
     * @return bool True, если новое расписание корректно; false в противном случае.
     */
    public static function checking_for_correct_cron($old_data, $new_data)
    {
        if ($new_data['type'] < $old_data['type'])
        {
            return false;
        }
        else if ($new_data['type'] == $old_data['type'])
        {
            // Для вариантов с интервалами (0 и 2) проверяем, что интервал не уменьшился
            if ($new_data['type'] == 0 && $old_data['min'] > $new_data['min']) return false;
            if ($new_data['type'] == 2 && $old_data['hour'] > $new_data['hour']) return false;
        }
        return true;
    }
}
