RRule\RRule::parseRfcString PHP Method

parseRfcString() public static method

Take a RFC 5545 string and returns an array (to be given to the constructor)
public static parseRfcString ( string $string ) : array
$string string The rule to be parsed
return array
    public static function parseRfcString($string)
    {
        $parts = array();
        $string = trim($string);
        $dtstart_type = 'date';
        $rfc_date_regexp = '/\\d{6}(T\\d{6})?Z?/';
        // a bit loose
        foreach (explode("\n", $string) as $line) {
            $line = trim($line);
            if (strpos($line, ':') === false) {
                $property_name = 'RRULE';
                $property_value = $line;
            } else {
                list($property_name, $property_value) = explode(':', $line);
            }
            $tmp = explode(';', $property_name);
            $property_name = $tmp[0];
            $property_params = array();
            array_splice($tmp, 0, 1);
            foreach ($tmp as $pair) {
                if (strpos($pair, '=') === false) {
                    throw new \InvalidArgumentException('Failed to parse RFC string, invalid property parameters: ' . $pair);
                }
                list($key, $value) = explode('=', $pair);
                $property_params[$key] = $value;
            }
            switch ($property_name) {
                case 'DTSTART':
                    $tmp = null;
                    if (!preg_match($rfc_date_regexp, $property_value)) {
                        throw new \InvalidArgumentException('Invalid DTSTART property: date or date time format incorrect');
                    }
                    if (isset($property_params['TZID'])) {
                        // TZID must only be specified if this is a date-time (see section 3.3.4 & 3.3.5 of RFC 5545)
                        if (strpos($property_value, 'T') === false) {
                            throw new \InvalidArgumentException('Invalid DTSTART property: TZID should not be specified if there is no time component');
                        }
                        // The "TZID" property parameter MUST NOT be applied to DATE-TIME
                        // properties whose time values are specified in UTC.
                        if (strpos($property_value, 'Z') !== false) {
                            throw new \InvalidArgumentException('Invalid DTSTART property: TZID must not be applied when time is specified in UTC');
                        }
                        $dtstart_type = 'tzid';
                        $tmp = new \DateTimeZone($property_params['TZID']);
                    } elseif (strpos($property_value, 'T') !== false) {
                        if (strpos($property_value, 'Z') === false) {
                            $dtstart_type = 'localtime';
                            // no timezone
                        } else {
                            $dtstart_type = 'utc';
                        }
                    }
                    $parts['DTSTART'] = new \DateTime($property_value, $tmp);
                    break;
                case 'RRULE':
                    foreach (explode(';', $property_value) as $pair) {
                        $pair = explode('=', $pair);
                        if (!isset($pair[1]) || isset($pair[2])) {
                            throw new \InvalidArgumentException("Failed to parse RFC string, malformed RRULE property: {$property_value}");
                        }
                        list($key, $value) = $pair;
                        if ($key === 'UNTIL') {
                            if (!preg_match($rfc_date_regexp, $value)) {
                                throw new \InvalidArgumentException('Invalid DTSTART property: date or date time format incorrect');
                            }
                            switch ($dtstart_type) {
                                case 'date':
                                    if (strpos($value, 'T') !== false) {
                                        throw new \InvalidArgumentException('Invalid UNTIL property: The value of the UNTIL rule part MUST be a date if DTSTART is a date.');
                                    }
                                    break;
                                case 'localtime':
                                    if (strpos($value, 'T') === false || strpos($value, 'Z') !== false) {
                                        throw new \InvalidArgumentException('Invalid UNTIL property: if the "DTSTART" property is specified as a date with local time, then the UNTIL rule part MUST also be specified as a date with local time');
                                    }
                                    break;
                                case 'tzid':
                                case 'utc':
                                    if (strpos($value, 'T') === false || strpos($value, 'Z') === false) {
                                        throw new \InvalidArgumentException('Invalid UNTIL property: if the "DTSTART" property is specified as a date with UTC time or a date with local time and time zone reference, then the UNTIL rule part MUST be specified as a date with UTC time.');
                                    }
                                    break;
                            }
                            $value = new \DateTime($value);
                        }
                        $parts[$key] = $value;
                    }
                    break;
                default:
                    throw new \InvalidArgumentException('Failed to parse RFC string, unsupported property: ' . $property_name);
            }
        }
        return $parts;
    }