aboutsummaryrefslogtreecommitdiff
path: root/bridges/DRKBlutspendeBridge.php
blob: 1507589836c8cccd9b05f43bbc6f0dd3ea248797 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php

class DRKBlutspendeBridge extends FeedExpander
{
    const MAINTAINER = 'User123698745';
    const NAME = 'DRK-Blutspende';
    const BASE_URI = 'https://www.drk-blutspende.de';
    const URI = self::BASE_URI;
    const CACHE_TIMEOUT = 60 * 60 * 1; // 1 hour
    const DESCRIPTION = 'German Red Cross (Deutsches Rotes Kreuz) blood donation service feed with more details';
    const CONTEXT_APPOINTMENTS = 'Termine';
    const PARAMETERS = [
        self::CONTEXT_APPOINTMENTS => [
            'term' => [
                'name' => 'PLZ / Ort',
                'required' => true,
                'exampleValue' => '12555',
            ],
            'radius' => [
                'name' => 'Umkreis in km',
                'type' => 'number',
                'exampleValue' => 10,
            ],
            'limit_days' => [
                'name' => 'Limit von Tagen',
                'title' => 'Nur Termine innerhalb der nächsten x Tagen',
                'type' => 'number',
                'exampleValue' => 28,
            ],
            'limit_items' => [
                'name' => 'Limit von Terminen',
                'title' => 'Nicht mehr als x Termine',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 20,
            ]
        ]
    ];

    public function collectData()
    {
        $limitItems = intval($this->getInput('limit_items'));
        $this->collectExpandableDatas(self::buildAppointmentsURI(), $limitItems);
    }

    protected function parseItem(array $item)
    {
        $html = getSimpleHTMLDOM($item['uri']);

        $detailsElement = $html->find('.details', 0);

        $dateElement = $detailsElement->find('.datum', 0);
        $dateLines = self::explodeLines($dateElement->plaintext);

        $addressElement = $detailsElement->find('.adresse', 0);
        $addressLines = self::explodeLines($addressElement->plaintext);

        $infoElement = $detailsElement->find('.angebote > h4 + p', 0);
        $info = $infoElement ? $infoElement->innertext : '';

        $imageElements = $detailsElement->find('.fotos img');

        $item['title'] = $dateLines[0] . ' ' . $dateLines[1] . ' ' . $addressLines[0] . ' - ' . $addressLines[1];

        $item['content'] = <<<HTML
        <p><b>{$dateLines[0]} {$dateLines[1]}</b></p>
        <p>{$addressElement->innertext}</p>
        <p>{$info}</p>
        HTML;

        foreach ($imageElements as $imageElement) {
            $src = $imageElement->getAttribute('src');
            $item['content'] .= <<<HTML
            <p><img src="{$src}"></p>
            HTML;
        }

        $item['description'] = null;

        return $item;
    }

    public function getURI()
    {
        if ($this->queriedContext === self::CONTEXT_APPOINTMENTS) {
            return str_replace('.rss?', '?', self::buildAppointmentsURI());
        }
        return parent::getURI();
    }

    private function buildAppointmentsURI()
    {
        $term = $this->getInput('term') ?? '';
        $radius = $this->getInput('radius') ?? '';
        $limitDays = intval($this->getInput('limit_days'));
        $dateTo = $limitDays > 0 ? date('Y-m-d', time() + (60 * 60 * 24 * $limitDays)) : '';
        return self::BASE_URI . '/blutspendetermine/termine.rss?date_to=' . $dateTo . '&radius=' . $radius . '&term=' . $term;
    }

    /**
     * Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by line breaks.
     */
    private function explodeLines(string $text): array
    {
        return array_map('trim', preg_split('/(\s*(\r\n|\n|\r)\s*)+/', $text));
    }
}