Index: src/config.dist.php
==================================================================
--- src/config.dist.php
+++ src/config.dist.php
@@ -196,10 +196,18 @@
*
* N'activer que si vous êtes sûr que le module est installé et activé (sinon
* les fichiers ne pourront être vus ou téléchargés).
* Nginx n'est PAS supporté, car X-Accel-Redirect ne peut gérer que des fichiers
* qui sont *dans* le document root du vhost, ce qui n'est pas le cas ici.
+ *
+ * Pour activer X-SendFile mettre dans la config du virtualhost de Garradin:
+ * XSendFile On
+ * XSendFilePath /var/www/garradin
+ *
+ * (remplacer le chemin par le répertoire racine de Garradin)
+ *
+ * Détails : https://tn123.org/mod_xsendfile/
*
* Défaut : false
*/
const ENABLE_XSENDFILE = false;
Index: src/include/init.php
==================================================================
--- src/include/init.php
+++ src/include/init.php
@@ -124,10 +124,11 @@
}
}
const WEBSITE = 'https://garradin.eu/';
const PLUGINS_URL = 'https://garradin.eu/plugins/list.json';
+const DEFAULT_REPORT_URL = 'http://henga.test/report/?p=ABCD';
// PHP devrait être assez intelligent pour chopper la TZ système mais nan
// il sait pas faire (sauf sur Debian qui a le bon patch pour ça), donc pour
// éviter le message d'erreur à la con on définit une timezone par défaut
// Pour utiliser une autre timezone, il suffit de définir date.timezone dans
@@ -222,11 +223,15 @@
'garradin_version' => garradin_version(),
]);
if (ERRORS_REPORT_URL)
{
- ErrorManager::setRemoteReporting(ERRORS_REPORT_URL, false);
+ ErrorManager::setRemoteReporting(ERRORS_REPORT_URL, true);
+}
+else
+{
+ ErrorManager::setRemoteReporting(DEFAULT_REPORT_URL, false);
}
ErrorManager::setProductionErrorTemplate('
Erreur interne
\__/ (xx) //||\\\\
Une erreur s\'est produite
-
+
');
function user_error($e)
Index: src/include/lib/Garradin/Compta/Journal.php
==================================================================
--- src/include/lib/Garradin/Compta/Journal.php
+++ src/include/lib/Garradin/Compta/Journal.php
@@ -374,39 +374,22 @@
return $db->get($query);
}
public function searchSQL($query)
{
- $db = DB::getInstance();
-
if (!preg_match('/LIMIT\s+/i', $query))
{
$query = preg_replace('/;?\s*$/', '', $query);
$query .= ' LIMIT 100';
}
- if (preg_match('/;\s*(.+?)$/', $query))
- {
- throw new UserException('Une seule requête peut être envoyée en même temps.');
- }
-
- $st = $db->prepare($query);
-
- if (!$st->readOnly())
- {
- throw new UserException('Seules les requêtes en lecture sont autorisées.');
- }
-
- $res = $st->execute();
- $out = [];
-
- while ($row = $res->fetchArray(SQLITE3_ASSOC))
- {
- $out[] = $row;
- }
-
- return $out;
+ try {
+ return DB::getInstance()->userSelectGet($query);
+ }
+ catch (\Exception $e) {
+ throw new UserException('Erreur dans la requête : ' . $e->getMessage());
+ }
}
public function schemaSQL()
{
$db = DB::getInstance();
Index: src/include/lib/Garradin/Membres/Import.php
==================================================================
--- src/include/lib/Garradin/Membres/Import.php
+++ src/include/lib/Garradin/Membres/Import.php
@@ -287,10 +287,11 @@
protected function export(array $list = null)
{
$db = DB::getInstance();
$champs = Config::getInstance()->get('champs_membres')->getKeys();
+ $champs = array_map([$db, 'quoteIdentifier'], $champs);
$champs_sql = 'm.' . implode(', m.', $champs);
$where = $list ? 'WHERE ' . $db->where('m.id', $list) : '';
$res = $db->iterate('SELECT ' . $champs_sql . ', c.nom AS "Catégorie membre" FROM membres AS m
INNER JOIN membres_categories AS c ON m.id_categorie = c.id
Index: src/include/lib/Garradin/Membres/Session.php
==================================================================
--- src/include/lib/Garradin/Membres/Session.php
+++ src/include/lib/Garradin/Membres/Session.php
@@ -27,10 +27,12 @@
// Extension des méthodes de UserSession
public function __construct()
{
$url = parse_url(ADMIN_URL);
+
+ //throw new \Exception('lol');
parent::__construct(DB::getInstance(), [
'cookie_domain' => $url['host'],
'cookie_path' => preg_replace('!/admin/$!', '/', $url['path']),
'cookie_secure' => (\Garradin\PREFER_HTTPS >= 2) ? true : false,
Index: src/include/lib/Garradin/Plugin.php
==================================================================
--- src/include/lib/Garradin/Plugin.php
+++ src/include/lib/Garradin/Plugin.php
@@ -290,19 +290,25 @@
include $this->path() . '/upgrade.php';
}
$infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false);
- return DB::getInstance()->update('plugins', [
+ $data = [
'nom' => $infos->nom,
'description'=> $infos->description,
'auteur' => $infos->auteur,
'url' => $infos->url,
'version' => $infos->version,
'menu' => (int)(bool)$infos->menu,
- 'menu_condition' => $infos->menu && isset($infos->menu_condition) ? trim($infos->menu_condition) : null,
- ], 'id = :id', ['id' => $this->id]);
+ ];
+
+ if ($infos->menu && !empty($infos->menu_condition))
+ {
+ $data['menu_condition'] = trim($infos->menu_condition);
+ }
+
+ return DB::getInstance()->update('plugins', $data, 'id = :id', ['id' => $this->id]);
}
/**
* Associer un signal à un callback du plugin
* @param string $signal Nom du signal (par exemple boucle.agenda pour la boucle de type AGENDA)
@@ -434,17 +440,12 @@
'{Membres::DROIT_ADMIN}' => Membres::DROIT_ADMIN,
]);
$condition = preg_replace_callback('/\{\$user\.(\w+)\}/', function ($m) use ($user) { return $user->{$m[1]}; }, $condition);
$query = 'SELECT 1 WHERE ' . $condition . ';';
- $st = $db->prepare($query);
- if (!$st->readOnly())
- {
- throw new \LogicException('Requête plugin pour affichage dans le menu n\'est pas en lecture : ' . $query);
- }
-
+ $st = $db->userSelectStatement($query);
$res = $st->execute();
if (!$res->fetchArray(\SQLITE3_NUM))
{
unset($list[$id]);
@@ -700,24 +701,30 @@
}
$config = json_encode($config);
}
- $db = DB::getInstance();
- $db->begin();
- $db->insert('plugins', [
+ $data = [
'id' => $id,
'officiel' => (int)(bool)$official,
'nom' => $infos->nom,
'description'=> $infos->description,
'auteur' => $infos->auteur,
'url' => $infos->url,
'version' => $infos->version,
'menu' => (int)(bool)$infos->menu,
- 'menu_condition' => $infos->menu && isset($infos->menu_condition) ? trim($infos->menu_condition) : null,
'config' => $config,
- ]);
+ ];
+
+ if ($infos->menu && !empty($infos->menu_condition))
+ {
+ $data['menu_condition'] = trim($infos->menu_condition);
+ }
+
+ $db = DB::getInstance();
+ $db->begin();
+ $db->insert('plugins', $data);
if (file_exists($path . '/install.php'))
{
$plugin = new Plugin($id);
require $plugin->path() . '/install.php';
Index: src/include/lib/Garradin/Recherche.php
==================================================================
--- src/include/lib/Garradin/Recherche.php
+++ src/include/lib/Garradin/Recherche.php
@@ -394,44 +394,27 @@
if (!in_array($target, self::TARGETS, true))
{
throw new \InvalidArgumentException('Cible inconnue : ' . $target);
}
- $db = DB::getInstance();
-
if ($force_select)
{
$query = preg_replace('/^\s*SELECT.*FROM\s+/Ui', 'SELECT ' . $force_select . ' FROM ', $query);
}
- if (!preg_match('/LIMIT\s+/i', $query))
+ if (!preg_match('/LIMIT\s+\d+/i', $query))
{
$query = preg_replace('/;?\s*$/', '', $query);
$query .= ' LIMIT 100';
}
- if (preg_match('/;\s*(.+?)$/', $query))
- {
- throw new UserException('Une seule requête peut être envoyée en même temps.');
- }
-
- $st = $db->prepare($query);
-
- if (!$st->readOnly())
- {
- throw new UserException('Seules les requêtes en lecture sont autorisées.');
- }
-
- $res = $st->execute();
- $out = [];
-
- while ($row = $res->fetchArray(SQLITE3_ASSOC))
- {
- $out[] = (object) $row;
- }
-
- return $out;
+ try {
+ return DB::getInstance()->userSelectGet($query);
+ }
+ catch (\Exception $e) {
+ throw new UserException('Erreur dans la requête : ' . $e->getMessage());
+ }
}
public function schema($target)
{
$db = DB::getInstance();
Index: src/include/lib/Garradin/Squelette.php
==================================================================
--- src/include/lib/Garradin/Squelette.php
+++ src/include/lib/Garradin/Squelette.php
@@ -572,11 +572,11 @@
if ($criteria['field'] == 'w.id')
{
$criteria['field'] = 'id';
}
-
+
$query_args[] = ['$this->getVariable(\'' . $criteria['field'] . '\')'];
break;
}
default:
break;
@@ -606,11 +606,11 @@
else
{
$query .= '?';
$query_args[] = ['\'.$this->variables[\'debut_liste\'].\''];
}
-
+
$query .= ','.(int)$limit;
}
}
else
{
@@ -651,21 +651,16 @@
}
}
try {
// Sécurité anti injection, à la compilation seulement
- $statement = $db->prepare($query);
+ $statement = $db->userSelectStatement($query);
}
catch (\Exception $e)
{
throw new \KD2\MiniSkelMarkupException("Erreur SQL dans la requête : ".$e->getMessage() . "\n " . $query);
}
-
- if (!$statement->readOnly())
- {
- throw new \KD2\MiniSkelMarkupException("Requête en écriture illégale: ".$query);
- }
$hash = sha1(uniqid(mt_rand(), true));
$out = new Squelette_Snippet();
$out->append(1, '$parent_hash = $this->current[\'_self_hash\'];');
$out->append(1, '$this->parent =& $parent_hash ? $this->_vars[$parent_hash] : null;');
Index: src/include/lib/Garradin/Wiki.php
==================================================================
--- src/include/lib/Garradin/Wiki.php
+++ src/include/lib/Garradin/Wiki.php
@@ -31,41 +31,41 @@
public function _checkFields(&$data)
{
$db = DB::getInstance();
- if (isset($data['titre']) && !trim($data['titre']))
+ if (array_key_exists('titre', $data) && !trim($data['titre']))
{
throw new UserException('Le titre ne peut rester vide.');
}
- if (isset($data['uri']) && !trim($data['uri']))
+ if (array_key_exists('uri', $data) && !trim($data['uri']))
{
throw new UserException('L\'adresse de la page ne peut rester vide.');
}
- if (isset($data['droit_lecture']))
+ if (array_key_exists('droit_lecture', $data))
{
$data['droit_lecture'] = (int) $data['droit_lecture'];
if ($data['droit_lecture'] < -1)
{
$data['droit_lecture'] = 0;
}
}
- if (isset($data['droit_ecriture']))
+ if (array_key_exists('droit_ecriture', $data))
{
$data['droit_ecriture'] = (int) $data['droit_ecriture'];
if ($data['droit_ecriture'] < 0)
{
$data['droit_ecriture'] = 0;
}
}
- if (isset($data['parent']))
+ if (array_key_exists('parent', $data))
{
$data['parent'] = (int) $data['parent'];
if ($data['parent'] < 0)
{
Index: src/templates/admin/config/membres.tpl
==================================================================
--- src/templates/admin/config/membres.tpl
+++ src/templates/admin/config/membres.tpl
@@ -28,11 +28,11 @@
{if $nom == 'passe'}{continue}{/if}
{html_champ_membre config=$champ name=$nom disabled=true}
{if empty($champ.editable) || !empty($champ.private)}
{if !empty($champ.private)}
- (Champ privé)
+ (Champ caché)
{elseif empty($champ.editable)}
(Non-modifiable par les membres)
{/if}