Ajout du support des écritures ventilées.
[garradin.git] / include / init.php
1 <?php
2
3 namespace Garradin;
4
5 error_reporting(-1);
6
7 /*
8 * Version de Garradin
9 */
10
11 function garradin_version()
12 {
13 if (defined('Garradin\VERSION'))
14 {
15 return VERSION;
16 }
17
18 $file = __DIR__ . '/../VERSION';
19
20 if (file_exists($file))
21 {
22 $version = trim(file_get_contents($file));
23 }
24 else
25 {
26 $version = 'unknown';
27 }
28
29 define('Garradin\VERSION', $version);
30 return $version;
31 }
32
33 function garradin_manifest()
34 {
35 $file = __DIR__ . '/../../manifest.uuid';
36
37 if (file_exists($file))
38 {
39 return substr(trim(file_get_contents($file)), 0, 10);
40 }
41
42 return false;
43 }
44
45 /*
46 * Configuration globale
47 */
48
49 // Configuration externalisée
50 if (file_exists(__DIR__ . '/../config.local.php'))
51 {
52 require __DIR__ . '/../config.local.php';
53 }
54
55 if (!defined('Garradin\ROOT'))
56 {
57 define('Garradin\ROOT', dirname(__DIR__));
58 }
59
60 if (!defined('Garradin\DATA_ROOT'))
61 {
62 define('Garradin\DATA_ROOT', ROOT);
63 }
64
65 if (!defined('Garradin\DB_FILE'))
66 {
67 define('Garradin\DB_FILE', DATA_ROOT . '/association.sqlite');
68 }
69
70 if (!defined('Garradin\DB_SCHEMA'))
71 {
72 define('Garradin\DB_SCHEMA', ROOT . '/include/data/schema.sql');
73 }
74
75 if (!defined('Garradin\WWW_URI'))
76 {
77 // Automagic URL discover
78 $path = str_replace(ROOT . '/www', '', getcwd());
79 $path = str_replace($path, '', dirname($_SERVER['SCRIPT_NAME']));
80 $path = (!empty($path[0]) && $path[0] != '/') ? '/' . $path : $path;
81 $path = (substr($path, -1) != '/') ? $path . '/' : $path;
82 define('Garradin\WWW_URI', $path);
83 }
84
85 if (!defined('Garradin\WWW_URL'))
86 {
87 $host = isset($_SERVER['HTTP_HOST'])
88 ? $_SERVER['HTTP_HOST']
89 : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
90 define('Garradin\WWW_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $host . WWW_URI);
91 }
92
93 if (!defined('Garradin\PLUGINS_ROOT'))
94 {
95 define('Garradin\PLUGINS_ROOT', DATA_ROOT . '/plugins');
96 }
97
98 if (!defined('Garradin\PLUGINS_SYSTEM'))
99 {
100 define('Garradin\PLUGINS_SYSTEM', '');
101 }
102
103 // Affichage des erreurs par défaut
104 if (!defined('Garradin\SHOW_ERRORS'))
105 {
106 define('Garradin\SHOW_ERRORS', true);
107 }
108
109 if (!defined('Garradin\MAIL_ERRORS'))
110 {
111 define('Garradin\MAIL_ERRORS', false);
112 }
113
114 // Utilisation de cron pour les tâches automatiques
115 if (!defined('Garradin\USE_CRON'))
116 {
117 define('Garradin\USE_CRON', false);
118 }
119
120 define('Garradin\WEBSITE', 'http://garradin.eu/');
121 define('Garradin\PLUGINS_URL', 'https://garradin.eu/plugins/list.json');
122
123 // PHP devrait être assez intelligent pour chopper la TZ système mais nan
124 // il sait pas faire (sauf sur Debian qui a le bon patch pour ça), donc pour
125 // éviter le message d'erreur à la con on définit une timezone par défaut
126 // Pour utiliser une autre timezone, il suffit de définir date.timezone dans
127 // un .htaccess ou dans config.local.php
128 if (!ini_get('date.timezone'))
129 {
130 if ($tz = @date_default_timezone_get())
131 {
132 ini_set('date.timezone', $tz);
133 }
134 else
135 {
136 ini_set('date.timezone', 'Europe/Paris');
137 }
138 }
139
140 ini_set('error_log', DATA_ROOT . '/error.log');
141 ini_set('log_errors', true);
142
143 if (SHOW_ERRORS)
144 {
145 // Gestion par défaut des erreurs
146 ini_set('display_errors', true);
147 ini_set('html_errors', false);
148
149 if (PHP_SAPI != 'cli')
150 {
151 ini_set('error_prepend_string', '<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">body { font-family: sans-serif; } h3 { color: darkred; }
152 pre { text-shadow: 2px 2px 5px black; color: darkgreen; font-size: 2em; float: left; margin: 0 1em 0 0; padding: 1em; background: #cfc; border-radius: 50px; }</style>
153 <pre> \__/<br /> (xx)<br />//||\\\\</pre>
154 <h1>Erreur fatale</h1>
155 <p>Une erreur fatale s\'est produite à l\'exécution de Garradin. Pour rapporter ce bug
156 merci d\'inclure le message ci-dessous :</p>
157 <h3>');
158 ini_set('error_append_string', '</h3><hr />
159 <p><a href="http://dev.kd2.org/garradin/Rapporter%20un%20bug">Comment rapporter un bug</a></p>');
160 }
161 }
162
163 /*
164 * Gestion des erreurs et exceptions
165 */
166
167 class UserException extends \LogicException
168 {
169 }
170
171 function exception_error_handler($errno, $errstr, $errfile, $errline )
172 {
173 // For @ ignored errors
174 if (error_reporting() === 0) return;
175 throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
176 }
177
178 function exception_handler($e)
179 {
180 if ($e instanceOf UserException || $e instanceOf miniSkelMarkupException)
181 {
182 try {
183 if (PHP_SAPI == 'cli')
184 {
185 echo $e->getMessage();
186 }
187 else
188 {
189 $tpl = Template::getInstance();
190
191 $tpl->assign('error', $e->getMessage());
192 $tpl->display('error.tpl');
193 }
194
195 exit;
196 }
197 catch (Exception $e)
198 {
199 }
200 }
201
202 $file = str_replace(ROOT, '', $e->getFile());
203
204 $error = "Exception of type ".get_class($e)." happened !\n\n".
205 $e->getCode()." - ".$e->getMessage()."\n\nIn: ".
206 $file . ":" . $e->getLine()."\n\n";
207
208 if (!empty($_SERVER['HTTP_HOST']) && !empty($_SERVER['REQUEST_URI']))
209 $error .= 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n\n";
210
211 $error .= $e->getTraceAsString();
212 $error .= "\n-------------\n";
213 $error .= 'Garradin version: ' . garradin_version() . "\n";
214 $error .= 'Garradin manifest: ' . garradin_manifest() . "\n";
215 $error .= 'PHP version: ' . phpversion() . "\n";
216
217 foreach ($_SERVER as $key=>$value)
218 {
219 if (is_array($value))
220 $value = json_encode($value);
221
222 $error .= $key . ': ' . $value . "\n";
223 }
224
225 $error = str_replace("\r", '', $error);
226 error_log($error);
227
228 if (MAIL_ERRORS)
229 {
230 mail(MAIL_ERRORS, '[Garradin] Erreur d\'exécution', $error, 'From: "' . WWW_URL . '" <noreply@no.reply>');
231 }
232
233 if (PHP_SAPI == 'cli')
234 {
235 echo $error;
236 }
237 else
238 {
239 echo '<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">body { font-family: sans-serif; } h3 { color: darkred; }
240 pre { text-shadow: 2px 2px 5px black; color: darkgreen; font-size: 2em; float: left; margin: 0 1em 0 0; padding: 1em; background: #cfc; border-radius: 50px; }</style>
241 <pre> \__/<br /> (xx)<br />//||\\\\</pre>
242 <h1>Erreur d\'exécution</h1>';
243
244 if (SHOW_ERRORS)
245 {
246 echo '<p>Une erreur s\'est produite à l\'exécution de Garradin. Pour rapporter ce bug
247 merci d\'inclure le message suivant :</p>
248 <textarea cols="70" rows="'.substr_count($error, "\n").'">'.htmlspecialchars($error, ENT_QUOTES, 'UTF-8').'</textarea>
249 <hr />
250 <p><a href="http://dev.kd2.org/garradin/Rapporter%20un%20bug">Comment rapporter un bug</a></p>';
251 }
252 else
253 {
254 echo '<p>Une erreur s\'est produite à l\'exécution de Garradin.</p>
255 <p>Le webmaster a été prévenu.</p>';
256 }
257 }
258
259 exit;
260 }
261
262 set_error_handler('Garradin\exception_error_handler');
263 set_exception_handler('Garradin\exception_handler');
264
265 /**
266 * Auto-load classes and libs
267 */
268 class Loader
269 {
270 /**
271 * Already loaded filenames
272 * @var array
273 */
274 static protected $loaded = [];
275
276 static protected $libs = [
277 'utils',
278 'squelette_filtres',
279 'static_cache',
280 'template'
281 ];
282
283 /**
284 * Loads a class from the $name
285 * @param stringg $classname
286 * @return bool true
287 */
288 static public function load($classname)
289 {
290 $classname = ltrim($classname, '\\');
291 $filename = '';
292 $namespace = '';
293
294 if ($lastnspos = strripos($classname, '\\'))
295 {
296 $namespace = substr($classname, 0, $lastnspos);
297 $classname = substr($classname, $lastnspos + 1);
298
299 if ($namespace != 'Garradin')
300 {
301 $filename = str_replace('\\', '/', $namespace) . '/';
302 }
303 }
304
305 $classname = strtolower($classname);
306
307 if (in_array($classname, self::$libs)) {
308 $filename = 'lib.' . $classname . '.php';
309 } else {
310 $filename .= 'class.' . $classname . '.php';
311 }
312
313 $filename = ROOT . '/include/' . $filename;
314
315 if (array_key_exists($filename, self::$loaded))
316 {
317 return true;
318 }
319
320 if (!file_exists($filename)) {
321 throw new \Exception('File '.$filename.' doesn\'t exists');
322 }
323
324 self::$loaded[$filename] = true;
325
326 require $filename;
327 }
328 }
329
330 \spl_autoload_register(['Garradin\Loader', 'load'], true);
331
332 $n = new Membres;
333
334 /*
335 * Inclusion des fichiers de base
336 */
337
338 if (!defined('Garradin\INSTALL_PROCESS') && !defined('Garradin\UPGRADE_PROCESS'))
339 {
340 if (!file_exists(DB_FILE))
341 {
342 utils::redirect('/admin/install.php');
343 }
344
345 $config = Config::getInstance();
346
347 if (version_compare($config->getVersion(), garradin_version(), '<'))
348 {
349 utils::redirect('/admin/upgrade.php');
350 }
351 }
352
353 ?>