Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
DateManipulator
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getIntervalIdentifier
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 getSteps
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace ContentTranslation;
4
5use Wikimedia\Timestamp\ConvertibleTimestamp;
6
7/**
8 * @author Niklas Laxström
9 */
10class DateManipulator {
11    public const WEEK = 'week';
12    public const MONTH = 'month';
13
14    /** @var string */
15    private $interval;
16
17    public function __construct( $interval ) {
18        if ( $interval === self::WEEK || $interval === self::MONTH ) {
19            $this->interval = $interval;
20        } else {
21            throw new \InvalidArgumentException( 'Invalid interval' );
22        }
23    }
24
25    /**
26     * @param int|string|\DateTime $timestamp
27     * @return \DateTime
28     */
29    public function getIntervalIdentifier( $timestamp ) {
30        $unix = ConvertibleTimestamp::convert( TS_UNIX, $timestamp );
31
32        // UTC timezone is forced for unix timestamps
33        $datetime = new \DateTime( "@$unix" );
34        $datetime->setTime( 0, 0, 0 );
35
36        if ( $this->interval === self::WEEK ) {
37            // We use Sundays to indicate a given week from Monday to Sunday.
38            // Take the current day of the week (0 (for Sunday) through 6 (for Saturday))
39            $dow = (int)$datetime->format( 'w' );
40            if ( $dow > 0 ) {
41                $n = 7 - $dow;
42                $datetime->modify( "+$n days" );
43            }
44        } elseif ( $this->interval === self::MONTH ) {
45            // Use the first day of the month to identify a month
46            $n = (int)$datetime->format( 'j' ) - 1;
47            $datetime->modify( "-$n days" );
48        }
49
50        return $datetime;
51    }
52
53    public function getSteps( \DateTime $min, \DateTime $max ) {
54        // Avoid modifying passed objects
55        $current = clone $min;
56        $interval = new \DateInterval( 'P1D' );
57
58        $steps = [];
59        do {
60            $id = $this->getIntervalIdentifier( $current );
61            $steps[ $id->format( 'Y-m-d' ) ] = $id;
62            $current->add( $interval );
63        } while ( $current <= $max );
64
65        return $steps;
66    }
67}