Passed
Push — main ( 220b50...55f6d1 )
by Daryl
03:00
created

Performances   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Test Coverage

Coverage 84.21%

Importance

Changes 8
Bugs 0 Features 1
Metric Value
wmc 14
eloc 51
c 8
b 0
f 1
dl 0
loc 135
ccs 48
cts 57
cp 0.8421
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getPerformancesBetween() 0 23 4
A getUpcomingPerformances() 0 9 2
A search() 0 19 3
A getPerformancesForProductionSeason() 0 4 1
A __construct() 0 4 1
A makeNewZoneAvailability() 0 14 1
A getPerformanceZoneAvailabilities() 0 10 2
1
<?php
2
3
namespace Clubdeuce\Tessitura\Resources;
4
5
use Clubdeuce\Tessitura\Base\Base;
6
use Clubdeuce\Tessitura\Interfaces\ApiInterface;
7
use Clubdeuce\Tessitura\Interfaces\ResourceInterface;
8
use DateTime;
9
use Exception;
10
use Throwable;
11
12
/**
13
 * Class to interact with performance data from a backend API.
14
 */
15
class Performances extends Base implements ResourceInterface
16
{
17
    public const RESOURCE = 'TXN/Performances';
18
    protected ApiInterface $_api;
19
20 8
    public function __construct(ApiInterface $api)
21
    {
22 8
        $this->_api = $api;
23 8
        parent::__construct();
24
    }
25
26
    /**
27
     * Get upcoming performances
28
     *
29
     * @param int $days Number of days to look ahead for performances. Defaults to thirty days.
30
     * @return Performance[]
31
     * @throws Exception
32
     */
33
    public function getUpcomingPerformances(int $days = 30): array
34
    {
35
        try {
36
            $start = new DateTime();
37
            $end   = new DateTime("now + {$days} days");
38
39
            return $this->getPerformancesBetween($start, $end);
40
        } catch (Throwable $e) {
41
            throw new Exception("Unable to get upcoming performances: " . $e->getMessage());
42
        }
43
    }
44
45
    /**
46
     * Get performances between two dates.
47
     *
48
     * @param DateTime $start
49
     * @param DateTime $end
50
     * @return Performance[]
51
     */
52 1
    public function getPerformancesBetween(DateTime $start, DateTime $end): array
53
    {
54 1
        $sorted       = [];
55 1
        $performances = $this->search([
56 1
            'PerformanceStartDate' => $start->format(DATE_ATOM),
57 1
            'PerformanceEndDate'   => $end->format(DATE_ATOM),
58 1
        ]);
59
60 1
        foreach ($performances as $performance) {
61
            try {
62 1
                $date = $performance->date();
63 1
                if (!is_null($date)) {
64 1
                    $sorted[$date->getTimestamp()] = $performance;
65
                }
66
            } catch (Throwable $e) {
67
                // Skip performances with invalid dates rather than stopping the entire operation
68
                continue;
69
            }
70
        }
71
72 1
        ksort($sorted);
73
74 1
        return $sorted;
75
    }
76
77
    /**
78
     * @param int $psId
79
     * @return Performance[]
80
     */
81 2
    public function getPerformancesForProductionSeason(int $psId): array
82
    {
83 2
        return $this->search([
84 2
            'ProductionSeasonIds' => (string)$psId,
85 2
        ]);
86
    }
87
88
    /**
89
     * @param  mixed[] $args
90
     * @return Performance[]
91
     */
92 5
    public function search(array $args = []): array
93
    {
94 5
        $endpoint = sprintf('%1$s/Search', self::RESOURCE);
95 5
        $body     = json_encode($args);
96
97 5
        $args = [
98 5
            'body'    => $body,
99 5
            'headers' => [
100 5
                'Content-Length' => $body ? strlen($body) : 0,
101 5
            ],
102 5
        ];
103
104 5
        $results = $this->_api->post($endpoint, $args);
105
106 5
        if (!is_array($results)) {
107
            return [];
108
        }
109
110 5
        return array_map(fn ($item) => new Performance($item), $results);
111
    }
112
113
    /**
114
     * @param int $performanceId
115
     * @return PerformanceZoneAvailability[]
116
     */
117 2
    public function getPerformanceZoneAvailabilities(int $performanceId): array
118
    {
119
        try {
120 2
            $data = $this->_api->get(sprintf('%1$s/Zones?performanceIds=%2$s', self::RESOURCE, $performanceId));
121
122 1
            return array_map([$this, 'makeNewZoneAvailability'], $data);
123 1
        } catch (Exception $e) {
124
            //trigger_error("Exception in getPerformanceZoneAvailabilities: " . $e->getMessage());
125
126 1
            return [];
127
        }
128
    }
129
130
    /**
131
     * Create a new PerformanceZoneAvailability instance from the provided data.
132
     *
133
     * @param mixed[] $data
134
     * @return PerformanceZoneAvailability
135
     */
136 2
    protected function makeNewZoneAvailability(array $data): PerformanceZoneAvailability
137
    {
138 2
        $data = $this->parseArgs($data, [
139 2
            'AvailableCount'   => 0,
140 2
            'Id'               => 0,
141 2
            'Inactive'         => false,
142 2
            'PerformanceId'    => 0,
143 2
            'SectionSummaries' => null,
144 2
            'Zone'             => null,
145 2
        ]);
146
147 2
        return new PerformanceZoneAvailability([
148 2
            'availableCount' => $data['AvailableCount'],
149 2
            'zone'           => $data['Zone'],
150 2
        ]);
151
    }
152
}
153