Completed
Branch FET-10486-add-timestamp-checki... (611b15)
by
unknown
136:24 queued 121:17
created

EspressoShortcode::sanitizeAttributes()   C

Complexity

Conditions 11
Paths 17

Size

Total Lines 39
Code Lines 28

Duplication

Lines 34
Ratio 87.18 %

Importance

Changes 0
Metric Value
cc 11
eloc 28
nc 17
nop 1
dl 34
loc 39
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace EventEspresso\core\services\shortcodes;
3
4
use EEH_Event_View;
5
use EventEspresso\core\domain\EnqueueAssetsInterface;
6
use EventEspresso\core\services\cache\PostRelatedCacheManager;
7
8
defined('EVENT_ESPRESSO_VERSION') || exit;
9
10
11
12
/**
13
 * Class EspressoShortcode
14
 * base class for all EE shortcode classes
15
 *
16
 * @package       Event Espresso
17
 * @author        Brent Christensen
18
 * @since         $VID:$
19
 */
20
abstract class EspressoShortcode implements ShortcodeInterface
21
{
22
23
    /**
24
     * transient prefix
25
     *
26
     * @type string
27
     */
28
    const CACHE_TRANSIENT_PREFIX = 'ee_sc_';
29
30
    /**
31
     * @var PostRelatedCacheManager $cache_manager
32
     */
33
    private $cache_manager;
34
35
36
37
    /**
38
     * EspressoShortcode constructor
39
     *
40
     * @param PostRelatedCacheManager $cache_manager
41
     */
42
    public function __construct(PostRelatedCacheManager $cache_manager)
43
    {
44
        $this->cache_manager = $cache_manager;
45
    }
46
47
48
49
    /**
50
     * enqueues scripts then processes the shortcode
51
     *
52
     * @param array $attributes
53
     * @return string
54
     * @throws \EE_Error
55
     */
56
    final public function processShortcodeCallback($attributes = array())
57
    {
58
        if ($this instanceof EnqueueAssetsInterface) {
59
            if (is_admin()) {
60
                $this->enqueueAdminScripts();
61
            } else {
62
                $this->enqueueScripts();
63
            }
64
        }
65
        return $this->shortcodeContent(
66
            $this->sanitizeAttributes((array)$attributes)
67
        );
68
    }
69
70
71
72
    /**
73
     * If shortcode caching is enabled for the shortcode,
74
     * and cached results exist, then that will be returned
75
     * else new content will be generated.
76
     * If caching is enabled, then the new content will be cached for later.
77
     *
78
     * @param array $attributes
79
     * @return mixed|string
80
     * @throws \EE_Error
81
     */
82
    private function shortcodeContent(array $attributes)
83
    {
84
        $shortcode = $this;
85
        $post_ID = $this->currentPostID();
86
        // something like "SC_EVENTS-123"
87
        $cache_ID = $this->shortcodeCacheID($post_ID);
88
        $this->cache_manager->clearPostRelatedCacheOnUpdate($post_ID, $cache_ID);
89
        return $this->cache_manager->get(
90
            $cache_ID,
91
            // serialized attributes
92
            wp_json_encode($attributes),
93
            // Closure for generating content if cache is expired
94
            function () use ($shortcode, $attributes) {
95
                return $shortcode->processShortcode($attributes);
96
            },
97
            // filterable cache expiration set by each shortcode
98
            apply_filters(
99
                'FHEE__EventEspresso_core_services_shortcodes_EspressoShortcode__shortcodeContent__cache_expiration',
100
                $this->cacheExpiration(),
101
                $this->getTag(),
102
                $this
103
            )
104
        );
105
    }
106
107
108
109
    /**
110
     * @return int
111
     * @throws \EE_Error
112
     */
113
    private function currentPostID()
114
    {
115
        // try to get EE_Event any way we can
116
        $event = EEH_Event_View::get_event();
117
        // then get some kind of ID
118
        if ($event instanceof \EE_Event) {
119
            $post_ID = $event->ID();
120
        } else {
121
            global $post;
122
            $post_ID = $post->ID;
123
        }
124
        return $post_ID;
125
    }
126
127
128
129
    /**
130
     * @param int $post_ID
131
     * @return string
132
     * @throws \EE_Error
133
     */
134
    private function shortcodeCacheID($post_ID)
135
    {
136
        $tag = str_replace('ESPRESSO_', '', $this->getTag());
137
        return "SC_{$tag}-{$post_ID}";
138
    }
139
140
141
142
    /**
143
     * array for defining custom attribute sanitization callbacks,
144
     * where keys match keys in your attributes array,
145
     * and values represent the sanitization function you wish to be applied to that attribute.
146
     * So for example, if you had an integer attribute named "event_id"
147
     * that you wanted to be sanitized using absint(),
148
     * then you would return the following:
149
     *      array('event_id' => 'absint')
150
     * Entering 'skip_sanitization' for the callback value
151
     * means that no sanitization will be applied
152
     * on the assumption that the attribute
153
     * will be sanitized at some point... right?
154
     * You wouldn't pass around unsanitized attributes would you?
155
     * That would be very Tom Foolery of you!!!
156
     *
157
     * @return array
158
     */
159
    protected function customAttributeSanitizationMap()
160
    {
161
        return array();
162
    }
163
164
165
166
    /**
167
     * Performs basic sanitization on shortcode attributes
168
     * Since incoming attributes from the shortcode usage in the WP editor will all be strings,
169
     * most attributes will by default be sanitized using the sanitize_text_field() function.
170
     * This can be overridden using the customAttributeSanitizationMap() method (see above),
171
     * all other attributes would be sanitized using the defaults in the switch statement below
172
     *
173
     * @param array $attributes
174
     * @return array
175
     */
176
    private function sanitizeAttributes(array $attributes)
177
    {
178
        $custom_sanitization = $this->customAttributeSanitizationMap();
179 View Code Duplication
        foreach ($attributes as $key => $value) {
180
            // is a custom sanitization callback specified ?
181
            if (isset($custom_sanitization[$key])) {
182
                $callback = $custom_sanitization[$key];
183
                if ($callback === 'skip_sanitization') {
184
                    $attributes[$key] = $value;
185
                    continue;
186
                }
187
                if (function_exists($callback)) {
188
                    $attributes[$key] = $callback($value);
189
                    continue;
190
                }
191
            }
192
            switch (true) {
193
                case $value === null :
194
                case is_int($value) :
195
                case is_float($value) :
196
                    // typical booleans
197
                case in_array($value, array(true, 'true', '1', 'on', 'yes', false, 'false', '0', 'off', 'no'), true) :
198
                    $attributes[$key] = $value;
199
                    break;
200
                case is_string($value) :
201
                    $attributes[$key] = sanitize_text_field($value);
202
                    break;
203
                case is_array($value) :
204
                    $attributes[$key] = $this->sanitizeAttributes($value);
205
                    break;
206
                default :
207
                    // only remaining data types are Object and Resource
208
                    // which are not allowed as shortcode attributes
209
                    $attributes[$key] = null;
210
                    break;
211
            }
212
        }
213
        return $attributes;
214
    }
215
216
217
218
}
219
// End of file EspressoShortcode.php
220
// Location: EventEspresso\core\services\shortcodes/EspressoShortcode.php