Completed
Branch BUG-10381-asset-loading (189bf4)
by
unknown
13:54
created

EspressoShortcode::sanitizeAttributes()   C

Complexity

Conditions 11
Paths 17

Size

Total Lines 38
Code Lines 28

Duplication

Lines 33
Ratio 86.84 %

Importance

Changes 0
Metric Value
cc 11
eloc 28
nc 17
nop 1
dl 33
loc 38
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 EventEspresso\core\domain\EnqueueAssetsInterface;
5
6
defined('EVENT_ESPRESSO_VERSION') || exit;
7
8
9
10
/**
11
 * Class EspressoShortcode
12
 * base class for all EE shortcode classes
13
 *
14
 * @package       Event Espresso
15
 * @author        Brent Christensen
16
 * @since         $VID:$
17
 */
18
abstract class EspressoShortcode implements ShortcodeInterface
19
{
20
21
    /**
22
     * transient prefix
23
     *
24
     * @type string
25
     */
26
    const CACHE_TRANSIENT_PREFIX = 'ee_sc_';
27
28
29
30
    /**
31
     * enqueues scripts then processes the shortcode
32
     *
33
     * @param array $attributes
34
     * @return string
35
     * @throws \EE_Error
36
     */
37
    final public function processShortcodeCallback($attributes = array())
38
    {
39
        if ($this instanceof EnqueueAssetsInterface) {
40
            if (is_admin()) {
41
                $this->enqueueAdminScripts();
0 ignored issues
show
Bug introduced by
The method enqueueAdminScripts() does not seem to exist on object<EventEspresso\cor...odes\EspressoShortcode>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
42
            } else {
43
                $this->enqueueScripts();
0 ignored issues
show
Bug introduced by
The method enqueueScripts() does not seem to exist on object<EventEspresso\cor...odes\EspressoShortcode>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
44
            }
45
        }
46
        return $this->shortcodeContent(
47
            $this->sanitizeAttributes((array)$attributes)
48
        );
49
    }
50
51
52
53
    /**
54
     * If shortcode caching is enabled for the shortcode,
55
     * and cached results exist, then that will be returned
56
     * else new content will be generated.
57
     * If caching is enabled, then the new content will be cached for later.
58
     *
59
     * @param array $attributes
60
     * @return mixed|string
61
     * @throws \EE_Error
62
     */
63
    private function shortcodeContent(array $attributes)
64
    {
65
        $content = '';
66
        $cache_id = '';
67
        // how long should we cache this shortcode's content for? 0 means no caching.
68
        $cache_expiration = absint(
69
            apply_filters(
70
                'FHEE__EventEspresso_core_services_shortcodes_EspressoShortcode__shortcodeContent__cache_expiration',
71
                $this->cacheExpiration(),
72
                $this->getTag(),
73
                $this
74
            )
75
        );
76
        // is caching enabled for this shortcode ?
77
        if ($cache_expiration) {
78
            $cache_id = $this->shortcodeCacheID($attributes);
79
            $content = get_transient($cache_id);
80
        }
81
        // any existing content ?
82
        if (empty($content)) {
83
            // nope! let's generate some new stuff
84
            $content = $this->processShortcode($attributes);
85
            // save the new content if caching is enabled
86
            if ($cache_expiration) {
87
                set_transient($cache_id, $content, $cache_expiration);
88
            }
89
        }
90
        return $content;
91
    }
92
93
94
95
    /**
96
     * @param array $attributes
97
     * @return string
98
     * @throws \EE_Error
99
     */
100
    private function shortcodeCacheID(array $attributes)
101
    {
102
        // try to get EE_Event any way we can
103
        $event = \EEH_Event_View::get_event();
104
        // then get some kind of ID
105
        if ($event instanceof \EE_Event) {
106
            $ID = $event->ID();
107
        } else {
108
            global $post;
109
            $ID = $post->ID;
110
        }
111
        return EspressoShortcode::CACHE_TRANSIENT_PREFIX . $ID . md5(wp_json_encode($attributes));
112
    }
113
114
115
116
    /**
117
     * array for defining custom attribute sanitization callbacks,
118
     * where keys match keys in your attributes array,
119
     * and values represent the sanitization function you wish to be applied to that attribute.
120
     * So for example, if you had an integer attribute named "event_id"
121
     * that you wanted to be sanitized using absint(),
122
     * then you would return the following:
123
     *      array('event_id' => 'absint')
124
     * Entering 'skip_sanitization' for the callback value
125
     * means that no sanitization will be applied
126
     * on the assumption that the attribute
127
     * will be sanitized at some point... right?
128
     * You wouldn't pass around unsanitized attributes would you?
129
     * That would be very Tom Foolery of you!!!
130
     *
131
     * @return array
132
     */
133
    protected function customAttributeSanitizationMap()
134
    {
135
        return array();
136
    }
137
138
139
140
    /**
141
     * Performs basic sanitization on shortcode attributes
142
     * Since incoming attributes from the shortcode usage in the WP editor will all be strings,
143
     * most attributes will by default be sanitized using the sanitize_text_field() function.
144
     * This can be overridden using the customAttributeSanitizationMap() method (see above),
145
     * all other attributes would be sanitized using the defaults in the switch statement below
146
     *
147
     * @param array $attributes
148
     * @return array
149
     */
150
    private function sanitizeAttributes(array $attributes)
151
    {
152
        $custom_sanitization = $this->customAttributeSanitizationMap();
153 View Code Duplication
        foreach ($attributes as $key => $value) {
154
            // is a custom sanitization callback specified ?
155
            if (isset($custom_sanitization[$key])) {
156
                $callback = $custom_sanitization[$key];
157
                if ($callback === 'skip_sanitization') {
158
                    $attributes[$key] = $value;
159
                    continue;
160
                } else if (function_exists($callback)) {
161
                    $attributes[$key] = $callback($value);
162
                    continue;
163
                }
164
            }
165
            switch (true) {
166
                case $value === null :
167
                case is_int($value) :
168
                case is_float($value) :
169
                    // typical booleans
170
                case in_array($value, array(true, 'true', '1', 'on', 'yes', false, 'false', '0', 'off', 'no'), true) :
171
                    $attributes[$key] = $value;
172
                    break;
173
                case is_string($value) :
174
                    $attributes[$key] = sanitize_text_field($value);
175
                    break;
176
                case is_array($value) :
177
                    $attributes[$key] = $this->sanitizeAttributes($value);
178
                    break;
179
                default :
180
                    // only remaining data types are Object and Resource
181
                    // which are not allowed as shortcode attributes
182
                    $attributes[$key] = null;
183
                    break;
184
            }
185
        }
186
        return $attributes;
187
    }
188
189
190
191
}
192
// End of file EspressoShortcode.php
193
// Location: EventEspresso\core\services\shortcodes/EspressoShortcode.php