These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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() { |
||
0 ignored issues
–
show
|
|||
21 | global $metadata; // FIXME:0 grown-ups don't program like this issue:17 |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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 |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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 |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
93 | global $sql; // FIXME:0 grown-ups don't program like this issue:17 |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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); |
||
0 ignored issues
–
show
|
|||
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 |
||
0 ignored issues
–
show
The constant
Battis\BootstrapSmarty\NotificationMessage::ERROR has been deprecated with message: Use `DANGER` instead for consistency with Bootstrap
This class constant has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead. ![]() |
|||
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 | ?> |
||
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever. ![]() |
|||
190 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: