Completed
Push — master ( ef4d2e...9d62e6 )
by Seth
02:42
created

Toolbox::smarty_addMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
3
namespace smtech\StMarksReflexiveCanvasLTI;
4
5
use LTI_Tool_Consumer;
6
use LTI_Data_Connector;
7
8
use Battis\HierarchicalSimpleCache;
9
use Battis\DataUtilities;
10
use Battis\BootstrapSmarty\NotificationMessage;
11
12
use smtech\StMarksSmarty\StMarksSmarty;
13
use smtech\ReflexiveCanvasLTI\Exception\ConfigurationException;
14
15
/**
16
 * Add HTML templating and basic caching to the ReflexiveCanvasLTI Toolbox
17
 *
18
 * @author Seth Battis <[email protected]>
19
 * @version v0.1
20
 */
21
class Toolbox extends \smtech\ReflexiveCanvasLTI\Toolbox
22
{
23
24
    /**
25
     * Cache manager
26
     * @var HierarchicalSimpleCache
27
     */
28
    protected $cache;
29
30
    /**
31
     * St. Mark's-styled HTML templating
32
     * @var StMarksSmarty
33
     */
34
    protected $smarty;
35
36
    /**
37
     * Update a Toolbox instance from a configuration file
38
     *
39
     * Extends the inherited `Toolbox::loadConfiguration()` to add two
40
     * additional pieces of configuration metadata:
41
     *
42
     *   - `APP_PATH` is the path to the Tool Provider app
43
     *   - `APP_URL` is the URL of the Tool Provider app
44
     *
45
     * Also stores the API access token acquired by `interactiveGetAccessToken()`.
46
     *
47
     * @see interactiveGetAccessToken() `interactiveGetAccessToken()`
48
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/smtech/reflexive-canvas-lti/master/doc/classes/smtech.ReflexiveCanvasLTI.Toolbox.html#method_loadConfiguration `smtech\ReflexiveCanvasLTI\Toolbox::loadConfiguration()`
49
     *
50
     * @param string $configFilePath
51
     * @param boolean $forceRecache (Optional, default `false`)
52
     * @return void
53
     */
54
    protected function loadConfiguration($configFilePath, $forceRecache = false)
55
    {
56
        parent::loadConfiguration($configFilePath, $forceRecache);
57
58
        /* patch in passed back API access token, if present */
59
        if (!empty($_SESSION['TOOL_CANVAS_API'])) {
60
            $this->metadata['TOOL_CANVAS_API'] = $_SESSION['TOOL_CANVAS_API'];
61
            unset($_SESSION['TOOL_CANVAS_API']);
62
        }
63
64
        if ($forceRecache || empty($this->config('APP_PATH'))) {
65
            $this->config('APP_PATH', dirname($this->config('TOOL_CONFIG_FILE')));
66
        }
67
68
        if ($forceRecache || empty($this->config('APP_URL'))) {
69
            $this->config('APP_URL', DataUtilities::URLfromPath($this->config('APP_PATH')));
70
        }
71
    }
72
73
    /**
74
     * Interactively acquire an API access token
75
     *
76
     * `/config/canvas/key` and `/config/canvas/secret` must be defined in
77
     * `config.xml` for this to work!
78
     *
79
     * @param string $reason Explanation of why an API access token is necessary
80
     * @param string $redirectURL (Optional, defaults to
81
     *     `$_SERVER['REQUEST_URI']`) URL of page to redirect to after
82
     *     acquiring access token
83
     * @param string $errorURL (Optional) URL of page to redirect to on error
84
     * @return void
85
     */
86
    public function interactiveGetAccessToken($reason = null, $redirectURL = null, $errorURL = null)
87
    {
88
        $redirectURL = (
89
            empty($redirectURL) ?
90
                $_SERVER['REQUEST_URI'] :
91
                $redirectURL
92
        );
93
        $errorURL = (
94
            empty($errorURL) ?
95
                DataUtilities::URLfromPath(__DIR__ . '/../error.php') :
96
                $errorURL
97
        );
98
        $canvas = $this->metadata['TOOL_CANVAS_API'];
99
        if (!empty($canvas['key']) && !empty($canvas['secret'])) {
100
            /* if so, request an API access token interactively */
101
            if (session_status() !== PHP_SESSION_ACTIVE) {
102
                session_start();
103
            }
104
            $_SESSION['oauth'] = [
105
                'purpose' => $this->metadata['TOOL_NAME'],
106
                'key' => $canvas['key'],
107
                'secret' => $canvas['secret']
108
            ];
109
            header(
110
                'Location: ' . DataUtilities::URLfromPath(__DIR__ . '/../oauth.php') .
111
                '?' . http_build_query([
112
                    'oauth-return' => $redirectURL,
113
                    'oauth-error' => $errorURL,
114
                    'reason' => $reason
115
                ])
116
            );
117
            break;
118
        } else { /* no (understandable) API credentials available -- doh! */
119
            throw new ConfigurationException(
120
                'Missing OAuth key/secret pair in configuration, which is ' .
121
                'required to interactively acquire an API access token',
122
                ConfigurationException::CANVAS_API_MISSING
123
            );
124
        }
125
    }
126
127
    /**
128
     * Create a (potentially new) LTI_Tool_Consumer
129
     *
130
     * @param string $key (Optional)
131
     * @return LTI_Tool_Consumer
132
     */
133
    private function interactiveConsumersControlPanel_loadConsumer($key = null)
134
    {
135
        /*
136
         * load an existing consumer (if we have a consumer_key) or create a blank
137
         * that we will fill in
138
         */
139
        $consumer = new LTI_Tool_Consumer(
140
            (empty($key) ? LTI_Data_Connector::getRandomString(32) : $key),
141
            $this->getToolProvider()->data_connector,
142
            true // wicked confusing _not_ to autoenable
143
        );
144
145
        /* pre-fill secret if not editing an existing consumer */
146
        if (empty($key)) {
147
            $consumer->secret = LTI_Data_Connector::getRandomString(32);
148
        }
149
150
        return $consumer;
151
    }
152
153
    /**
154
     * Handle tool consumer management interactively
155
     *
156
     * Display and manage a control panel for managing Tool Consumers
157
     * interactively.
158
     *
159
     * @uses interactiveConsumersControlPanel_loadConsumer() `interactiveConsumersControlPanel_loadConsumer()`
160
     * @return void
161
     */
162
    public function interactiveConsumersControlPanel()
163
    {
164
        /* clean request values */
165
        $name = (empty($_POST['name']) ? null : trim($_POST['name']));
166
        $key = (empty($_POST['key']) ? null : trim($_POST['key']));
167
        $secret = (empty($_POST['secret']) ? null : trim($_POST['secret']));
168
        $enabled = (empty($_POST['enabled']) ? false : (boolean) $_POST['enabled']);
169
        $action = (empty($_POST['action']) ? false : strtolower(trim($_POST['action'])));
170
171
        /* load requested consumer (or create new if none requested) */
172
        $consumer = $this->interactiveConsumersControlPanel_loadConsumer($key);
173
174
        /* what are we asked to do with this consumer? */
175
        switch ($action) {
176
            case 'update':
177
            case 'insert':
178
                $consumer->name = $name;
179
                $consumer->secret = $secret;
180
                $consumer->enabled = $enabled;
181
                if (!$consumer->save()) {
182
                    $this->smarty_addMessage(
183
                        'Error saving consumer',
184
                        'There was an error attempting to save your new or ' .
185
                        'updated consumer information to the database.',
186
                        NotificationMessage::DANGER
187
                    );
188
                }
189
                break;
190
            case 'delete':
191
                $consumer->delete();
192
                break;
193
            case 'select':
194
                $this->smarty_assign('key', $key);
195
                break;
196
        }
197
198
        /*
199
         * if action was anything other than 'select', create a new empty
200
         * consumer to fill the form with
201
         */
202
        if ($action && $action !== 'select') {
203
            $consumer = $this->interactiveConsumersControlPanel_loadConsumer();
204
        }
205
206
        /* display a list of consumers */
207
        $consumers = $this->lti_getConsumers();
208
        $this->smarty_assign([
0 ignored issues
show
Documentation introduced by
array('name' => 'Consume...s->metadata['APP_URL']) is of type array<string,?,{"name":"...ion":"?","appUrl":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
            'name' => 'Consumers',
210
            'category' => 'Control Panel',
211
            'consumers' => $consumers,
212
            'consumer' => $consumer,
213
            'formAction' => $_SERVER['PHP_SELF'],
214
            'appUrl' => $this->metadata['APP_URL']
215
        ]);
216
        $this->smarty_display('consumers-control-panel.tpl');
217
    }
218
219
    /**
220
     * Update the cache manager
221
     *
222
     * @param HierarchicalSimpleCache $cache
223
     */
224
    public function setCache(HierarchicalSimpleCache $cache)
225
    {
226
        $this->cache = $cache;
227
    }
228
229
    /**
230
     * Get the cache manager
231
     *
232
     * @return HierarchicalSimpleCache
233
     */
234
    public function getCache()
235
    {
236
        if (empty($this->cache)) {
237
            $this->cache = new HierarchicalSimpleCache($this->getMySQL(), basename(__FILE__, '.php'));
238
        }
239
        return $this->cache;
240
    }
241
242
    /**
243
     * Push a hierarchical layer to the cache
244
     *
245
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/simplecache/master/doc/classes/Battis.HierarchicalSimpleCache.html#method_pushKey Pass-through to `HierarchicalSimpleCache::pushKey()`
246
     *
247
     * @param  string $layer
248
     * @return string
249
     */
250
    public function cache_pushKey($layer)
251
    {
252
        return $this->getCache()->pushKey($layer);
253
    }
254
255
    /**
256
     * Pop a hierarchical layer off of the cache
257
     *
258
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/simplecache/master/doc/classes/Battis.HierarchicalSimpleCache.html#method_popKey Pass-through to `HierarchicalSimpleCache::popKey()`
259
     *
260
     * @return string|null
261
     */
262
    public function cache_popKey()
263
    {
264
        return $this->getCache()->popKey();
265
    }
266
267
    /**
268
     * Retrieve a cached value
269
     *
270
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/simplecache/master/doc/classes/Battis.HierarchicalSimpleCache.html#method_getCache Pass-through to `HierarchicalSimpleCache::getCache()`
271
     *
272
     * @param string $key
273
     * @return mixed
274
     */
275
    public function cache_get($key)
276
    {
277
        return $this->getCache()->getCache($key);
278
    }
279
280
    /**
281
     * Set a cached value
282
     *
283
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/simplecache/master/doc/classes/Battis.HierarchicalSimpleCache.html#method_setCache Pass-through to `HierarchicalSimpleCache::setCache()`
284
     *
285
     * @param string $key
286
     * @param mixed $data
287
     * @return boolean
288
     */
289
    public function cache_set($key, $data)
290
    {
291
        return $this->getCache()->setCache($key, $data);
292
    }
293
294
    /**
295
     * Update the HTML templating engine
296
     *
297
     * @param StMarksSmarty $smarty
298
     */
299
    public function setSmarty(StMarksSmarty $smarty)
300
    {
301
        $this->smarty = $smarty;
302
    }
303
304
    /**
305
     * Get the HTML templating engine
306
     *
307
     * @return StMarksSmarty
308
     */
309
    public function getSmarty()
310
    {
311
        if (empty($this->smarty)) {
312
            $this->smarty = StMarksSmarty::getSmarty();
313
            $this->smarty->setFramed(true);
314
        }
315
        return $this->smarty;
316
    }
317
318
    /**
319
     * Assign a value to a template variables
320
     *
321
     * @link http://www.smarty.net/docs/en/api.assign.tpl Pass-through to `Smarty::assign()`
322
     *
323
     * @param string $varname
324
     * @param mixed $var
325
     * @param boolean $noCache (Optional, default `false`)
326
     * @return void
327
     */
328
    public function smarty_assign($varname, $var = null, $noCache = false)
329
    {
330
        return $this->getSmarty()->assign($varname, $var, $noCache);
331
    }
332
333
    /**
334
     * Register another template directory
335
     *
336
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/BootstrapSmarty/master/doc/classes/Battis.BootstrapSmarty.BootstrapSmarty.html#method_addTemplateDir Pass-through to `BootstrapSmarty::addTemplateDir()`
337
     *
338
     * @param string $template
339
     * @param string $key (Optional, default `null`)
340
     * @param boolean $isConfig (Optional, default `false`)
341
     */
342
    public function smarty_addTemplateDir($template, $key = null, $isConfig = false)
343
    {
344
        return $this->getSmarty()->addTemplateDir($template, $key, $isConfig);
345
    }
346
347
    /**
348
     * Prepend an over-riding template directory to Smarty
349
     *
350
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/BootstrapSmarty/master/doc/classes/Battis.BootstrapSmarty.BootstrapSmarty.html#method_prependTemplateDir Pass-through to `BootstrapSmarty::prependTemplateDir()`
351
     *
352
     * @param string $template
353
     * @param string $key (Optional)
354
     */
355
    public function smarty_prependTemplateDir($template, $key = null) {
356
        return $this->getSmarty()->prependTemplateDir($template, $key);
357
    }
358
359
    /**
360
     * Add a message to be displayed to the user
361
     *
362
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/BootstrapSmarty/master/doc/classes/Battis.BootstrapSmarty.BootstrapSmarty.html#method_addMessage Pass-through to `BootstrapSmarty::addMessage()`
363
     *
364
     * @param string $title
365
     * @param string $content,
0 ignored issues
show
Documentation introduced by
There is no parameter named $content,. Did you maybe mean $content?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
366
     * @param string $class (Optional, default `NotificationMessage::INFO`)
367
     */
368
    public function smarty_addMessage($title, $content, $class = NotificationMessage::INFO)
369
    {
370
        return $this->getSmarty()->addMessage($title, $content, $class);
371
    }
372
373
    /**
374
     * Display an HTML template
375
     *
376
     * @link https://htmlpreview.github.io/?https://raw.githubusercontent.com/battis/BootstrapSmarty/master/doc/classes/Battis.BootstrapSmarty.BootstrapSmarty.html#method_display Pass-through to `BootstrapSmarty::display()`
377
     *
378
     * @param string $template (Optional, default `page.tpl`)
379
     * @param string $cache_id (Optional, default `null`)
380
     * @param string $compile_id (Optional, default, `null`)
381
     * @param string $parent (Optional, default `null`)
382
     * @return void
383
     */
384
    public function smarty_display($template = 'page.tpl', $cache_id = null, $compile_id = null, $parent = null)
385
    {
386
        return $this->getSmarty()->display($template, $cache_id, $compile_id, $parent);
387
    }
388
}
389