Вход Регистрация
Файл: vendor/dragonmantank/cron-expression/src/Cron/DayOfWeekField.php
Строк: 194
<?php

declare(strict_types=1);

namespace 
Cron;

use 
DateTimeInterface;
use 
InvalidArgumentException;

/**
 * Day of week field.  Allows: * / , - ? L #.
 *
 * Days of the week can be represented as a number 0-7 (0|7 = Sunday)
 * or as a three letter string: SUN, MON, TUE, WED, THU, FRI, SAT.
 *
 * 'L' stands for "last". It allows you to specify constructs such as
 * "the last Friday" of a given month.
 *
 * '#' is allowed for the day-of-week field, and must be followed by a
 * number between one and five. It allows you to specify constructs such as
 * "the second Friday" of a given month.
 */
class DayOfWeekField extends AbstractField
{
    
/**
     * {@inheritdoc}
     */
    
protected $rangeStart 0;

    
/**
     * {@inheritdoc}
     */
    
protected $rangeEnd 7;

    
/**
     * @var array Weekday range
     */
    
protected $nthRange;

    
/**
     * {@inheritdoc}
     */
    
protected $literals = [=> 'MON'=> 'TUE'=> 'WED'=> 'THU'=> 'FRI'=> 'SAT'=> 'SUN'];

    
/**
     * Constructor
     */
    
public function __construct()
    {
        
$this->nthRange range(15);
        
parent::__construct();
    }

    
/**
     * @inheritDoc
     */
    
public function isSatisfiedBy(DateTimeInterface $date$valuebool $invert): bool
    
{
        if (
'?' === $value) {
            return 
true;
        }

        
// Convert text day of the week values to integers
        
$value $this->convertLiterals($value);

        
$currentYear = (int) $date->format('Y');
        
$currentMonth = (int) $date->format('m');
        
$lastDayOfMonth = (int) $date->format('t');

        
// Find out if this is the last specific weekday of the month
        
if ($lPosition strpos($value'L')) {
            
$weekday $this->convertLiterals(substr($value0$lPosition));
            
$weekday %= 7;

            
$daysInMonth = (int) $date->format('t');
            
$remainingDaysInMonth $daysInMonth - (int) $date->format('d');
            return ((
$weekday === (int) $date->format('w')) && ($remainingDaysInMonth 7));
        }

        
// Handle # hash tokens
        
if (strpos($value'#')) {
            [
$weekday$nth] = explode('#'$value);

            if (!
is_numeric($nth)) {
                throw new 
InvalidArgumentException("Hashed weekdays must be numeric, {$nth} given");
            } else {
                
$nth = (int) $nth;
            }

            
// 0 and 7 are both Sunday, however 7 matches date('N') format ISO-8601
            
if ('0' === $weekday) {
                
$weekday 7;
            }

            
$weekday = (int) $this->convertLiterals((string) $weekday);

            
// Validate the hash fields
            
if ($weekday || $weekday 7) {
                throw new 
InvalidArgumentException("Weekday must be a value between 0 and 7. {$weekday} given");
            }

            if (!
in_array($nth$this->nthRangetrue)) {
                throw new 
InvalidArgumentException("There are never more than 5 or less than 1 of a given weekday in a month, {$nth} given");
            }

            
// The current weekday must match the targeted weekday to proceed
            
if ((int) $date->format('N') !== $weekday) {
                return 
false;
            }

            
$tdate = clone $date;
            
$tdate $tdate->setDate($currentYear$currentMonth1);
            
$dayCount 0;
            
$currentDay 1;
            while (
$currentDay $lastDayOfMonth 1) {
                if ((int) 
$tdate->format('N') === $weekday) {
                    if (++
$dayCount >= $nth) {
                        break;
                    }
                }
                
$tdate $tdate->setDate($currentYear$currentMonth, ++$currentDay);
            }

            return (int) 
$date->format('j') === $currentDay;
        }

        
// Handle day of the week values
        
if (false !== strpos($value'-')) {
            
$parts explode('-'$value);
            if (
'7' === $parts[0]) {
                
$parts[0] = 0;
            } elseif (
'0' === $parts[1]) {
                
$parts[1] = 7;
            }
            
$value implode('-'$parts);
        }

        
// Test to see which Sunday to use -- 0 == 7 == Sunday
        
$format in_array(7array_map(function ($value) {
            return (int) 
$value;
        }, 
str_split($value)), true) ? 'N' 'w';
        
$fieldValue = (int) $date->format($format);

        return 
$this->isSatisfied($fieldValue$value);
    }

    
/**
     * @inheritDoc
     */
    
public function increment(DateTimeInterface &$date$invert false$parts null): FieldInterface
    
{
        if (! 
$invert) {
            
$date $date->add(new DateInterval('P1D'));
            
$date $date->setTime(00);
        } else {
            
$date $date->sub(new DateInterval('P1D'));
            
$date $date->setTime(2359);
        }

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     */
    
public function validate(string $value): bool
    
{
        
$basicChecks parent::validate($value);

        if (!
$basicChecks) {
            if (
'?' === $value) {
                return 
true;
            }

            
// Handle the # value
            
if (false !== strpos($value'#')) {
                
$chunks explode('#'$value);
                
$chunks[0] = $this->convertLiterals($chunks[0]);

                if (
parent::validate($chunks[0]) && is_numeric($chunks[1]) && in_array((int) $chunks[1], $this->nthRangetrue)) {
                    return 
true;
                }
            }

            if (
preg_match('/^(.*)L$/'$value$matches)) {
                return 
$this->validate($matches[1]);
            }

            return 
false;
        }

        return 
$basicChecks;
    }
}
Онлайн: 0
Реклама