1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
require_once(__DIR__ . '/vendor/autoload.php'); |
4
|
|
|
|
5
|
|
|
define('SECRETS_FILE', __DIR__ . '/secrets.xml'); |
6
|
|
|
define('SCHEMA_FILE', __DIR__ . '/admin/schema-app.sql'); |
7
|
|
|
define('MYSQL_PREFIX', ''); |
8
|
|
|
|
9
|
|
|
use Battis\AppMetadata; |
10
|
|
|
use smtech\StMarksSmarty\StMarksSmarty; |
11
|
|
|
use Battis\BootstrapSmarty\NotificationMessage; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Test if the app is in the middle of launching |
15
|
|
|
* |
16
|
|
|
* Wait for $toolProvider to be fully initialized before starting the app logic. |
17
|
|
|
* |
18
|
|
|
* @return boolean |
19
|
|
|
**/ |
20
|
|
|
function midLaunch() { |
|
|
|
|
21
|
|
|
global $metadata; // FIXME:0 grown-ups don't program like this issue:17 |
|
|
|
|
22
|
|
|
return $metadata['APP_LAUNCH_URL'] === (($_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Initialize a SimpleXMLElement from the SECRETS_FILE |
27
|
|
|
* |
28
|
|
|
* @return SimpleXMLElement |
29
|
|
|
* |
30
|
|
|
* @throws CanvasAPIviaLTI_Exception MISSING_SECRETS_FILE if the SECRETS_FILE cannot be found |
31
|
|
|
* @throws CanvasAPIviaLTI_Exception INVALID_SECRETS_FILE if the SECRETS_FILE exists, but cannot be parsed |
32
|
|
|
**/ |
33
|
|
|
function initSecrets() { |
34
|
|
|
if (file_exists(SECRETS_FILE)) { |
35
|
|
|
// http://stackoverflow.com/a/24760909 (oy!) |
36
|
|
|
if (($secrets = simplexml_load_string(file_get_contents(SECRETS_FILE))) !== false) { |
37
|
|
|
return $secrets; |
38
|
|
|
} else { |
39
|
|
|
throw new CanvasAPIviaLTI_Exception( |
40
|
|
|
SECRETS_FILE . ' could not be loaded. ', |
41
|
|
|
CanvasAPIviaLTI_Exception::INVALID_SECRETS_FILE |
42
|
|
|
); |
43
|
|
|
} |
44
|
|
|
} else { |
45
|
|
|
throw new CanvasAPIviaLTI_Exception( |
46
|
|
|
SECRETS_FILE . " could not be found.", |
47
|
|
|
CanvasAPIviaLTI_Exception::MISSING_SECRETS_FILE |
48
|
|
|
); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Initialize a mysqli connector using the credentials stored in SECRETS_FILE |
54
|
|
|
* |
55
|
|
|
* @uses initSecrets() If $secrets is not already initialized |
56
|
|
|
* |
57
|
|
|
* @return mysqli A valid mysqli connector to the database backing the CanvasAPIviaLTI instance |
58
|
|
|
* |
59
|
|
|
* @throws CanvasAPIviaLTI_Exception MYSQL_CONNECTION if a mysqli connection cannot be established |
60
|
|
|
**/ |
61
|
|
|
function initMySql() { |
62
|
|
|
global $secrets; // FIXME:0 grown-ups don't program like this issue:17 |
|
|
|
|
63
|
|
|
if (!($secrets instanceof SimpleXMLElement)) { |
64
|
|
|
$secrets = initSecrets(); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/* turn off warnings, since we're going to test the connection ourselves */ |
68
|
|
|
set_error_handler(function() {}); |
69
|
|
|
$sql = new mysqli( |
70
|
|
|
(string) $secrets->mysql->host, |
71
|
|
|
(string) $secrets->mysql->username, |
72
|
|
|
(string) $secrets->mysql->password, |
73
|
|
|
(string) $secrets->mysql->database |
74
|
|
|
); |
75
|
|
|
restore_error_handler(); |
76
|
|
|
|
77
|
|
|
if ($sql->connect_error) { |
78
|
|
|
throw new CanvasAPIviaLTI_Exception( |
79
|
|
|
$sql->connect_error, |
80
|
|
|
CanvasAPIviaLTI_Exception::MYSQL_CONNECTION |
81
|
|
|
); |
82
|
|
|
} |
83
|
|
|
return $sql; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Initialize AppMetadata |
88
|
|
|
* |
89
|
|
|
* @return \Battis\AppMetadata |
90
|
|
|
**/ |
91
|
|
|
function initAppMetadata() { |
92
|
|
|
global $secrets; // FIXME:0 grown-ups don't program like this issue:17 |
|
|
|
|
93
|
|
|
global $sql; // FIXME:0 grown-ups don't program like this issue:17 |
|
|
|
|
94
|
|
|
|
95
|
|
|
$metadata = new AppMetadata($sql, (string) $secrets->app->id); |
96
|
|
|
|
97
|
|
|
return $metadata; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Preformat `var_dump()` |
102
|
|
|
* |
103
|
|
|
* @param mixed $var |
104
|
|
|
* |
105
|
|
|
* @return void |
106
|
|
|
**/ |
107
|
|
|
function html_var_dump($var) { |
108
|
|
|
echo '<pre>'; |
109
|
|
|
var_dump($var); |
|
|
|
|
110
|
|
|
echo '</pre>'; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/***************************************************************************** |
114
|
|
|
* * |
115
|
|
|
* The script begins here * |
116
|
|
|
* * |
117
|
|
|
*****************************************************************************/ |
118
|
|
|
|
119
|
|
|
/* assume everything's going to be fine... */ |
120
|
|
|
$ready = true; |
121
|
|
|
|
122
|
|
|
/* preliminary interactive only initialization */ |
123
|
|
|
if (php_sapi_name() != 'cli') { |
124
|
|
|
session_start(); |
125
|
|
|
|
126
|
|
|
/* fire up the templating engine for interactive scripts */ |
127
|
|
|
$smarty = StMarksSmarty::getSmarty(); |
128
|
|
|
$smarty->addTemplateDir(__DIR__ . '/templates', 'starter-canvas-api-via-lti'); |
129
|
|
|
$smarty->setFramed(true); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/* initialization that needs to happen for interactive and CLI scripts */ |
133
|
|
|
try { |
134
|
|
|
/* initialize global variables */ |
135
|
|
|
$secrets = initSecrets(); |
136
|
|
|
$sql = initMySql(); |
137
|
|
|
$metadata = initAppMetadata(); |
138
|
|
|
} catch (CanvasAPIviaLTI_Exception $e) { |
139
|
|
|
if (php_sapi_name() == 'cli') { |
140
|
|
|
echo 'Initialization Failure [' . $e->getCode() . ']' . PHP_EOL . $e->getMessage() . PHP_EOL; |
141
|
|
|
exit; |
142
|
|
|
} else { |
143
|
|
|
$smarty->addMessage( |
144
|
|
|
'Initialization Failure [' . $e->getCode() . ']', |
145
|
|
|
$e->getMessage(), |
146
|
|
|
NotificationMessage::ERROR |
|
|
|
|
147
|
|
|
); |
148
|
|
|
$smarty->display(); |
149
|
|
|
exit; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/* interactive initialization only */ |
154
|
|
|
if ($ready && php_sapi_name() != 'cli') { |
155
|
|
|
|
156
|
|
|
/* allow web apps to use common.inc.php without LTI authentication */ |
157
|
|
|
if (!defined('IGNORE_LTI')) { |
158
|
|
|
|
159
|
|
|
try { |
160
|
|
|
if (midLaunch()) { |
161
|
|
|
$ready = false; |
162
|
|
|
} elseif (isset($_SESSION['toolProvider'])) { |
163
|
|
|
$toolProvider = $_SESSION['toolProvider']; |
164
|
|
|
} else { |
165
|
|
|
throw new CanvasAPIviaLTI_Exception( |
166
|
|
|
'The LTI launch request is missing', |
167
|
|
|
CanvasAPIviaLTI_Exception::LAUNCH_REQUEST |
168
|
|
|
); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
} catch (CanvasAPIviaLTI_Exception $e) { |
172
|
|
|
$ready = false; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
if ($ready) { |
177
|
|
|
$smarty->addStylesheet($metadata['APP_URL'] . '/css/canvas-api-via-lti.css', 'starter-canvas-api-via-lti'); |
178
|
|
|
$smarty->addStylesheet($metadata['APP_URL'] . '/css/app.css'); |
179
|
|
|
|
180
|
|
|
if (!midLaunch() || !defined('IGNORE_LTI')) { |
181
|
|
|
require_once(__DIR__ . '/common-app.inc.php'); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
} elseif (php_sapi_name() == 'cli') { |
185
|
|
|
require_once(__DIR__ . '/common-app.inc.php'); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
|
189
|
|
|
?> |
|
|
|
|
190
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.