Passed
Pull Request — master (#29)
by
unknown
01:52
created

DelegatingTicketStore::deleteTicket()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
namespace SimpleSAML\Module\casserver\Cas\Ticket;
4
5
use InvalidArgumentException;
6
use SimpleSAML\Configuration;
7
use SimpleSAML\Logger;
8
use SimpleSAML\Module;
9
10
/**
11
 * Ticket store that delegates to other ticket stores.
12
 * Allows you to use multiple source for redundancy or allows a transition from one source to another.
13
 */
14
class DelegatingTicketStore extends TicketStore
15
{
16
    private $delegateTo = 'all';
17
18
    /**
19
     * @var TicketStore[]
20
     */
21
    private $ticketStores = [];
22
23
    /**
24
     * @var TicketStore
25
     */
26
    private $primaryDelegate;
27
28
    public function __construct(Configuration $casConfig)
29
    {
30
        $config = $casConfig->getConfigItem('ticketstore');
31
        $this->delegateTo = $config->getString('delegateTo', 'all');
32
        /** @var $storeConfig Configuration */
33
        foreach ($config->getArray('ticketStores') as $name => $storeArray) {
34
            // TicketStore expects the store config to be in a specific item
35
            $storeConfig = Configuration::loadFromArray(['ticketstore' => $storeArray]);
36
            $class = $storeConfig->getConfigItem('ticketstore')->getString('class');
37
            $ticketStoreClass = Module::resolveClass($class, 'Cas_Ticket');
38
            try {
39
                $ticketStore = new $ticketStoreClass($storeConfig);
40
                $ticketStores[$name] = $ticketStore;
41
            } catch (\Exception $e) {
42
                Logger::error("Unable to create ticket store '$name'. Error " . $e->getMessage());
43
            }
44
        }
45
        assert(!empty($ticketStores));
46
        $this->ticketStores = $ticketStores;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $ticketStores seems to be defined by a foreach iteration on line 33. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
47
48
        if ($this->delegateTo === 'first') {
49
            $this->primaryDelegate = reset($ticketStores);
50
        } elseif ($this->delegateTo !== 'all') {
51
            if (array_key_exists($this->delegateTo, $ticketStores)) {
52
                $this->primaryDelegate = $ticketStores[$this->delegateTo];
53
            } else {
54
                throw new InvalidArgumentException("No ticket store called '" . $this->delegateTo . "'");
55
            }
56
        }
57
    }
58
59
    /**
60
     * Get the ticket, searching one or all of the delegates
61
     * @param $ticketId string The ticket to find
62
     * @return array|null The ticket or null if none found
63
     * @throws \Exception from any delegate stores ONLY if no delegates worked
64
     */
65
    public function getTicket($ticketId)
66
    {
67
        if ($this->delegateTo === 'all') {
68
            $ticket = null;
69
            $rethrowException = null;
70
            foreach ($this->ticketStores as $name => $store) {
71
                try {
72
                    $ticket = $store->getTicket($ticketId);
73
                    $rethrowException = false; // no need to rethrow, at least one store worked
74
                } catch (\Exception $e) {
75
                    if ($rethrowException === null) {
76
                        $rethrowException = $e;
77
                    }
78
                    Logger::error("Unable to read tickets from '$name'. Trying next store. Error " . $e->getMessage());
79
                }
80
                if ($ticket) {
81
                    return $ticket;
82
                }
83
            }
84
            if ($rethrowException) {
85
                throw $rethrowException;
86
            }
87
            return $ticket;
88
        } else {
89
            return $this->primaryDelegate->getTicket($ticketId);
90
        }
91
    }
92
93
    /**
94
     * @param $ticket
95
     * @throws \Exception from any delegate stores ONLY if no delegates worked
96
     */
97
    public function addTicket(array $ticket)
98
    {
99
        if ($this->delegateTo === 'all') {
100
            $rethrowException = null;
101
            foreach ($this->ticketStores as $name => $store) {
102
                try {
103
                    $store->addTicket($ticket);
104
                    $rethrowException = false; // no need to rethrow, at least one store worked
105
                } catch (\Exception $e) {
106
                    if ($rethrowException === null) {
107
                        $rethrowException = $e;
108
                    }
109
                    Logger::error("Unable to add ticket to '$name'. Continue to next store. Error" . $e->getMessage());
110
                }
111
            }
112
            if ($rethrowException) {
113
                throw $rethrowException;
114
            }
115
        } else {
116
            $this->primaryDelegate->addTicket($ticket);
117
        }
118
    }
119
120
    /**
121
     * @param $ticketId string
122
     */
123
    public function deleteTicket($ticketId)
124
    {
125
        if ($this->delegateTo === 'all') {
126
            foreach ($this->ticketStores as $name => $store) {
127
                try {
128
                    $store->deleteTicket($ticketId);
129
                } catch (\Exception $e) {
130
                    Logger::error("Unable to delete ticket from '$name'. Trying next store. Error" . $e->getMessage());
131
                }
132
            }
133
        } else {
134
            $this->primaryDelegate->deleteTicket($ticketId);
135
        }
136
    }
137
}
138