timegridio/concierge

View on GitHub
src/Vacancy/VacancyParser.php

Summary

Maintainability
A
25 mins
Test Coverage
<?php

namespace Timegridio\Concierge\Vacancy;

class VacancyParser
{
    const REGEX_PATTERN_VACANCY = '/(?P<services>.*)\n\ (?P<days>.*)\n\ \ (?<hours>.*)/im';

    /////////////////////
    // VACANCY PARSING //
    /////////////////////

    public function readVacancies($vacancyString)
    {
        preg_match_all(self::REGEX_PATTERN_VACANCY, $vacancyString, $matches, PREG_SET_ORDER);

        return $matches;
    }

    public function buildVacancies(array $vacancyParameters)
    {
        $services = $this->services($vacancyParameters['services']);
        $days = $this->dates($vacancyParameters['days']);
        $hourRanges = $this->hours($vacancyParameters['hours']);

        $builtVacancies = [];
        foreach ($services as $service) {
            foreach ($days as $day) {
                foreach ($hourRanges as $hourRange) {
                    $data = [
                        'service'  => $service['slug'],
                        'date'     => $day,
                        'startAt'  => $hourRange['startAt'],
                        'finishAt' => $hourRange['finishAt'],
                        'capacity' => $service['capacity'],
                    ];
                    // Avoid repeated sets
                    $key = md5(implode('.', $data));
                    $builtVacancies[$key] = $data;
                }
            }
        }

        return $builtVacancies;
    }

    public function parseStatements($stringStatements)
    {
        $vacancyStatements = $this->readVacancies($stringStatements);

        $builtVacancies = [];
        foreach ($vacancyStatements as $vacancyStatement) {
            $builtVacancies = array_merge($builtVacancies, $this->buildVacancies($vacancyStatement));
        }

        return $builtVacancies;
    }

    /////////////////////
    // SERVICE PARSING //
    /////////////////////

    public function services($services)
    {
        $services = $this->splitServices($services);

        return $this->getServicesCapacity($services);
    }

    public function splitServices($services)
    {
        return preg_split('/\ *\,\ */', $services);
    }

    public function getServicesCapacity(array $services)
    {
        $converted = [];
        foreach ($services as $service) {
            $converted[] = $this->getServiceCapacity($service);
        }

        return $converted;
    }

    public function getServiceCapacity($service)
    {
        $capacity = 1;
        if (strpos($service, ':') !== false) {
            list($service, $capacity) = explode(':', $service);
        }

        return ['slug' => $service, 'capacity' => trim($capacity)];
    }

    //////////////////
    // DATE PARSING //
    //////////////////

    public function dates($days)
    {
        $days = $this->splitDates($days);

        return $this->convertDaysToDate($days);
    }

    public function splitDates($days)
    {
        return preg_split('/\ *\,\ */', $days);
    }

    public function convertDaysToDate(array $days)
    {
        $converted = [];
        foreach ($days as $day) {
            $converted[] = $this->dayToDate($day);
        }

        return $converted;
    }

    public function dayToDate($day)
    {
        return date('Y-m-d', strtotime($day));
    }

    //////////////////
    // TIME PARSING //
    //////////////////

    public function hours($string)
    {
        $ranges = $this->splitRanges($string);

        return $this->normalizeRanges($ranges);
    }

    public function normalizeRanges($ranges)
    {
        $normalizedRanges = [];

        foreach ($ranges as $range) {
            list($startAt, $finishAt) = preg_split('/\ *\-\ */', $range);
            $normalizedRanges[] = [
                'startAt'  => $this->milTimeToStandard($startAt),
                'finishAt' => $this->milTimeToStandard($finishAt),
            ];
        }

        return $normalizedRanges;
    }

    public function splitRanges($string)
    {
        return preg_split('/,\ */', $string);
    }

    public function milTimeToStandard($militaryTime)
    {
        $militaryTime = trim($militaryTime);

        if ($militaryTime == '') {
            return '';
        }

        if (strpos($militaryTime, ':') !== false) {
            return $militaryTime;
        }

        $parts = [];

        if (strlen($militaryTime) <= 2) {
            $parts[] = intval($militaryTime);
            $parts[] = '00';
        }
        if (strlen($militaryTime) == 3) {
            $parts[0] = substr($militaryTime, 0, 1);
            $parts[1] = substr($militaryTime, 1, 2);
        }
        if (strlen($militaryTime) == 4) {
            $parts[0] = substr($militaryTime, 0, 2);
            $parts[1] = substr($militaryTime, 2, 2);
        }

        return implode(':', $parts);
    }
}