Completed
Branch BUG-10923-reg-form-question-cs... (bf89a7)
by
unknown
66:43 queued 55:42
created

CachingLoader::getIdentifierForArgument()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 5
nop 1
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\services\loaders;
4
5
use Closure;
6
use EventEspresso\core\exceptions\InvalidDataTypeException;
7
use EventEspresso\core\services\collections\CollectionInterface;
8
9
defined('EVENT_ESPRESSO_VERSION') || exit;
10
11
12
13
/**
14
 * Class CachingLoader
15
 * caches objects returned by the decorated loader
16
 *
17
 * @package       Event Espresso
18
 * @author        Brent Christensen
19
 * @since         $VID:$
20
 */
21
class CachingLoader extends LoaderDecorator
22
{
23
24
    /**
25
     * @var CollectionInterface $cache
26
     */
27
    protected $cache;
28
29
    /**
30
     * @var string $identifier
31
     */
32
    protected $identifier;
33
34
35
36
    /**
37
     * CachingLoader constructor.
38
     *
39
     * @param LoaderDecoratorInterface $loader
40
     * @param CollectionInterface      $cache
41
     * @param string                   $identifier
42
     * @throws InvalidDataTypeException
43
     */
44
    public function __construct(LoaderDecoratorInterface $loader, CollectionInterface $cache, $identifier = '')
45
    {
46
        parent::__construct($loader);
47
        $this->cache = $cache;
48
        $this->setIdentifier($identifier);
49
        if ($this->identifier !== '') {
50
            // to only clear this cache, and assuming an identifier has been set, simply do the following:
51
            // do_action('AHEE__EventEspresso\core\services\loaders\CachingLoader__resetCache__IDENTIFIER');
52
            // where "IDENTIFIER" = the string that was set during construction
53
            add_action(
54
                "AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache__{$identifier}",
55
                array($this, 'reset')
56
            );
57
        }
58
        // to clear ALL caches, simply do the following:
59
        // do_action('AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache');
60
        add_action(
61
            'AHEE__EventEspresso_core_services_loaders_CachingLoader__resetCache',
62
            array($this, 'reset')
63
        );
64
    }
65
66
67
68
    /**
69
     * @return string
70
     */
71
    public function identifier()
72
    {
73
        return $this->identifier;
74
    }
75
76
77
78
    /**
79
     * @param string $identifier
80
     * @throws InvalidDataTypeException
81
     */
82
    private function setIdentifier($identifier)
83
    {
84
        if ( ! is_string($identifier)) {
85
            throw new InvalidDataTypeException('$identifier', $identifier, 'string');
86
        }
87
        $this->identifier = $identifier;
88
    }
89
90
91
92
    /**
93
     * @param string $fqcn
94
     * @param array  $arguments
95
     * @param bool   $shared
96
     * @return mixed
97
     */
98
    public function load($fqcn, $arguments = array(), $shared = true)
99
    {
100
        $fqcn = ltrim($fqcn, '\\');
101
        // caching can be turned off via the following code:
102
        // add_filter('FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache', '__return_true');
103
        if(
104
            apply_filters(
105
                'FHEE__EventEspresso_core_services_loaders_CachingLoader__load__bypass_cache',
106
                false,
107
                $this
108
            )
109
        ){
110
            // even though $shared might be true, caching should be bypassed for whatever reason,
111
            // so we don't want the core loader to cache anything, therefore caching is turned off
112
            return $this->loader->load($fqcn, $arguments, false);
113
        }
114
        $identifier = md5($fqcn . $this->getIdentifierForArgument($arguments));
115
        if($this->cache->has($identifier)){
116
            return $this->cache->get($identifier);
117
        }
118
        $object = $this->loader->load($fqcn, $arguments, $shared);
119
        if($object instanceof $fqcn){
120
            $this->cache->add($object, $identifier);
121
        }
122
        return $object;
123
    }
124
125
126
127
    /**
128
     * empties cache and calls reset() on loader if method exists
129
     */
130
    public function reset()
131
    {
132
        $this->cache->trashAndDetachAll();
133
        $this->loader->reset();
134
    }
135
136
137
138
    /**
139
     * build a string representation of a class' arguments
140
     * (mostly because Closures can't be serialized)
141
     *
142
     * @param array $arguments
143
     * @return string
144
     */
145
    private function getIdentifierForArgument(array $arguments)
146
    {
147
        $identifier = '';
148
        foreach ($arguments as $argument) {
149
            switch (true) {
150
                case is_object($argument) :
151
                case $argument instanceof Closure :
152
                    $identifier .= spl_object_hash($argument);
153
                    break;
154
                case is_array($argument) :
155
                    $identifier .= $this->getIdentifierForArgument($argument);
156
                    break;
157
                default :
158
                    $identifier .= $argument;
159
                    break;
160
            }
161
        }
162
        return $identifier;
163
    }
164
165
166
}
167
// End of file CachingLoader.php
168
// Location: EventEspresso\core\services\loaders/CachingLoader.php
169