DELETED README
Index: README
==================================================================
--- README
+++ README
@@ -1,33 +0,0 @@
-Garradin - Gestionnaire d'association libre
-===========================================
-
-Inclus les bibliothèques suivantes :
-
-- Gibberish AES
- https://github.com/mdp/gibberish-aes
- Copyright : Mark Percival 2008 - http://markpercival.us
- Licence : MIT
-
-- Countries - Liste des pays ISO 3166-1
- Copyright : BohwaZ
- Licence : Domaine public
-
-- Simple Diff PHP library
- Copyright : BohwaZ 2009
- Licence : GNU GPL v3
-
-- Garbage2xhtml - HTML cleaner
- Copyright : BohwaZ 2006-2011
- Licence : GNU AGPL v3
-
-- miniSkel - SPIP-like templates
- Copyright : BohwaZ 2007-2012
- Licence : GNU GPL v3
-
-- Passphrase - a PHP library to generate passphrases
- Copyright : BohwaZ 2011-2012
- Licence : WTFPL
-
-- Template_Lite
- Copyright : 2003,2004,2005 by Paul Lockaby, 2005,2006 Mark Dickenson, 2005-2012 BohwaZ
- Licence : GNU GPL v2.1
DELETED VERSION
Index: VERSION
==================================================================
--- VERSION
+++ VERSION
@@ -1,1 +0,0 @@
-0.5.6
DELETED construire_plan_comptable.php
Index: construire_plan_comptable.php
==================================================================
--- construire_plan_comptable.php
+++ construire_plan_comptable.php
@@ -1,583 +0,0 @@
- 2)
- {
- $prefixe = substr($code, 0, 3);
-
- if ($prefixe == 401 || $prefixe == 411 || $prefixe == 421 || $prefixe == 430 || $prefixe == 440
- || $prefixe == 468 || $code == 4686 || $prefixe == 472 || $prefixe == 487)
- {
- $position = Compta_Comptes::PASSIF;
- }
- else
- {
- $position = Compta_Comptes::ACTIF;
- }
- }
- else
- {
- $position = Compta_Comptes::PASSIF | Compta_Comptes::ACTIF;
- }
- }
- elseif ($classe == 6)
- {
- $position = Compta_Comptes::CHARGE;
- }
- elseif ($classe == 7)
- {
- $position = Compta_Comptes::PRODUIT;
- }
- elseif ($classe == 8)
- {
- if (substr($code, 0, 2) == 86)
- {
- $position = Compta_Comptes::CHARGE;
- }
- elseif (substr($code, 0, 2) == 87)
- {
- $position = Compta_Comptes::PRODUIT;
- }
- }
- elseif ($classe == 9)
- {
- $position = Compta_Comptes::CHARGE | Compta_Comptes::PRODUIT;
- }
-
- $plan[$code] = array(
- 'code' => $code,
- 'nom' => $nom,
- 'parent' => $parent,
- 'position' => $position,
- );
-}
-
-$json = utils::json_readable_encode($plan, 0);
-file_put_contents('include/plan_comptable.json', $json);
-
-die("OK\n");
-
-?>
DELETED include/class.champs_membres.php
Index: include/class.champs_membres.php
==================================================================
--- include/class.champs_membres.php
+++ include/class.champs_membres.php
@@ -1,428 +0,0 @@
- 'Adresse E-Mail',
- 'url' => 'Adresse URL',
- 'checkbox' => 'Case à cocher',
- 'date' => 'Date',
- 'datetime' => 'Date et heure',
- //'file' => 'Fichier',
- 'password' => 'Mot de passe',
- 'number' => 'Numéro',
- 'tel' => 'Numéro de téléphone',
- 'select' => 'Sélecteur à choix unique',
- 'multiple' => 'Sélecteur à choix multiple',
- 'country' => 'Sélecteur de pays',
- 'text' => 'Texte',
- 'textarea' => 'Texte multi-lignes',
- );
-
- protected $text_types = array(
- 'email',
- 'text',
- 'select',
- 'textarea',
- 'url',
- 'password',
- 'country'
- );
-
- protected $config_fields = array(
- 'type',
- 'title',
- 'help',
- 'editable',
- 'list_row',
- 'mandatory',
- 'private',
- 'options'
- );
-
- static protected $presets = null;
-
- public function __toString()
- {
- return utils::write_ini_string($this->champs);
- }
-
- public function toString()
- {
- return utils::write_ini_string($this->champs);
- }
-
- static public function importInstall()
- {
- $champs = parse_ini_file(GARRADIN_ROOT . '/include/data/champs_membres.ini', true);
- $champs = array_filter($champs, function ($row) { return !empty($row['install']); });
- return new Champs_Membres($champs);
- }
-
- static public function importPresets()
- {
- if (is_null(self::$presets))
- {
- self::$presets = parse_ini_file(GARRADIN_ROOT . '/include/data/champs_membres.ini', true);
- }
-
- return self::$presets;
- }
-
- static public function listUnusedPresets(Champs_Membres $champs)
- {
- return array_diff_key(self::importPresets(), $champs->getAll());
- }
-
- public function __construct($champs)
- {
- if ($champs instanceOf Champs_Membres)
- {
- $this->champs = $champs->getAll();
- }
- elseif (is_array($champs))
- {
- foreach ($champs as $key=>&$config)
- {
- $this->_checkField($key, $config);
- }
-
- $this->champs = $champs;
- }
- else
- {
- $champs = parse_ini_string((string)$champs, true);
-
- foreach ($champs as $key=>&$config)
- {
- $this->_checkField($key, $config);
- }
-
- $this->champs = $champs;
- }
- }
-
- public function getTypes()
- {
- return $this->types;
- }
-
- public function get($champ, $key = null)
- {
- if (!array_key_exists($champ, $this->champs))
- return null;
-
- if ($key !== null)
- {
- if (array_key_exists($key, $this->champs[$champ]))
- return $this->champs[$champ][$key];
- else
- return null;
- }
-
- return $this->champs[$champ];
- }
-
- public function isText($champ)
- {
- if (!array_key_exists($champ, $this->champs))
- return null;
-
- if (in_array($this->champs[$champ]['type'], $this->text_types))
- return true;
- else
- return false;
- }
-
- public function getAll()
- {
- $this->champs['passe']['title'] = 'Mot de passe';
- return $this->champs;
- }
-
- public function getList()
- {
- $champs = $this->champs;
- unset($champs['passe']);
- return $champs;
- }
-
- public function getFirst()
- {
- reset($this->champs);
- return key($this->champs);
- }
-
- public function getListedFields()
- {
- $champs = $this->champs;
-
- $champs = array_filter($champs, function ($a) {
- return empty($a['list_row']) ? false : true;
- });
-
- uasort($champs, function ($a, $b) {
- if ($a['list_row'] == $b['list_row'])
- return 0;
-
- return ($a['list_row'] > $b['list_row']) ? 1 : -1;
- });
-
- return $champs;
- }
-
- /**
- * Vérifie la cohérence et la présence des bons éléments pour un champ
- * @param string $name Nom du champ
- * @param array $config Configuration du champ
- * @return boolean true
- */
- protected function _checkField($name, &$config)
- {
- if (!preg_match('!^\w+(_\w+)*$!', $name))
- {
- throw new UserException('Le nom du champ est invalide.');
- }
-
- foreach ($config as $key=>&$value)
- {
- // Champ install non pris en compte
- if ($key == 'install')
- {
- unset($config[$key]);
- continue;
- }
-
- if (!in_array($key, $this->config_fields))
- {
- throw new \BadMethodCallException('Champ '.$key.' non valide.');
- }
-
- if ($key == 'editable' || $key == 'private' || $key == 'mandatory')
- {
- $value = (bool) (int) $value;
- }
- elseif ($key == 'list_row')
- {
- $value = (int) $value;
- }
- elseif ($key == 'help' || $key == 'title')
- {
- $value = trim((string) $value);
- }
- elseif ($key == 'options')
- {
- $value = (array) $value;
-
- foreach ($value as $option_key=>$option_value)
- {
- if (trim($option_value) == '')
- {
- unset($value[$option_key]);
- }
- }
- }
- }
-
- if (empty($config['title']) && $name != 'passe')
- {
- throw new UserException('Champ "'.$name.'" : Le titre est obligatoire.');
- }
-
- if (empty($config['type']) || !array_key_exists($config['type'], $this->types))
- {
- throw new UserException('Champ "'.$name.'" : Le type est vide ou non valide.');
- }
-
- if ($name == 'email' && $config['type'] != 'email')
- {
- throw new UserException('Le champ email ne peut être d\'un type différent de email.');
- }
-
- if ($name == 'passe' && $config['type'] != 'password')
- {
- throw new UserException('Le champ mot de passe ne peut être d\'un type différent de mot de passe.');
- }
-
- if (($config['type'] == 'multiple' || $config['type'] == 'select') && empty($config['options']))
- {
- throw new UserException('Le champ "'.$name.'" nécessite de comporter au moins une option possible.');
- }
-
- if (!array_key_exists('editable', $config))
- {
- $config['editable'] = false;
- }
-
- if (!array_key_exists('mandatory', $config))
- {
- $config['mandatory'] = false;
- }
-
- if (!array_key_exists('private', $config))
- {
- $config['private'] = false;
- }
-
- return true;
- }
-
- /**
- * Ajouter un nouveau champ
- * @param string $name Nom du champ
- * @param array $config Configuration du champ
- * @return boolean true
- */
- public function add($name, $config)
- {
- $this->_checkField($name, $config);
-
- $this->champs[$name] = $config;
-
- return true;
- }
-
- /**
- * Modifie un champ particulier
- * @param string $champ Nom du champ
- * @param string $key Nom de la clé à modifier
- * @param mixed $value Valeur à affecter
- * @return boolean true
- */
- public function set($champ, $key, $value)
- {
- if (!isset($this->champs[$champ]))
- {
- throw new \LogicException('Champ "'.$champ.'" inconnu.');
- }
-
- // Vérification
- $config = $this->champs[$champ];
- $config[$key] = $value;
- $this->_checkField($champ, $config);
-
- $this->champs[$champ] = $config;
- return true;
- }
-
- /**
- * Modifie les champs en interne en vérifiant que tout va bien
- * @param array $champs Liste des champs
- * @return boolean true
- */
- public function setAll($champs)
- {
- if (!array_key_exists('email', $champs))
- {
- throw new UserException('Le champ E-Mail ne peut être supprimé des fiches membres.');
- }
-
- if (!array_key_exists('passe', $champs))
- {
- throw new UserException('Le champ Mot de passe ne peut être supprimé des fiches membres.');
- }
-
- foreach ($champs as $name=>&$config)
- {
- $this->_checkField($name, $config);
- }
-
- $this->champs = $champs;
-
- return true;
- }
-
- /**
- * Enregistre les changements de champs en base de données
- * @param boolean $enable_copy Recopier les anciennes champs dans les nouveaux ?
- * @return boolean true
- */
- public function save($enable_copy = true)
- {
- $db = DB::getInstance();
- $config = Config::getInstance();
-
- // Champs à créer
- $create = array(
- 'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement',
- 'id_categorie INTEGER NOT NULL, -- Numéro de catégorie',
- 'date_connexion TEXT NULL, -- Date de dernière connexion',
- 'date_inscription TEXT NOT NULL DEFAULT CURRENT_DATE, -- Date d\'inscription',
- 'date_cotisation TEXT NULL, -- Date de cotisation',
- //'exemption_transaction INTEGER NOT NULL DEFAULT 0, -- Exempté de transaction obligatoire',
- );
-
- $create_keys = array(
- 'FOREIGN KEY (id_categorie) REFERENCES membres_categories (id)'
- );
-
- // Champs à recopier
- $copy = array(
- 'id',
- 'id_categorie',
- 'date_connexion',
- 'date_inscription',
- 'date_cotisation',
- //'exemption_transaction',
- );
-
- $anciens_champs = $config->get('champs_membres');
- $anciens_champs = is_null($anciens_champs) ? $this->champs : $anciens_champs->getAll();
-
- foreach ($this->champs as $key=>$cfg)
- {
- if ($cfg['type'] == 'number')
- $type = 'FLOAT';
- elseif ($cfg['type'] == 'multiple' || $cfg['type'] == 'checkbox')
- $type = 'INTEGER';
- elseif ($cfg['type'] == 'file')
- $type = 'BLOB';
- else
- $type = 'TEXT';
-
- $line = $key . ' ' . $type . ',';
-
- if (!empty($cfg['title']))
- {
- $line .= ' -- ' . str_replace(array("\n", "\r"), '', $cfg['title']);
- }
-
- $create[] = $line;
-
- if (array_key_exists($key, $anciens_champs))
- {
- $copy[] = $key;
- }
- }
-
- $create = array_merge($create, $create_keys);
-
- $create = 'CREATE TABLE membres_tmp (' . "\n\t" . implode("\n\t", $create) . "\n);";
- $copy = 'INSERT INTO membres_tmp (' . implode(', ', $copy) . ') SELECT ' . implode(', ', $copy) . ' FROM membres;';
-
- $db->exec('PRAGMA foreign_keys = OFF;');
- $db->exec('BEGIN;');
- $db->exec($create);
-
- if ($enable_copy) {
- $db->exec($copy);
- }
-
- $db->exec('DROP TABLE IF EXISTS membres;');
- $db->exec('ALTER TABLE membres_tmp RENAME TO membres;');
- $db->exec('CREATE INDEX membres_id_categorie ON membres (id_categorie);'); // Index
- $db->exec('END;');
- $db->exec('PRAGMA foreign_keys = ON;');
-
- $config->set('champs_membres', $this);
- $config->save();
-
- return true;
- }
-}
-
-?>
DELETED include/class.compta_categories.php
Index: include/class.compta_categories.php
==================================================================
--- include/class.compta_categories.php
+++ include/class.compta_categories.php
@@ -1,126 +0,0 @@
-exec(file_get_contents(GARRADIN_ROOT . '/include/data/categories_comptables.sql'));
- }
-
- public function add($data)
- {
- $this->_checkFields($data);
-
- $db = DB::getInstance();
-
- if (empty($data['compte']) || !trim($data['compte']))
- {
- throw new UserException('Le compte associé ne peut rester vide.');
- }
-
- $data['compte'] = trim($data['compte']);
-
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['compte']))
- {
- throw new UserException('Le compte associé n\'existe pas.');
- }
-
- if (!isset($data['type']) ||
- ($data['type'] != self::DEPENSES && $data['type'] != self::RECETTES))
- {
- // Catégories "autres" pas possibles pour le moment
- throw new UserException('Type de catégorie inconnu.');
- }
-
- $db->simpleInsert('compta_categories', array(
- 'intitule' => $data['intitule'],
- 'description'=> $data['description'],
- 'compte' => $data['compte'],
- 'type' => (int)$data['type'],
- ));
-
- return $db->lastInsertRowId();
- }
-
- public function edit($id, $data)
- {
- $this->_checkFields($data);
-
- $db = DB::getInstance();
-
- $db->simpleUpdate('compta_categories',
- array(
- 'intitule' => $data['intitule'],
- 'description'=> $data['description'],
- ),
- 'id = \''.$db->escapeString(trim($id)).'\'');
-
- return true;
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
-
- // Ne pas supprimer une catégorie qui est utilisée !
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE id_categorie = ? LIMIT 1;', false, $id))
- {
- throw new UserException('Cette catégorie ne peut être supprimée car des opérations comptables y sont liées.');
- }
-
- $db->simpleExec('DELETE FROM compta_categories WHERE id = ?;', $id);
-
- return true;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT * FROM compta_categories WHERE id = ?;', true, (int)$id);
- }
-
- public function getList($type = null)
- {
- $db = DB::getInstance();
- $type = is_null($type) ? '' : 'cat.type = '.(int)$type;
- return $db->simpleStatementFetch('
- SELECT cat.*, cc.libelle AS compte_libelle
- FROM compta_categories AS cat INNER JOIN compta_comptes AS cc
- ON cc.id = cat.compte
- WHERE '.$type.' ORDER BY cat.intitule;', SQLITE3_ASSOC);
- }
-
- public function listMoyensPaiement()
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetchAssocKey('SELECT code, nom FROM compta_moyens_paiement ORDER BY nom COLLATE NOCASE;');
- }
-
- public function getMoyenPaiement($code)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT nom FROM compta_moyens_paiement WHERE code = ?;', false, $code);
- }
-
- protected function _checkFields(&$data)
- {
- if (empty($data['intitule']) || !trim($data['intitule']))
- {
- throw new UserException('L\'intitulé ne peut rester vide.');
- }
-
- $data['intitule'] = trim($data['intitule']);
- $data['description'] = isset($data['description']) ? trim($data['description']) : '';
-
- return true;
- }
-}
-
-?>
DELETED include/class.compta_comptes.php
Index: include/class.compta_comptes.php
==================================================================
--- include/class.compta_comptes.php
+++ include/class.compta_comptes.php
@@ -1,239 +0,0 @@
-exec('BEGIN;');
- $ids = array();
-
- foreach ($plan as $id=>$compte)
- {
- $ids[] = $id;
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $id))
- {
- $db->simpleUpdate('compta_comptes', array(
- 'parent' => $compte['parent'],
- 'libelle' => $compte['nom'],
- 'position' => $compte['position'],
- 'plan_comptable' => 1,
- ), 'id = \''.$db->escapeString($id).'\'');
- }
- else
- {
- $db->simpleInsert('compta_comptes', array(
- 'id' => $id,
- 'parent' => $compte['parent'],
- 'libelle' => $compte['nom'],
- 'position' => $compte['position'],
- 'plan_comptable' => 1,
- ));
- }
- }
-
- $db->exec('DELETE FROM compta_comptes WHERE id NOT IN(\''.implode('\', \'', $ids).'\') AND plan_comptable = 1;');
-
- $db->exec('END;');
-
- return true;
- }
-
- public function add($data)
- {
- $this->_checkFields($data, true);
-
- $db = DB::getInstance();
-
- if (empty($data['id']))
- {
- $new_id = $data['parent'];
- $nb_sous_comptes = $db->simpleQuerySingle('SELECT COUNT(*) FROM compta_comptes WHERE parent = ?;', false, $new_id);
-
- // Pas plus de 26 sous-comptes par compte, parce que l'alphabet s'arrête à 26 lettres
- if ($nb_sous_comptes >= 26)
- {
- throw new UserException('Nombre de sous-comptes maximal atteint pour ce compte parent-ci.');
- }
-
- $new_id .= chr(65+(int)$nb_sous_comptes);
- }
- else
- {
- $new_id = $data['id'];
- }
-
- if (isset($data['position']))
- {
- $position = (int) $data['position'];
- }
- else
- {
- $position = $db->simpleQuerySingle('SELECT position FROM compta_comptes WHERE id = ?;', false, $data['parent']);
- }
-
- $db->simpleInsert('compta_comptes', array(
- 'id' => $new_id,
- 'libelle' => trim($data['libelle']),
- 'parent' => $data['parent'],
- 'plan_comptable' => 0,
- 'position' => (int)$position,
- ));
-
- return $new_id;
- }
-
- public function edit($id, $data)
- {
- $db = DB::getInstance();
-
- // Vérification que l'on peut éditer ce compte
- if ($db->simpleQuerySingle('SELECT plan_comptable FROM compta_comptes WHERE id = ?;', false, $id))
- {
- throw new UserException('Ce compte fait partie du plan comptable et n\'est pas modifiable.');
- }
-
- if (isset($data['position']) && empty($data['position']))
- {
- throw new UserException('Aucune position du compte n\'a été indiquée.');
- }
-
- $this->_checkFields($data);
-
- $update = array(
- 'libelle' => trim($data['libelle']),
- );
-
- if (isset($data['position']))
- {
- $update['position'] = (int) trim($data['position']);
- }
-
- $db->simpleUpdate('compta_comptes', $update, 'id = \''.$db->escapeString(trim($id)).'\'');
-
- return true;
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
-
- // Ne pas supprimer un compte qui est utilisé !
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE compte_debit = ? OR compte_debit = ? LIMIT 1;', false, $id, $id))
- {
- throw new UserException('Ce compte ne peut être supprimé car des opérations comptables y sont liées.');
- }
-
- $db->simpleExec('DELETE FROM compta_comptes WHERE id = ?;', trim($id));
-
- return true;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT * FROM compta_comptes WHERE id = ?;', true, trim($id));
- }
-
- public function getList($parent = 0)
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetchAssocKey('SELECT id, * FROM compta_comptes WHERE parent = ? ORDER BY id;', SQLITE3_ASSOC, $parent);
- }
-
- public function getListAll($parent = 0)
- {
- $db = DB::getInstance();
- return $db->queryFetchAssoc('SELECT id, libelle FROM compta_comptes ORDER BY id;');
- }
-
- public function listTree($parent = 0, $include_children = true)
- {
- $db = DB::getInstance();
-
- if ($include_children)
- {
- $parent = $parent ? 'WHERE parent LIKE \''.$db->escapeString($parent).'%\' ' : '';
- }
- else
- {
- $parent = $parent ? 'WHERE parent = \''.$db->escapeString($parent).'\' ' : 'WHERE parent = 0';
- }
-
- return $db->simpleStatementFetch('SELECT * FROM compta_comptes '.$parent.' ORDER BY id;');
- }
-
- protected function _checkFields(&$data, $force_parent_check = false)
- {
- $db = DB::getInstance();
-
- if (empty($data['libelle']) || !trim($data['libelle']))
- {
- throw new UserException('Le libellé ne peut rester vide.');
- }
-
- $data['libelle'] = trim($data['libelle']);
-
- if (isset($data['id']))
- {
- $force_parent_check = true;
- $data['id'] = trim($data['id']);
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['id']))
- {
- throw new UserException('Le compte numéro '.$data['id'].' existe déjà.');
- }
- }
-
- if (isset($data['parent']) || $force_parent_check)
- {
- if (empty($data['parent']) && !trim($data['parent']))
- {
- throw new UserException('Le compte ne peut pas ne pas avoir de compte parent.');
- }
-
- if (!($id = $db->simpleQuerySingle('SELECT id FROM compta_comptes WHERE id = ?;', false, $data['parent'])))
- {
- throw new UserException('Le compte parent indiqué n\'existe pas.');
- }
-
- $data['parent'] = trim($id);
- }
-
- if (isset($data['id']))
- {
- if (strncmp($data['id'], $data['parent'], strlen($data['parent'])) !== 0)
- {
- throw new UserException('Le compte '.$data['id'].' n\'est pas un sous-compte de '.$data['parent'].'.');
- }
- }
-
- return true;
- }
-
- public function getPositions()
- {
- return array(
- self::ACTIF => 'Actif',
- self::PASSIF => 'Passif',
- self::ACTIF | self::PASSIF => 'Actif et passif',
- self::CHARGE => 'Charge',
- self::PRODUIT => 'Produit',
- self::CHARGE | self::PRODUIT => 'Charge et produit',
- );
- }
-}
-
-?>
DELETED include/class.compta_comptes_bancaires.php
Index: include/class.compta_comptes_bancaires.php
==================================================================
--- include/class.compta_comptes_bancaires.php
+++ include/class.compta_comptes_bancaires.php
@@ -1,129 +0,0 @@
-_checkBankFields($data);
-
- $new_id = parent::add($data);
-
- $db = DB::getInstance();
- $db->simpleInsert('compta_comptes_bancaires', array(
- 'id' => $new_id,
- 'banque' => $data['banque'],
- 'iban' => $data['iban'],
- 'bic' => $data['bic'],
- ));
-
- return $new_id;
- }
-
- public function edit($id, $data)
- {
- $db = DB::getInstance();
-
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_comptes_bancaires WHERE id = ?;', false, $id))
- {
- throw new UserException('Ce compte n\'est pas un compte bancaire.');
- }
-
- $this->_checkBankFields($data);
- $result = parent::edit($id, $data);
-
- if (!$result)
- {
- return $result;
- }
-
- $db->simpleUpdate('compta_comptes_bancaires', array(
- 'banque' => $data['banque'],
- 'iban' => $data['iban'],
- 'bic' => $data['bic'],
- ), 'id = \''.$db->escapeString(trim($id)).'\'');
-
- return true;
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_comptes_bancaires WHERE id = ?;', false, trim($id)))
- {
- throw new UserException('Ce compte n\'est pas un compte bancaire.');
- }
-
- $db->simpleExec('DELETE FROM compta_comptes_bancaires WHERE id = ?;', trim($id));
- $return = parent::delete($id);
-
- return $return;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT * FROM compta_comptes AS c
- INNER JOIN compta_comptes_bancaires AS cc
- ON c.id = cc.id
- WHERE c.id = ?;', true, $id);
- }
-
- public function getList($parent = false)
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetchAssocKey('SELECT c.id AS id, * FROM compta_comptes AS c
- INNER JOIN compta_comptes_bancaires AS cc ON c.id = cc.id
- WHERE c.parent = '.self::NUMERO_PARENT_COMPTES.' ORDER BY c.id;');
- }
-
- protected function _checkBankFields(&$data)
- {
- if (empty($data['banque']) || !trim($data['banque']))
- {
- throw new UserException('Le nom de la banque ne peut rester vide.');
- }
-
- if (empty($data['bic']))
- {
- $data['bic'] = '';
- }
- else
- {
- $data['bic'] = trim(strtoupper($data['bic']));
- $data['bic'] = preg_replace('![^\dA-Z]!', '', $data['bic']);
-
- if (!utils::checkBIC($data['bic']))
- {
- throw new UserException('Code BIC/SWIFT invalide.');
- }
- }
-
- if (empty($data['iban']))
- {
- $data['iban'] = '';
- }
- else
- {
- $data['iban'] = trim(strtoupper($data['iban']));
- $data['iban'] = preg_replace('![^\dA-Z]!', '', $data['iban']);
-
- if (!utils::checkIBAN($data['iban']))
- {
- throw new UserException('Code IBAN invalide.');
- }
- }
-
- return true;
- }
-}
-
-?>
DELETED include/class.compta_exercices.php
Index: include/class.compta_exercices.php
==================================================================
--- include/class.compta_exercices.php
+++ include/class.compta_exercices.php
@@ -1,535 +0,0 @@
-_checkFields($data);
-
- $db = DB::getInstance();
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE
- (debut <= :debut AND fin >= :debut) OR (debut <= :fin AND fin >= :fin);', false,
- array('debut' => $data['debut'], 'fin' => $data['fin'])))
- {
- throw new UserException('La date de début ou de fin se recoupe avec un autre exercice.');
- }
-
- if ($db->querySingle('SELECT 1 FROM compta_exercices WHERE cloture = 0;'))
- {
- throw new UserException('Il n\'est pas possible de créer un nouvel exercice tant qu\'il existe un exercice non-clôturé.');
- }
-
- $db->simpleInsert('compta_exercices', array(
- 'libelle' => trim($data['libelle']),
- 'debut' => $data['debut'],
- 'fin' => $data['fin'],
- ));
-
- return $db->lastInsertRowId();
- }
-
- public function edit($id, $data)
- {
- $db = DB::getInstance();
-
- $this->_checkFields($data);
-
- // Evitons que les exercices se croisent
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE id != :id AND
- ((debut <= :debut AND fin >= :debut) OR (debut <= :fin AND fin >= :fin));', false,
- array('debut' => $data['debut'], 'fin' => $data['fin'], 'id' => (int) $id)))
- {
- throw new UserException('La date de début ou de fin se recoupe avec un autre exercice.');
- }
-
- // On vérifie qu'on ne va pas mettre des opérations en dehors de tout exercice
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE id_exercice = ?
- AND date < ? LIMIT 1;', false, (int)$id, $data['debut']))
- {
- throw new UserException('Des opérations de cet exercice ont une date antérieure à la date de début de l\'exercice.');
- }
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE id_exercice = ?
- AND date > ? LIMIT 1;', false, (int)$id, $data['fin']))
- {
- throw new UserException('Des opérations de cet exercice ont une date postérieure à la date de fin de l\'exercice.');
- }
-
- $db->simpleUpdate('compta_exercices', array(
- 'libelle' => trim($data['libelle']),
- 'debut' => $data['debut'],
- 'fin' => $data['fin'],
- ), 'id = \''.(int)$id.'\'');
-
- return true;
- }
-
- /**
- * Clôturer un exercice et en ouvrir un nouveau
- * Le report à nouveau n'est pas effectué automatiquement par cette fonction, voir doReports pour ça.
- * @param integer $id ID de l'exercice à clôturer
- * @param string $end Date de clôture de l'exercice au format Y-m-d
- * @return integer L'ID du nouvel exercice créé
- */
- public function close($id, $end)
- {
- $db = DB::getInstance();
-
- if (!utils::checkDate($end))
- {
- throw new UserException('Date de fin vide ou invalide.');
- }
-
- $db->exec('BEGIN;');
-
- // Clôture de l'exercice
- $db->simpleUpdate('compta_exercices', array(
- 'cloture' => 1,
- 'fin' => $end,
- ), 'id = \''.(int)$id.'\'');
-
- // Date de début du nouvel exercice : lendemain de la clôture du précédent exercice
- $new_begin = utils::modifyDate($end, '+1 day');
-
- // Date de fin du nouvel exercice : un an après l'ouverture
- $new_end = utils::modifyDate($new_begin, '+1 year');
-
- // Enfin sauf s'il existe déjà des opérations après cette date, auquel cas la date de fin
- // est fixée à la date de la dernière opération, ceci pour ne pas avoir d'opération
- // orpheline d'exercice
- $last = $db->simpleQuerySingle('SELECT date FROM compta_journal WHERE id_exercice = ? AND date >= ? ORDER BY date DESC LIMIT 1;', false, $id, $new_end);
- $new_end = $last ?: $new_end;
-
- // Création du nouvel exercice
- $new_id = $this->add(array(
- 'debut' => $new_begin,
- 'fin' => $new_end,
- 'libelle' => 'Nouvel exercice'
- )
- );
-
- // Ré-attribution des opérations de l'exercice à clôturer qui ne sont pas dans son
- // intervale au nouvel exercice
- $db->simpleExec('UPDATE compta_journal SET id_exercice = ? WHERE id_exercice = ? AND date >= ?;',
- $new_id, $id, $new_begin);
-
- $db->exec('END;');
-
- return $new_id;
- }
-
- /**
- * Créer les reports à nouveau issus de l'exercice $old_id dans le nouvel exercice courant
- * @param integer $old_id ID de l'ancien exercice
- * @param string $date Date Y-m-d donnée aux opérations créées
- * @return boolean true si succès
- */
- public function doReports($old_id, $date)
- {
- $db = DB::getInstance();
-
- $report_crediteur = 110;
- $report_debiteur = 119;
-
- // Récupérer chacun des comptes de bilan et leurs soldes
- $statement = $db->simpleStatement('SELECT id,
- COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit = compte AND id_exercice = :id), 0) AS debit,
- COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit = compte AND id_exercice = :id), 0) AS credit,
- CASE WHEN position & ' . Compta_Comptes::ACTIF . ' THEN debit - credit ELSE credit - debit END AS solde
- FROM compta_comptes
- LEFT JOIN compta_journal ON compta_comptes.id = compta_journal.compte_debit
- OR compta_comptes.id = compta_journal.compte_credit
- WHERE id_exercice = :id AND solde != 0 AND substr(id, 0, 1) <= 5;', array('id' => $old_id));
-
- while ($row = $statement->fetchArray(SQLITE3_ASSOC))
- {
- // Chaque solde de compte est reporté dans le nouvel exercice
- $journal->add(array(
- 'libelle' => 'Report à nouveau',
- 'date' => $date,
- 'montant' => abs($solde),
- // FIXME : de quel compte viens l'argent?!
- 'compte_debit' => ($solde < 0 ? $report_crediteur : $row['compte']),
- 'compte_credit' => ($solde > 0 ? $report_debiteur : $row['compte']),
- 'remarques' => 'Report à nouveau créé automatiquement à la clôture de l\'exercice précédent',
- ));
- }
-
- // Solder tous les comptes de charges et de produits (production du résultat)
- $this->solderResultat($id);
-
- $db->exec('END;');
-
- return $new_id;
- }
-
- /**
- * Solder les comptes de charge et de produits puis les inscrire au résultat du n
- * @param integer $exercice ID de l'exercice à solder
- * @return boolean true en cas de succès
- */
- public function solderResultat($exercice)
- {
- $db = DB::getInstance();
-
- $resultat_crediteur = 120;
- $resultat_debiteur = 129;
-
- $res = $db->prepare('SELECT compte, debit, credit
- FROM
- (SELECT compte_debit AS compte, SUM(montant) AS debit, 0 AS credit
- FROM compta_journal WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_debit
- UNION
- SELECT compte_credit AS compte, 0 AS debit, SUM(montant) AS credit
- FROM compta_journal WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_credit)
- WHERE compte LIKE \'6%\' OR compte LIKE \'7%\'
- ORDER BY base64(compte) COLLATE BINARY ASC;'
- )->execute();
-
- while ($row = $res->fetchArray(SQLITE3_NUM))
- {
- list($compte, $debit, $credit) = $row;
-
- if ($compte[0] == 6) // Charges
- {
- $solde = $debit - $credit;
- $debit = $solde > 0 ? $resultat_crediteur : $resultat_debiteur;
- $credit = $compte;
- }
- else // Produits
- {
- $solde = $credit - $debit;
- $debit = $compte;
- $credit = $solde > 0 ? $resultat_crediteur : $resultat_debiteur;
- }
-
- // Solde nul : rien à inscrire au résultat
- if ($solde == 0)
- {
- continue;
- }
-
- // Enregistrement du résultat
- $journal = new Compta_Journal;
- $journal->add(array(
- 'libelle' => 'Résultat de l\'exercice',
- 'date' => $end,
- 'montant' => abs($solde),
- 'compte_debit' => $debit,
- 'compte_credit' => $credit,
- ));
- }
-
- $res->finalize();
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
-
- // Ne pas supprimer un compte qui est utilisé !
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE id_exercice = ? LIMIT 1;', false, $id))
- {
- throw new UserException('Cet exercice ne peut être supprimé car des opérations comptables y sont liées.');
- }
-
- $db->simpleExec('DELETE FROM compta_exercices WHERE id = ?;', (int)$id);
-
- return true;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT *, strftime(\'%s\', debut) AS debut,
- strftime(\'%s\', fin) AS fin FROM compta_exercices WHERE id = ?;', true, (int)$id);
- }
-
- public function getCurrent()
- {
- $db = DB::getInstance();
- return $db->querySingle('SELECT *, strftime(\'%s\', debut) AS debut, strftime(\'%s\', fin) FROM compta_exercices
- WHERE cloture = 0 LIMIT 1;', true);
- }
-
- public function getCurrentId()
- {
- $db = DB::getInstance();
- return $db->querySingle('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');
- }
-
- public function getList()
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetchAssocKey('SELECT id, *, strftime(\'%s\', debut) AS debut,
- strftime(\'%s\', fin) AS fin,
- (SELECT COUNT(*) FROM compta_journal WHERE id_exercice = compta_exercices.id) AS nb_operations
- FROM compta_exercices ORDER BY fin DESC;', SQLITE3_ASSOC);
- }
-
- protected function _checkFields(&$data)
- {
- $db = DB::getInstance();
-
- if (empty($data['libelle']) || !trim($data['libelle']))
- {
- throw new UserException('Le libellé ne peut rester vide.');
- }
-
- $data['libelle'] = trim($data['libelle']);
-
- if (empty($data['debut']) || !checkdate(substr($data['debut'], 5, 2), substr($data['debut'], 8, 2), substr($data['debut'], 0, 4)))
- {
- throw new UserException('Date de début vide ou invalide.');
- }
-
- if (empty($data['fin']) || !checkdate(substr($data['fin'], 5, 2), substr($data['fin'], 8, 2), substr($data['fin'], 0, 4)))
- {
- throw new UserException('Date de fin vide ou invalide.');
- }
-
- return true;
- }
-
-
- public function getJournal($exercice)
- {
- $db = DB::getInstance();
- $query = 'SELECT *, strftime(\'%s\', date) AS date FROM compta_journal
- WHERE id_exercice = '.(int)$exercice.' ORDER BY date, id;';
- return $db->simpleStatementFetch($query);
- }
-
- public function getGrandLivre($exercice)
- {
- $db = DB::getInstance();
- $livre = array('classes' => array(), 'debit' => 0.0, 'credit' => 0.0);
-
- $res = $db->prepare('SELECT compte FROM
- (SELECT compte_debit AS compte FROM compta_journal
- WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_debit
- UNION
- SELECT compte_credit AS compte FROM compta_journal
- WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_credit)
- ORDER BY base64(compte) COLLATE BINARY ASC;'
- )->execute();
-
- while ($row = $res->fetchArray(SQLITE3_NUM))
- {
- $compte = $row[0];
- $classe = substr($compte, 0, 1);
- $parent = substr($compte, 0, 2);
-
- if (!array_key_exists($classe, $livre['classes']))
- {
- $livre['classes'][$classe] = array();
- }
-
- if (!array_key_exists($parent, $livre['classes'][$classe]))
- {
- $livre['classes'][$classe][$parent] = array(
- 'total' => 0.0,
- 'comptes' => array(),
- );
- }
-
- $livre['classes'][$classe][$parent]['comptes'][$compte] = array('debit' => 0.0, 'credit' => 0.0, 'journal' => array());
-
- $livre['classes'][$classe][$parent]['comptes'][$compte]['journal'] = $db->simpleStatementFetch(
- 'SELECT *, strftime(\'%s\', date) AS date FROM (
- SELECT * FROM compta_journal WHERE compte_debit = :compte AND id_exercice = '.(int)$exercice.'
- UNION
- SELECT * FROM compta_journal WHERE compte_credit = :compte AND id_exercice = '.(int)$exercice.'
- )
- ORDER BY date, numero_piece, id;', SQLITE3_ASSOC, array('compte' => $compte));
-
- $debit = (float) $db->simpleQuerySingle(
- 'SELECT SUM(montant) FROM compta_journal WHERE compte_debit = ? AND id_exercice = '.(int)$exercice.';',
- false, $compte);
-
- $credit = (float) $db->simpleQuerySingle(
- 'SELECT SUM(montant) FROM compta_journal WHERE compte_credit = ? AND id_exercice = '.(int)$exercice.';',
- false, $compte);
-
- $livre['classes'][$classe][$parent]['comptes'][$compte]['debit'] = $debit;
- $livre['classes'][$classe][$parent]['comptes'][$compte]['credit'] = $credit;
-
- $livre['classes'][$classe][$parent]['total'] += $debit;
- $livre['classes'][$classe][$parent]['total'] -= $credit;
-
- $livre['debit'] += $debit;
- $livre['credit'] += $credit;
- }
-
- $res->finalize();
-
- return $livre;
- }
-
- public function getCompteResultat($exercice)
- {
- $db = DB::getInstance();
-
- $charges = array('comptes' => array(), 'total' => 0.0);
- $produits = array('comptes' => array(), 'total' => 0.0);
- $resultat = 0.0;
-
- $res = $db->prepare('SELECT compte, debit, credit
- FROM
- (SELECT compte_debit AS compte, SUM(montant) AS debit, 0 AS credit
- FROM compta_journal WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_debit
- UNION
- SELECT compte_credit AS compte, 0 AS debit, SUM(montant) AS credit
- FROM compta_journal WHERE id_exercice = '.(int)$exercice.' GROUP BY compte_credit)
- WHERE compte LIKE \'6%\' OR compte LIKE \'7%\'
- ORDER BY base64(compte) COLLATE BINARY ASC;'
- )->execute();
-
- while ($row = $res->fetchArray(SQLITE3_NUM))
- {
- list($compte, $debit, $credit) = $row;
- $classe = substr($compte, 0, 1);
- $parent = substr($compte, 0, 2);
-
- if ($classe == 6)
- {
- if (!isset($charges['comptes'][$parent]))
- {
- $charges['comptes'][$parent] = array('comptes' => array(), 'solde' => 0.0);
- }
-
- $solde = $debit - $credit;
-
- $charges['comptes'][$parent]['comptes'][$compte] = $solde;
- $charges['total'] += $solde;
- $charges['comptes'][$parent]['solde'] += $solde;
- }
- elseif ($classe == 7)
- {
- if (!isset($produits['comptes'][$parent]))
- {
- $produits['comptes'][$parent] = array('comptes' => array(), 'solde' => 0.0);
- }
-
- $solde = $credit - $debit;
-
- $produits['comptes'][$parent]['comptes'][$compte] = $solde;
- $produits['total'] += $solde;
- $produits['comptes'][$parent]['solde'] += $solde;
- }
- }
-
- $res->finalize();
-
- $resultat = $produits['total'] - $charges['total'];
-
- return array('charges' => $charges, 'produits' => $produits, 'resultat' => $resultat);
- }
-
- /**
- * Calculer le bilan comptable pour l'exercice $exercice
- * @param integer $exercice ID de l'exercice dont il faut produire le bilan
- * @param boolean $resultat true s'il faut calculer le résultat de l'exercice (utile pour un exercice en cours)
- * @return array Un tableau multi-dimensionnel avec deux clés : actif et passif
- */
- public function getBilan($exercice, $resultat = true)
- {
- $db = DB::getInstance();
-
- $include = array(Compta_Comptes::ACTIF, Compta_Comptes::PASSIF,
- Compta_Comptes::PASSIF | Compta_Comptes::ACTIF);
-
- $actif = array('comptes' => array(), 'total' => 0.0);
- $passif = array('comptes' => array(), 'total' => 0.0);
-
- if ($resultat)
- {
- $resultat = $this->getCompteResultat($exercice);
-
- if ($resultat['resultat'] > 0)
- {
- $passif['comptes']['12'] = array(
- 'comptes' => array('120' => $resultat['resultat']),
- 'solde' => $resultat['resultat']
- );
-
- $passif['total'] = $resultat['resultat'];
- }
- else
- {
- $passif['comptes']['12'] = array(
- 'comptes' => array('129' => $resultat['resultat']),
- 'solde' => $resultat['resultat']
- );
-
- $passif['total'] = $resultat['resultat'];
- }
- }
-
- // Y'a sûrement moyen d'améliorer tout ça pour que le maximum de travail
- // soit fait au niveau du SQL, mais pour le moment ça marche
- $res = $db->prepare('SELECT compte, debit, credit, (SELECT position FROM compta_comptes WHERE id = compte) AS position
- FROM
- (SELECT compte_debit AS compte, SUM(montant) AS debit, NULL AS credit
- FROM compta_journal WHERE id_exercice = 1 GROUP BY compte_debit
- UNION
- SELECT compte_credit AS compte, NULL AS debit, SUM(montant) AS credit
- FROM compta_journal WHERE id_exercice = 1 GROUP BY compte_credit)
- WHERE compte IN (SELECT id FROM compta_comptes WHERE position IN ('.implode(', ', $include).'))
- ORDER BY base64(compte) COLLATE BINARY ASC;'
- )->execute();
-
- while ($row = $res->fetchArray(SQLITE3_NUM))
- {
- list($compte, $debit, $credit, $position) = $row;
- $parent = substr($compte, 0, 2);
-
- if ($position & Compta_Comptes::ACTIF)
- {
- if (!isset($actif['comptes'][$parent]))
- {
- $actif['comptes'][$parent] = array('comptes' => array(), 'solde' => 0.0);
- }
-
- $solde = $debit - $credit;
-
- if (!isset($actif['comptes'][$parent]['comptes'][$compte]))
- {
- $actif['comptes'][$parent]['comptes'][$compte] = 0.0;
- }
-
- $actif['comptes'][$parent]['comptes'][$compte] += $solde;
- $actif['total'] += $solde;
- $actif['comptes'][$parent]['solde'] += $solde;
- }
-
- if ($position & Compta_Comptes::PASSIF)
- {
- if (!isset($passif['comptes'][$parent]))
- {
- $passif['comptes'][$parent] = array('comptes' => array(), 'solde' => 0.0);
- }
-
- $solde = $credit - $debit;
-
- if (!isset($passif['comptes'][$parent]['comptes'][$compte]))
- {
- $passif['comptes'][$parent]['comptes'][$compte] = 0.0;
- }
-
- $passif['comptes'][$parent]['comptes'][$compte] += $solde;
- $passif['total'] += $solde;
- $passif['comptes'][$parent]['solde'] += $solde;
- }
- }
-
- $res->finalize();
-
- return array('actif' => $actif, 'passif' => $passif);
- }
-}
-
-?>
DELETED include/class.compta_import.php
Index: include/class.compta_import.php
==================================================================
--- include/class.compta_import.php
+++ include/class.compta_import.php
@@ -1,232 +0,0 @@
-prepare('SELECT
- journal.id,
- strftime(\'%d/%m/%Y\', date) AS date,
- (CASE cat.type WHEN 1 THEN \'Recette\' WHEN -1 THEN \'Dépense\' ELSE \'Autre\' END) AS type,
- (CASE cat.intitule WHEN NULL THEN \'\' ELSE cat.intitule END) AS cat,
- journal.libelle,
- montant,
- compte_debit,
- debit.libelle AS libelle_debit,
- compte_credit,
- credit.libelle AS libelle_credit,
- (CASE moyen_paiement WHEN NULL THEN \'\' ELSE moyen.nom END) AS moyen,
- numero_cheque,
- numero_piece,
- remarques
- FROM compta_journal AS journal
- LEFT JOIN compta_categories AS cat ON cat.id = journal.id_categorie
- LEFT JOIN compta_comptes AS debit ON debit.id = journal.compte_debit
- LEFT JOIN compta_comptes AS credit ON credit.id = journal.compte_credit
- LEFT JOIN compta_moyens_paiement AS moyen ON moyen.code = journal.moyen_paiement
- WHERE id_exercice = '.(int)$exercice.'
- ORDER BY journal.date;
- ')->execute();
-
- $fp = fopen('php://output', 'w');
-
- fputcsv($fp, $header);
-
- while ($row = $res->fetchArray(SQLITE3_ASSOC))
- {
- fputcsv($fp, $row);
- }
-
- fclose($fp);
-
- return true;
- }
-
- public function fromCitizen($path)
- {
- if (!file_exists($path) || !is_readable($path))
- {
- throw new \RuntimeException('Fichier inconnu : '.$path);
- }
-
- $fp = fopen($path, 'r');
-
- if (!$fp)
- {
- return false;
- }
-
- $db = DB::getInstance();
- $db->exec('BEGIN;');
- $comptes = new Compta_Comptes;
- $banques = new Compta_Comptes_Bancaires;
- $cats = new Compta_Categories;
- $journal = new Compta_Journal;
-
- $columns = array();
- $liste_comptes = $db->simpleStatementFetchAssoc('SELECT id, id FROM compta_comptes;');
- $liste_cats = $db->simpleStatementFetchAssoc('SELECT intitule, id FROM compta_categories;');
- $liste_moyens = $cats->listMoyensPaiement();
-
- $get_compte = function ($compte, $intitule) use (&$liste_comptes, &$comptes, &$banques)
- {
- if (substr($compte, 0, 2) == '51')
- {
- $compte = '512' . substr($compte, -1);
- }
-
- // Création comptes
- if (!array_key_exists($compte, $liste_comptes))
- {
- if (substr($compte, 0, 3) == '512')
- {
- $liste_comptes[$compte] = $banques->add(array(
- 'libelle' => $intitule,
- 'banque' => 'Inconnue',
- ));
- }
- else
- {
- $liste_comptes[$compte] = $comptes->add(array(
- 'id' => $compte,
- 'libelle' => $intitule,
- 'parent' => substr($compte, 0, -1)
- ));
- }
- }
-
- return $compte;
- };
-
- $col = function($column) use (&$row, &$columns)
- {
- if (!isset($columns[$column]))
- return null;
-
- if (!isset($row[$columns[$column]]))
- return null;
-
- return $row[$columns[$column]];
- };
-
- while (!feof($fp))
- {
- $row = fgetcsv($fp, 4096, ';');
-
- if (empty($row))
- {
- continue;
- }
-
- if (empty($columns))
- {
- $columns = $row;
- $columns = array_flip($columns);
- continue;
- }
-
- $date = explode('/', $col('Date'));
- $date = $date[2] . '-' . $date[1] . '-' . $date[0];
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_exercices
- WHERE (? < debut || ? > fin) AND cloture = 0;', false, $date, $date))
- {
- $db->exec('ROLLBACK;');
- throw new UserException('Impossible d\'importer dans cet exercice : une opération est datée au '.$col('Date').', en dehors de l\'exercice.');
- }
-
- if ($db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE ? < debut AND cloture = 0;', false, $date))
- {
- $db->exec('ROLLBACK;');
- throw new UserException('Une opération est datée du '.$col('Date').', soit avant la date de début de l\'exercice.');
- }
-
- $debit = $get_compte($col('Compte débité - Numéro'), $col('Compte débité - Intitulé'));
- $credit = $get_compte($col('Compte crédité - Numéro'), $col('Compte crédité - Intitulé'));
-
- $cat = $col('Rubrique');
- $moyen = strtoupper(substr($col('Moyen de paiement'), 0, 2));
-
- if (!$moyen || !array_key_exists($moyen, $liste_moyens))
- {
- $moyen = false;
- $cat = false;
- }
-
- if ($cat && !array_key_exists($cat, $liste_cats))
- {
- if ($col('Nature') == 'Recette')
- {
- $type = $cats::RECETTES;
- $compte = $credit;
- }
- elseif ($col('Nature') == 'Dépense')
- {
- $type = $cats::DEPENSES;
- $compte = $debit;
- }
- else
- {
- $type = $cats::AUTRES;
- $cat = false;
- }
-
- if ($type != $cats::AUTRES)
- {
- $liste_cats[$cat] = $cats->add(array(
- 'intitule' => $cat,
- 'type' => $type,
- 'compte' => $compte
- ));
- }
- }
-
- $data = array(
- 'libelle' => $col('Libellé'),
- 'montant' => $col('Montant'),
- 'date' => $date,
- 'compte_credit' => $credit,
- 'compte_debit' => $debit,
- 'numero_piece' => $col('Numéro de pièce'),
- 'remarques' => $col('Remarques'),
- );
-
- if ($cat)
- {
- $data['moyen_paiement'] = $moyen;
- $data['numero_cheque'] = $col('Numéro de chèque');
- $data['id_categorie'] = $liste_cats[$cat];
- }
-
- $journal->add($data);
- }
-
- $db->exec('END;');
-
- fclose($fp);
- return true;
- }
-}
-
-?>
DELETED include/class.compta_journal.php
Index: include/class.compta_journal.php
==================================================================
--- include/class.compta_journal.php
+++ include/class.compta_journal.php
@@ -1,296 +0,0 @@
-querySingle('SELECT id FROM compta_exercices WHERE cloture = 0 LIMIT 1;');
-
- if (!$id)
- {
- throw new UserException('Aucun exercice en cours.');
- }
-
- return $id;
- }
-
- public function checkExercice()
- {
- return $this->_getCurrentExercice();
- }
-
- protected function _checkOpenExercice($id)
- {
- if (is_null($id))
- return true;
-
- $db = DB::getInstance();
- $id = $db->simpleQuerySingle('SELECT id FROM compta_exercices
- WHERE cloture = 0 AND id = ? LIMIT 1;', false, (int)$id);
-
- if ($id)
- return true;
-
- return false;
- }
-
- public function getSolde($id_compte, $inclure_sous_comptes = false)
- {
- $db = DB::getInstance();
- $exercice = $this->_getCurrentExercice();
- $compte = $inclure_sous_comptes
- ? 'LIKE \'' . $db->escapeString(trim($id_compte)) . '%\''
- : '= \'' . $db->escapeString(trim($id_compte)) . '\'';
-
- $debit = 'COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_debit '.$compte.' AND id_exercice = '.(int)$exercice.'), 0)';
- $credit = 'COALESCE((SELECT SUM(montant) FROM compta_journal WHERE compte_credit '.$compte.' AND id_exercice = '.(int)$exercice.'), 0)';
-
- // L'actif augmente au débit, le passif au crédit
- $position = $db->simpleQuerySingle('SELECT position FROM compta_comptes WHERE id = ?;', false, $id_compte);
-
- if (($position & Compta_Comptes::ACTIF) || ($position & Compta_Comptes::CHARGE))
- {
- $query = $debit . ' - ' . $credit;
- }
- else
- {
- $query = $credit . ' - ' . $debit;
- }
-
- return $db->querySingle('SELECT ' . $query . ';');
- }
-
- public function getJournalCompte($compte, $inclure_sous_comptes = false)
- {
- $db = DB::getInstance();
-
- $position = $db->simpleQuerySingle('SELECT position FROM compta_comptes WHERE id = ?;', false, $compte);
-
- $exercice = $this->_getCurrentExercice();
- $compte = $inclure_sous_comptes
- ? 'LIKE \'' . $db->escapeString(trim($compte)) . '%\''
- : '= \'' . $db->escapeString(trim($compte)) . '\'';
-
- // L'actif et les charges augmentent au débit, le passif et les produits au crédit
- if (($position & Compta_Comptes::ACTIF) || ($position & Compta_Comptes::CHARGE))
- {
- $d = '';
- $c = '-';
- }
- else
- {
- $d = '-';
- $c = '';
- }
-
- $query = 'SELECT *, strftime(\'%s\', date) AS date,
- running_sum(CASE WHEN compte_debit '.$compte.' THEN '.$d.'montant ELSE '.$c.'montant END) AS solde
- FROM compta_journal WHERE (compte_debit '.$compte.' OR compte_credit '.$compte.') AND id_exercice = '.(int)$exercice.'
- ORDER BY date ASC;';
-
- // Obligatoire pour bien taper dans l'index de la date
- // sinon running_sum est appelé 2 fois et ça marche pas du coup
- // FIXME mettre ça ailleurs pour que ça soit appelé moins souvent
- $db->exec('ANALYZE compta_journal;');
-
- $db->resetRunningSum();
- return $db->simpleStatementFetch($query);
- }
-
- public function add($data)
- {
- $this->_checkFields($data);
-
- $db = DB::getInstance();
-
- $data['id_exercice'] = $this->_getCurrentExercice();
-
- $db->simpleInsert('compta_journal', $data);
- $id = $db->lastInsertRowId();
-
- return $id;
- }
-
- public function edit($id, $data)
- {
- $db = DB::getInstance();
-
- // Vérification que l'on peut éditer cette opération
- if (!$this->_checkOpenExercice($db->simpleQuerySingle('SELECT id_exercice FROM compta_journal WHERE id = ?;', false, $id)))
- {
- throw new UserException('Cette opération fait partie d\'un exercice qui a été clôturé.');
- }
-
- $this->_checkFields($data);
-
- $db->simpleUpdate('compta_journal', $data,
- 'id = \''.trim($id).'\'');
-
- return true;
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
-
- // Vérification que l'on peut éditer cette opération
- if (!$this->_checkOpenExercice($db->simpleQuerySingle('SELECT id_exercice FROM compta_journal WHERE id = ?;', false, $id)))
- {
- throw new UserException('Cette opération fait partie d\'un exercice qui a été clôturé.');
- }
-
- $db->simpleExec('DELETE FROM compta_journal WHERE id = ?;', (int)$id);
-
- return true;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT *, strftime(\'%s\', date) AS date FROM compta_journal WHERE id = ?;', true, $id);
- }
-
- protected function _checkFields(&$data)
- {
- $db = DB::getInstance();
-
- if (empty($data['libelle']) || !trim($data['libelle']))
- {
- throw new UserException('Le libellé ne peut rester vide.');
- }
-
- $data['libelle'] = trim($data['libelle']);
-
- if (!empty($data['moyen_paiement'])
- && !$db->simpleQuerySingle('SELECT 1 FROM compta_moyens_paiement WHERE code = ?;', false, $data['moyen_paiement']))
- {
- throw new UserException('Moyen de paiement invalide.');
- }
-
- if (empty($data['date']) || !utils::checkDate($data['date']))
- {
- throw new UserException('Date vide ou invalide.');
- }
-
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_exercices WHERE cloture = 0
- AND debut <= :date AND fin >= :date;', false, array('date' => $data['date'])))
- {
- throw new UserException('La date ne correspond pas à l\'exercice en cours.');
- }
-
- if (empty($data['moyen_paiement']))
- {
- $data['moyen_paiement'] = null;
- $data['numero_cheque'] = null;
- }
- else
- {
- $data['moyen_paiement'] = strtoupper($data['moyen_paiement']);
-
- if ($data['moyen_paiement'] != 'CH')
- {
- $data['numero_cheque'] = null;
- }
- }
-
- $data['montant'] = str_replace(',', '.', $data['montant']);
- $data['montant'] = (float)$data['montant'];
-
- if ($data['montant'] <= 0)
- {
- throw new UserException('Le montant ne peut être égal ou inférieur à zéro.');
- }
-
- foreach (array('remarques', 'numero_piece', 'numero_cheque') as $champ)
- {
- if (empty($data[$champ]) || !trim($data[$champ]))
- {
- $data[$champ] = '';
- }
- else
- {
- $data[$champ] = trim($data[$champ]);
- }
- }
-
- if (empty($data['compte_debit']) ||
- !$db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['compte_debit']))
- {
- throw new UserException('Compte débité inconnu.');
- }
-
- if (empty($data['compte_credit']) ||
- !$db->simpleQuerySingle('SELECT 1 FROM compta_comptes WHERE id = ?;', false, $data['compte_credit']))
- {
- throw new UserException('Compte crédité inconnu.');
- }
-
- $data['compte_credit'] = strtoupper(trim($data['compte_credit']));
- $data['compte_debit'] = strtoupper(trim($data['compte_debit']));
-
- if (isset($data['id_categorie']))
- {
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_categories WHERE id = ?;', false, (int)$data['id_categorie']))
- {
- throw new UserException('Catégorie inconnue.');
- }
-
- $data['id_categorie'] = (int)$data['id_categorie'];
- }
- else
- {
- $data['id_categorie'] = NULL;
- }
-
- if (isset($data['id_auteur']))
- {
- $data['id_auteur'] = (int)$data['id_auteur'];
- }
-
- return true;
- }
-
- public function getListForCategory($type = null, $cat = null)
- {
- $db = DB::getInstance();
- $exercice = $this->_getCurrentExercice();
-
- $query = 'SELECT compta_journal.*, strftime(\'%s\', compta_journal.date) AS date ';
-
- if (is_null($cat) && !is_null($type))
- {
- $query.= ', compta_categories.intitule AS categorie
- FROM compta_journal LEFT JOIN compta_categories
- ON compta_journal.id_categorie = compta_categories.id ';
- }
- else
- {
- $query.= ' FROM compta_journal ';
- }
-
- $query .= ' WHERE ';
-
- if (!is_null($cat))
- {
- $query .= 'id_categorie = ' . (int)$cat;
- }
- elseif (is_null($type) && is_null($cat))
- {
- $query .= 'id_categorie IS NULL';
- }
- else
- {
- $query.= 'id_categorie IN (SELECT id FROM compta_categories WHERE type = '.(int)$type.')';
- }
-
- $query .= ' AND id_exercice = ' . (int)$exercice;
- $query .= ' ORDER BY date;';
-
- return $db->simpleStatementFetch($query);
- }
-}
-
-?>
DELETED include/class.compta_stats.php
Index: include/class.compta_stats.php
==================================================================
--- include/class.compta_stats.php
+++ include/class.compta_stats.php
@@ -1,102 +0,0 @@
-getStats('SELECT strftime(\'%Y%m\', date) AS date,
- SUM(montant) FROM compta_journal
- WHERE id_categorie IN (SELECT id FROM compta_categories WHERE type = '.$type.')
- AND id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0)
- GROUP BY strftime(\'%Y-%m\', date) ORDER BY date;');
- }
-
- public function recettes()
- {
- return $this->_byType(-1);
- }
-
- public function depenses()
- {
- return $this->_byType(1);
- }
-
- public function soldeCompte($compte, $augmente = 'debit', $diminue = 'credit')
- {
- $db = DB::getInstance();
-
- if (strpos($compte, '%') !== false)
- {
- $compte = 'LIKE \''. $db->escapeString($compte) . '\'';
- }
- else
- {
- $compte = '= \''. $db->escapeString($compte) . '\'';
- }
-
- $stats = $this->getStats('SELECT strftime(\'%Y%m\', date) AS date,
- (COALESCE((SELECT SUM(montant) FROM compta_journal
- WHERE compte_'.$augmente.' '.$compte.' AND id_exercice = cj.id_exercice
- AND date >= strftime(\'%Y-%m-01\', cj.date)
- AND date <= strftime(\'%Y-%m-31\', cj.date)), 0)
- - COALESCE((SELECT SUM(montant) FROM compta_journal
- WHERE compte_'.$diminue.' '.$compte.' AND id_exercice = cj.id_exercice
- AND date >= strftime(\'%Y-%m-01\', cj.date)
- AND date <= strftime(\'%Y-%m-31\', cj.date)), 0)
- ) AS solde
- FROM compta_journal AS cj
- WHERE (compte_debit '.$compte.' OR compte_credit '.$compte.')
- AND id_exercice = (SELECT id FROM compta_exercices WHERE cloture = 0)
- GROUP BY strftime(\'%Y-%m\', date) ORDER BY date;');
-
- $c = 0;
- foreach ($stats as $k=>$v)
- {
- $c += $v;
- $stats[$k] = $c;
- }
-
- return $stats;
- }
-
- public function getStats($query)
- {
- $db = DB::getInstance();
-
- $data = $db->simpleStatementFetchAssoc($query);
-
- $e = $db->querySingle('SELECT *, strftime(\'%s\', debut) AS debut,
- strftime(\'%s\', fin) AS fin FROM compta_exercices WHERE cloture = 0;', true);
-
- $y = date('Y', $e['debut']);
- $m = date('m', $e['debut']);
- $max = date('Ym', $e['fin']);
-
- while ($y . $m <= $max)
- {
- if (!isset($data[$y . $m]))
- {
- $data[$y . $m] = 0;
- }
-
- if ($m == 12)
- {
- $m = '01';
- $y++;
- }
- else
- {
- $m++;
- $m = str_pad((int)$m, 2, '0', STR_PAD_LEFT);
- }
- }
-
- ksort($data);
-
- return $data;
- }
-}
-
-?>
DELETED include/class.config.php
Index: include/class.config.php
==================================================================
--- include/class.config.php
+++ include/class.config.php
@@ -1,291 +0,0 @@
-fields_types = array(
- 'nom_asso' => $string,
- 'adresse_asso' => $string,
- 'email_asso' => $string,
- 'site_asso' => $string,
-
- 'monnaie' => $string,
- 'pays' => $string,
-
- 'champs_membres' => $object,
-
- 'email_envoi_automatique'=> $string,
-
- 'categorie_membres' => $int,
-
- 'categorie_dons' => $int,
- 'categorie_cotisations' => $int,
-
- 'accueil_wiki' => $string,
- 'accueil_connexion' => $string,
-
- 'frequence_sauvegardes' => $int,
- 'nombre_sauvegardes' => $int,
-
- 'version' => $string,
- );
-
- $db = DB::getInstance();
-
- $this->config = $db->simpleStatementFetchAssoc('SELECT cle, valeur FROM config ORDER BY cle;');
-
- foreach ($this->config as $key=>&$value)
- {
- if (!array_key_exists($key, $this->fields_types))
- {
- // Ancienne clé de config qui n'est plus utilisée
- continue;
- }
-
- if (is_array($this->fields_types[$key]))
- {
- $value = explode(',', $value);
- }
- elseif ($key == 'champs_membres')
- {
- $value = new Champs_Membres((string)$value);
- }
- else
- {
- settype($value, gettype($this->fields_types[$key]));
- }
- }
- }
-
- public function __destruct()
- {
- if (!empty($this->modified))
- {
- //echo '
Il y a des champs modifiés non sauvés dans '.__CLASS__.' !
';
- }
- }
-
- public function save()
- {
- if (empty($this->modified))
- return true;
-
- $values = array();
-
- $db = DB::getInstance();
- $db->exec('BEGIN;');
-
- foreach ($this->modified as $key=>$modified)
- {
- $value = $this->config[$key];
-
- if (is_array($value))
- {
- $value = implode(',', $value);
- }
- elseif (is_object($value))
- {
- $value = (string) $value;
- }
-
- $db->simpleExec('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
- $key, $value);
- }
-
- $db->exec('END;');
-
- $this->modified = array();
-
- return true;
- }
-
- public function get($key)
- {
- if (!array_key_exists($key, $this->fields_types))
- {
- throw new \OutOfBoundsException('Ce champ est inconnu.');
- }
-
- if (!array_key_exists($key, $this->config))
- {
- return null;
- }
-
- return $this->config[$key];
- }
-
- public function getVersion()
- {
- if (!array_key_exists('version', $this->config))
- {
- return '0';
- }
-
- return $this->config['version'];
- }
-
- public function setVersion($version)
- {
- $this->config['version'] = $version;
-
- $db = DB::getInstance();
- $db->simpleExec('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
- 'version', $version);
-
- return true;
- }
-
- public function set($key, $value)
- {
- if (!array_key_exists($key, $this->fields_types))
- {
- throw new \OutOfBoundsException('Ce champ est inconnu.');
- }
-
- if (is_array($this->fields_types[$key]))
- {
- $value = !empty($value) ? (array) $value : array();
- }
- elseif (is_int($this->fields_types[$key]))
- {
- $value = (int) $value;
- }
- elseif (is_float($this->fields_types[$key]))
- {
- $value = (float) $value;
- }
- elseif (is_bool($this->fields_types[$key]))
- {
- $value = (bool) $value;
- }
- elseif (is_string($this->fields_types[$key]))
- {
- $value = (string) $value;
- }
-
- switch ($key)
- {
- case 'nom_asso':
- {
- if (!trim($value))
- {
- throw new UserException('Le nom de l\'association ne peut rester vide.');
- }
- break;
- }
- case 'accueil_wiki':
- case 'accueil_connexion':
- {
- if (!trim($value))
- {
- $key = str_replace('accueil_', '', $key);
- throw new UserException('Le nom de la page d\'accueil ' . $key . ' ne peut rester vide.');
- }
- break;
- }
- case 'email_asso':
- case 'email_envoi_automatique':
- {
- if (!filter_var($value, FILTER_VALIDATE_EMAIL))
- {
- throw new UserException('Adresse e-mail invalide.');
- }
- break;
- }
- case 'champs_membres':
- {
- if (!($value instanceOf Champs_Membres))
- {
- throw new \UnexpectedValueException('$value doit être de type Champs_Membres');
- }
- break;
- }
- case 'categorie_cotisations':
- case 'categorie_dons':
- {
- return false;
- $db = DB::getInstance();
- if (!$db->simpleQuerySingle('SELECT 1 FROM compta_categories WHERE id = ?;', false, $value))
- {
- throw new UserException('Champ '.$key.' : La catégorie comptable numéro \''.$value.'\' ne semble pas exister.');
- }
- break;
- }
- case 'categorie_membres':
- {
- $db = DB::getInstance();
- if (!$db->simpleQuerySingle('SELECT 1 FROM membres_categories WHERE id = ?;', false, $value))
- {
- throw new UserException('La catégorie de membres par défaut numéro \''.$value.'\' ne semble pas exister.');
- }
- break;
- }
- case 'monnaie':
- {
- if (!trim($value))
- {
- throw new UserException('La monnaie doit être renseignée.');
- }
-
- break;
- }
- case 'pays':
- {
- if (!trim($value) || !utils::getCountryName($value))
- {
- throw new UserException('Le pays renseigné est invalide.');
- }
-
- break;
- }
- default:
- break;
- }
-
- if (!isset($this->config[$key]) || $value !== $this->config[$key])
- {
- $this->config[$key] = $value;
- $this->modified[$key] = true;
- }
-
- return true;
- }
-
- public function getFieldsTypes()
- {
- return $this->fields_types;
- }
-
- public function getConfig()
- {
- return $this->config;
- }
-}
-
-?>
DELETED include/class.db.php
Index: include/class.db.php
==================================================================
--- include/class.db.php
+++ include/class.db.php
@@ -1,435 +0,0 @@
-instruction = $instruction;
- }
-
- public function __toString()
- {
- return $this->instruction;
- }
-}
-
-class DB extends \SQLite3
-{
- static protected $_instance = null;
-
- protected $_running_sum = 0.0;
-
- static public function getInstance($create = false)
- {
- return self::$_instance ?: self::$_instance = new DB($create);
- }
-
- private function __clone()
- {
- }
-
- public function __construct($create = false)
- {
- $flags = SQLITE3_OPEN_READWRITE;
-
- if ($create)
- {
- $flags |= SQLITE3_OPEN_CREATE;
- }
-
- parent::__construct(GARRADIN_DB_FILE, $flags);
-
- // Activer les contraintes des foreign keys
- $this->exec('PRAGMA foreign_keys = ON;');
-
- $this->createFunction('transliterate_to_ascii', array('Garradin\utils', 'transliterateToAscii'));
- $this->createFunction('base64', 'base64_encode');
- $this->createFunction('rank', array($this, 'sql_rank'));
- $this->createFunction('running_sum', array($this, 'sql_running_sum'));
- }
-
- public function sql_running_sum($data)
- {
- // Why is this function called two times for the first row?!
- // Dunno but here is a workaround
- if (is_null($this->_running_sum))
- {
- $this->_running_sum = 0.0;
- return $this->_running_sum;
- }
-
- $this->_running_sum += $data;
- return $this->_running_sum;
- }
-
- public function resetRunningSum()
- {
- $this->_running_sum = null;
- }
-
- public function sql_rank($aMatchInfo)
- {
- $iSize = 4; // byte size
- $iPhrase = (int) 0; // Current phrase //
- $score = (double)0.0; // Value to return //
-
- /* Check that the number of arguments passed to this function is correct.
- ** If not, jump to wrong_number_args. Set aMatchinfo to point to the array
- ** of unsigned integer values returned by FTS function matchinfo. Set
- ** nPhrase to contain the number of reportable phrases in the users full-text
- ** query, and nCol to the number of columns in the table.
- */
- $aMatchInfo = (string) func_get_arg(0);
- $nPhrase = ord(substr($aMatchInfo, 0, $iSize));
- $nCol = ord(substr($aMatchInfo, $iSize, $iSize));
-
- if (func_num_args() > (1 + $nCol))
- {
- throw new \Exception("Invalid number of arguments : ".$nCol);
- }
-
- // Iterate through each phrase in the users query. //
- for ($iPhrase = 0; $iPhrase < $nPhrase; $iPhrase++)
- {
- $iCol = (int) 0; // Current column //
-
- /* Now iterate through each column in the users query. For each column,
- ** increment the relevancy score by:
- **
- ** ( / ) *
- **
- ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So
- ** the hit count and global hit counts for each column are found in
- ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively.
- */
- $aPhraseinfo = substr($aMatchInfo, (2 + $iPhrase * $nCol * 3) * $iSize);
-
- for ($iCol = 0; $iCol < $nCol; $iCol++)
- {
- $nHitCount = ord(substr($aPhraseinfo, 3 * $iCol * $iSize, $iSize));
- $nGlobalHitCount = ord(substr($aPhraseinfo, (3 * $iCol + 1) * $iSize, $iSize));
- $weight = ($iCol < func_num_args() - 1) ? (double) func_get_arg($iCol + 1) : 0;
-
- if ($nHitCount > 0)
- {
- $score += ((double)$nHitCount / (double)$nGlobalHitCount) * $weight;
- }
- }
- }
-
- return $score;
- }
-
- public function escape($str)
- {
- return $this->escapeString($str);
- }
-
- public function e($str)
- {
- return $this->escapeString($str);
- }
-
- protected function _getArgType($arg, $name = '')
- {
- if (is_float($arg))
- return SQLITE3_FLOAT;
- elseif (is_int($arg))
- return SQLITE3_INTEGER;
- elseif (is_bool($arg))
- return SQLITE3_INTEGER;
- elseif (is_null($arg))
- return SQLITE3_NULL;
- elseif (is_string($arg))
- return SQLITE3_TEXT;
- elseif (is_object($arg) && $arg instanceof SQLite3_instruction)
- return SQLITE3_INSTRUCTION;
- else
- throw new \InvalidArgumentException('Argument '.$name.' is of invalid type '.gettype($arg));
- }
-
- public function simpleStatement($query, $args = array())
- {
- $statement = $this->prepare($query);
- $nb = $statement->paramCount();
-
- if (count($args) == 1 && is_array($args[0]))
- {
- if (count($args[0]) != $nb)
- {
- throw new \LengthException('Only '.count($args[0]).' arguments in array, but '.$nb.' are required by query.');
- }
-
- foreach ($args[0] as $key=>$value)
- {
- if (is_int($key))
- {
- throw new \InvalidArgumentException(__FUNCTION__ . ' requires second argument to be a named-associative array, but key '.$key.' is an integer.');
- }
-
- $statement->bindValue(':'.$key, $value, $this->_getArgType($value, $key));
- }
- }
- else
- {
- if (count($args) != $nb)
- {
- throw new \LengthException('Only '.count($args).' arguments, but '.$nb.' are required by query.');
- }
-
- for ($i = 1; $i <= count($args); $i++)
- {
- $arg = $args[$i - 1];
- $statement->bindValue($i, $arg, $this->_getArgType($arg, $i));
- }
- }
-
- return $statement->execute();
- }
-
- public function simpleStatementFetch($query, $mode = SQLITE3_BOTH)
- {
- if ($mode != SQLITE3_BOTH && $mode != SQLITE3_ASSOC && $mode != SQLITE3_NUM)
- {
- throw new \InvalidArgumentException('Mode argument should be either SQLITE3_BOTH, SQLITE3_ASSOC or SQLITE3_NUM.');
- }
-
- $args = array_slice(func_get_args(), 2);
- return $this->_fetchResult($this->simpleStatement($query, $args), $mode);
- }
-
- public function simpleStatementFetchAssoc($query)
- {
- $args = array_slice(func_get_args(), 1);
- return $this->_fetchResultAssoc($this->simpleStatement($query, $args));
- }
-
- public function simpleStatementFetchAssocKey($query, $mode = SQLITE3_BOTH)
- {
- if ($mode != SQLITE3_BOTH && $mode != SQLITE3_ASSOC && $mode != SQLITE3_NUM)
- {
- throw new \InvalidArgumentException('Mode argument should be either SQLITE3_BOTH, SQLITE3_ASSOC or SQLITE3_NUM.');
- }
-
- $args = array_slice(func_get_args(), 2);
- return $this->_fetchResultAssocKey($this->simpleStatement($query, $args), $mode);
- }
-
- public function escapeAuto($value, $name = '')
- {
- $type = $this->_getArgType($value, $name);
-
- switch ($type)
- {
- case SQLITE3_FLOAT:
- return floatval($value);
- case SQLITE3_INTEGER:
- return intval($value);
- case SQLITE3_NULL:
- return 'NULL';
- case SQLITE3_TEXT:
- return '\'' . $this->escapeString($value) . '\'';
- case SQLITE3_INSTRUCTION:
- return (string) $value;
- }
- }
-
- /**
- * Returns a correct, escaped query from a query statement and list of arguments,
- * either as named array or as a list of indexed arguments.
- */
- protected function _getSimpleQuery($query, $args)
- {
- if (count($args) == 1 && is_array($args[0]))
- {
- preg_match_all('/:[a-z_]+/', $query, $matches);
- $nb = count(array_unique($matches[0]));
-
- if (count($args[0]) < $nb)
- {
- throw new \LengthException('Only '.count($args[0]).' arguments in array, but '.$nb.' are required by query.');
- }
-
- foreach ($args[0] as $key=>$value)
- {
- if (is_int($key))
- {
- throw new \InvalidArgumentException(__FUNCTION__ . ' requires second argument to be a named-associative array, but key '.$key.' is an integer.');
- }
-
- $value = preg_replace('#(?escapeAuto($value, $key));
- $query = preg_replace('/:'.$key.'(?![a-z])/', $value, $query);
- }
- }
- else
- {
- $nb = substr_count($query, '?');
-
- if (count($args) != $nb)
- {
- throw new \LengthException('Only '.count($args).' arguments, but '.$nb.' are required by query.');
- }
-
- for ($i = 1; $i <= count($args); $i++)
- {
- $arg = $args[$i - 1];
- $arg = $this->escapeAuto($arg, $i);
-
- $pos = strpos($query, '?');
- $query = substr_replace($query, $arg, $pos, 1);
- }
- }
-
- return $query;
- }
-
- /**
- * Simple INSERT query
- */
- public function simpleInsert($table, $fields)
- {
- $fields_names = array_keys($fields);
- return $this->simpleExec('INSERT INTO '.$table.' ('.implode(', ', $fields_names).')
- VALUES (:'.implode(', :', $fields_names).');', $fields);
- }
-
- public function simpleUpdate($table, $fields, $where)
- {
- $query = 'UPDATE '.$table.' SET ';
-
- foreach ($fields as $key=>$value)
- {
- $query .= $key . ' = :'.$key.', ';
- }
-
- $query = substr($query, 0, -2);
- $query .= ' WHERE '.$where.';';
- return $this->simpleExec($query, $fields);
- }
-
- /**
- * Formats and escapes a statement and then returns the result of exec()
- */
- public function simpleExec($query)
- {
- $args = array_slice(func_get_args(), 1);
- $query = $this->_getSimpleQuery($query, $args);
-
- try {
- return $this->exec($query);
- }
- catch (ErrorException $e)
- {
- echo $query;
- echo "\n\n";
- throw $e;
- }
- }
-
- public function simpleQuerySingle($query, $all_columns = false)
- {
- $args = array_slice(func_get_args(), 2);
- $query = $this->_getSimpleQuery($query, $args);
-
- try {
- return $this->querySingle($query, $all_columns);
- }
- catch (ErrorException $e)
- {
- echo $query;
- echo "\n\n";
- throw $e;
- }
- }
-
- public function queryFetch($query, $mode = SQLITE3_BOTH)
- {
- return $this->_fetchResult($this->query($query), $mode);
- }
-
- public function queryFetchAssoc($query)
- {
- return $this->_fetchResultAssoc($this->query($query));
- }
-
- public function queryFetchAssocKey($query, $mode = SQLITE3_BOTH)
- {
- return $this->_fetchResultAssocKey($this->query($query), $mode);
- }
-
- protected function _fetchResult($result, $mode)
- {
- $out = array();
-
- while ($row = $result->fetchArray($mode))
- {
- $out[] = $row;
- }
-
- $result->finalize();
- unset($result, $row);
-
- return $out;
- }
-
- protected function _fetchResultAssoc($result)
- {
- $out = array();
-
- while ($row = $result->fetchArray(SQLITE3_NUM))
- {
- $out[$row[0]] = $row[1];
- }
-
- $result->finalize();
- unset($result, $row);
-
- return $out;
- }
-
- protected function _fetchResultAssocKey($result, $mode)
- {
- $out = array();
-
- while ($row = $result->fetchArray($mode))
- {
- $key = current($row);
- $out[$key] = $row;
- }
-
- $result->finalize();
- unset($result, $row);
-
- return $out;
- }
-
- public function countRows($result)
- {
- $i = 0;
-
- while ($result->fetchArray(SQLITE3_NUM))
- $i++;
-
- return $i;
- }
-}
-
-?>
DELETED include/class.membres.php
Index: include/class.membres.php
==================================================================
--- include/class.membres.php
+++ include/class.membres.php
@@ -1,724 +0,0 @@
-_getSalt(22);
- return crypt($password, $salt);
- }
-
- protected function _checkPassword($password, $stored_hash)
- {
- return crypt($password, $stored_hash) == $stored_hash;
- }
-
- protected function _sessionStart($force = false)
- {
- if (!isset($_SESSION) && ($force || isset($_COOKIE[session_name()])))
- {
- session_start();
- }
-
- // Fix bug with register_globals ($test is a reference to $_SESSION['test'])
- if (ini_get('register_globals') && isset($_SESSION))
- {
- foreach ($_SESSION as $key=>$value)
- {
- if (isset($GLOBALS[$key]))
- unset($GLOBALS[$key]);
- }
- }
-
- return true;
- }
-
- public function keepSessionAlive()
- {
- $this->_sessionStart(true);
- }
-
- public function login($email, $passe)
- {
- if (!filter_var($email, FILTER_VALIDATE_EMAIL))
- return false;
-
- $db = DB::getInstance();
- $r = $db->simpleQuerySingle('SELECT *, strftime(\'%s\', date_cotisation) AS date_cotisation FROM membres WHERE email = ? LIMIT 1;', true, trim($email));
-
- if (empty($r))
- return false;
-
- if (!$this->_checkPassword(trim($passe), $r['passe']))
- return false;
-
- $droits = $this->getDroits($r['id_categorie']);
-
- if ($droits['connexion'] == self::DROIT_AUCUN)
- return false;
-
- $this->_sessionStart(true);
- $db->simpleExec('UPDATE membres SET date_connexion = datetime(\'now\') WHERE id = ?;', $r['id']);
-
- return $this->updateSessionData($r, $droits);
- }
-
- public function recoverPasswordCheck($email)
- {
- if (!filter_var($email, FILTER_VALIDATE_EMAIL))
- return false;
-
- $db = DB::getInstance();
-
- $id = $db->simpleQuerySingle('SELECT id FROM membres WHERE email = ? LIMIT 1;', false, trim($email));
-
- if (!$id)
- {
- return false;
- }
-
- $config = Config::getInstance();
-
- $dest = trim($email);
-
- $this->_sessionStart(true);
- $hash = sha1($dest . $id . 'recover' . GARRADIN_ROOT . time());
- $_SESSION['recover_password'] = array('id' => (int) $id, 'email' => $dest, 'hash' => $hash);
-
- $message = "Bonjour,\n\nVous avez oublié votre mot de passe ? Pas de panique !\n\n";
- $message.= "Il vous suffit de cliquer sur le lien ci-dessous pour recevoir un nouveau mot de passe.\n\n";
- $message.= WWW_URL . 'admin/password.php?c=' . substr($hash, -10);
- $message.= "\n\nSi vous n'avez pas demandé à recevoir ce message, ignorez-le, votre mot de passe restera inchangé.";
-
- return utils::mail($dest, '['.$config->get('nom_asso').'] Mot de passe perdu ?', $message);
- }
-
- public function recoverPasswordConfirm($hash)
- {
- $this->_sessionStart();
-
- if (empty($_SESSION['recover_password']['hash']))
- return false;
-
- if (substr($_SESSION['recover_password']['hash'], -10) != $hash)
- return false;
-
- $config = Config::getInstance();
- $db = DB::getInstance();
-
- $password = utils::suggestPassword();
-
- $dest = $_SESSION['recover_password']['email'];
- $id = (int)$_SESSION['recover_password']['id'];
-
- $message = "Bonjour,\n\nVous avez demandé un nouveau mot de passe pour votre compte.\n\n";
- $message.= "Votre adresse email : ".$dest."\n";
- $message.= "Votre nouveau mot de passe : ".$password."\n\n";
- $message.= "Si vous n'avez pas demandé à recevoir ce message, merci de nous le signaler.";
-
- $password = $this->_hashPassword($password);
-
- $db->simpleUpdate('membres', array('passe' => $password), 'id = '.(int)$id);
-
- return utils::mail($dest, '['.$config->get('nom_asso').'] Nouveau mot de passe', $message);
- }
-
- public function updateSessionData($membre = null, $droits = null)
- {
- if (is_null($membre))
- {
- $membre = $this->get($_SESSION['logged_user']['id']);
- }
-
- if (is_null($droits))
- {
- $droits = $this->getDroits($membre['id_categorie']);
- }
-
- $membre['droits'] = $droits;
- $_SESSION['logged_user'] = $membre;
- return true;
- }
-
- public function isLogged()
- {
- $this->_sessionStart();
-
- return empty($_SESSION['logged_user']) ? false : true;
- }
-
- public function getLoggedUser()
- {
- if (!$this->isLogged())
- return false;
-
- return $_SESSION['logged_user'];
- }
-
- public function logout()
- {
- $_SESSION = array();
- setcookie(session_name(), '', 0, '/');
- return true;
- }
-
- public function sessionStore($key, $value)
- {
- if (!isset($_SESSION['storage']))
- {
- $_SESSION['storage'] = array();
- }
-
- if ($value === null)
- {
- unset($_SESSION['storage'][$key]);
- }
- else
- {
- $_SESSION['storage'][$key] = $value;
- }
-
- return true;
- }
-
- public function sessionGet($key)
- {
- if (!isset($_SESSION['storage'][$key]))
- {
- return null;
- }
-
- return $_SESSION['storage'][$key];
- }
-
- public function sendMessage($dest, $sujet, $message, $copie = false)
- {
- if (!$this->isLogged())
- {
- throw new \LogicException('Cette fonction ne peut être appelée que par un utilisateur connecté.');
- }
-
- $from = $this->getLoggedUser();
- $from = $from['email'];
- // Uniquement adresse email pour le moment car faudrait trouver comment
- // indiquer le nom mais qu'il soit correctement échappé FIXME
-
- $config = Config::getInstance();
-
- $message .= "\n\n--\nCe message a été envoyé par un membre de ".$config->get('nom_asso');
- $message .= ", merci de contacter ".$config->get('email_asso')." en cas d'abus.";
-
- if ($copie)
- {
- utils::mail($from, $sujet, $message);
- }
-
- return utils::mail($dest, $sujet, $message, array('From' => $from));
- }
-
- // Gestion des données ///////////////////////////////////////////////////////
-
- public function _checkFields(&$data, $check_mandatory = true, $check_password = true)
- {
- $champs = Config::getInstance()->get('champs_membres');
-
- foreach ($champs->getAll() as $key=>$config)
- {
- if (!isset($data[$key]) || empty($data[$key]) || (!is_array($data[$key]) && trim($data[$key]) == ''))
- {
- if (!empty($config['mandatory']) && $check_mandatory && ($check_password || $key != 'passe'))
- {
- throw new UserException('Le champ "' . $config['title'] . '" doit obligatoirement être renseigné.');
- }
- elseif (!empty($config['mandatory']))
- {
- continue;
- }
- }
-
- if (isset($data[$key]))
- {
- if ($config['type'] == 'email' && trim($data[$key]) != '' && !filter_var($data[$key], FILTER_VALIDATE_EMAIL))
- {
- throw new UserException('Adresse e-mail invalide dans le champ "' . $config['title'] . '".');
- }
- elseif ($config['type'] == 'url' && trim($data[$key]) != '' && !filter_var($data[$key], FILTER_VALIDATE_URL))
- {
- throw new UserException('Adresse URL invalide dans le champ "' . $config['title'] . '".');
- }
- elseif ($config['type'] == 'tel')
- {
- $data[$key] = utils::normalizePhoneNumber($data[$key]);
- }
- elseif ($config['type'] == 'country')
- {
- $data[$key] = strtoupper(substr($data[$key], 0, 2));
- }
- elseif ($config['type'] == 'checkbox')
- {
- $data[$key] = empty($data[$key]) ? 0 : 1;
- }
- elseif ($config['type'] == 'number' && trim($data[$key]) != '')
- {
- if (empty($data[$key]))
- {
- $data[$key] = 0;
- }
-
- if (!is_numeric($data[$key]))
- throw new UserException('Le champ "' . $config['title'] . '" doit contenir un chiffre.');
- }
- elseif ($config['type'] == 'select' && !in_array($data[$key], $config['options']))
- {
- throw new UserException('Le champ "' . $config['title'] . '" ne correspond pas à un des choix proposés.');
- }
- elseif ($config['type'] == 'multiple')
- {
- if (empty($data[$key]) || !is_array($data[$key]))
- {
- $data[$key] = 0;
- continue;
- }
-
- $binary = 0;
-
- foreach ($data[$key] as $k => $v)
- {
- if (array_key_exists($k, $config['options']) && !empty($v))
- {
- $binary |= 0x01 << $k;
- }
- }
-
- $data[$key] = $binary;
- }
- }
- }
-
- if (isset($data['code_postal']) && trim($data['code_postal']) != '')
- {
- if (!empty($data['pays']) && $data['pays'] == 'FR' && !preg_match('!^\d{5}$!', $data['code_postal']))
- {
- throw new UserException('Code postal invalide.');
- }
- }
-
- if (!empty($data['passe']) && strlen($data['passe']) < 5)
- {
- throw new UserException('Le mot de passe doit faire au moins 5 caractères.');
- }
-
- return true;
- }
-
- public function add($data = array(), $check_mandatory = true)
- {
- $this->_checkFields($data, $check_mandatory);
- $db = DB::getInstance();
-
- if (!empty($data['email'])
- && $db->simpleQuerySingle('SELECT 1 FROM membres WHERE email = ? LIMIT 1;', false, $data['email']))
- {
- throw new UserException('Cette adresse e-mail est déjà utilisée par un autre membre, il faut en choisir une autre.');
- }
-
- if (isset($data['passe']) && trim($data['passe']) != '')
- {
- $data['passe'] = $this->_hashPassword($data['passe']);
- }
- else
- {
- unset($data['passe']);
- }
-
- if (empty($data['id_categorie']))
- {
- $data['id_categorie'] = Config::getInstance()->get('categorie_membres');
- }
-
- $db->simpleInsert('membres', $data);
- return $db->lastInsertRowId();
- }
-
- public function edit($id, $data = array(), $check_mandatory = true)
- {
- $db = DB::getInstance();
-
- if (isset($data['id']) && ($data['id'] == $id || empty($data['id'])))
- {
- unset($data['id']);
- }
-
- $this->_checkFields($data, $check_mandatory, false);
-
- if (!empty($data['email'])
- && $db->simpleQuerySingle('SELECT 1 FROM membres WHERE email = ? AND id != ? LIMIT 1;', false, $data['email'], (int)$id))
- {
- throw new UserException('Cette adresse e-mail est déjà utilisée par un autre membre, il faut en choisir une autre.');
- }
-
- if (!empty($data['id']))
- {
- if ($db->simpleQuerySingle('SELECT 1 FROM membres WHERE id = ?;', false, (int)$data['id']))
- {
- throw new UserException('Ce numéro est déjà attribué à un autre membre.');
- }
-
- // Si on ne vérifie pas toutes les tables qui sont liées ici à un ID de membre
- // la requête de modification provoquera une erreur de contrainte de foreign key
- // ce qui est normal. Donc : il n'est pas possible de changer l'ID d'un membre qui
- // a participé au wiki, à la compta, etc.
- if ($db->simpleQuerySingle('SELECT 1 FROM wiki_revisions WHERE id_auteur = ?;', false, (int)$id)
- || $db->simpleQuerySingle('SELECT 1 FROM compta_journal WHERE id_auteur = ?;', false, (int)$id))
- #|| $db->simpleQuerySingle('SELECT 1 FROM wiki_suivi WHERE id_membre = ?;', false, (int)$id))
- {
- throw new UserException('Le numéro n\'est pas modifiable pour ce membre car des contenus sont liés à ce numéro de membre (wiki, compta, etc.).');
- }
- }
-
- if (!empty($data['passe']) && trim($data['passe']))
- {
- $data['passe'] = $this->_hashPassword($data['passe']);
- }
- else
- {
- unset($data['passe']);
- }
-
- if (isset($data['id_categorie']) && empty($data['id_categorie']))
- {
- $data['id_categorie'] = Config::getInstance()->get('categorie_membres');
- }
-
- $db->simpleUpdate('membres', $data, 'id = '.(int)$id);
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT *,
- strftime(\'%s\', date_cotisation) AS date_cotisation,
- strftime(\'%s\', date_inscription) AS date_inscription,
- strftime(\'%s\', date_connexion) AS date_connexion
- FROM membres WHERE id = ? LIMIT 1;', true, (int)$id);
- }
-
- public function delete($ids)
- {
- if (!is_array($ids))
- {
- $ids = array((int)$ids);
- }
-
- if ($this->isLogged())
- {
- $user = $this->getLoggedUser();
-
- foreach ($ids as $id)
- {
- if ($user['id'] == $id)
- {
- throw new UserException('Il n\'est pas possible de supprimer son propre compte.');
- }
- }
- }
-
- return self::_deleteMembres($ids);
- }
-
- public function getNom($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT nom FROM membres WHERE id = ? LIMIT 1;', false, (int)$id);
- }
-
- public function getDroits($id)
- {
- $db = DB::getInstance();
- $droits = $db->simpleQuerySingle('SELECT * FROM membres_categories WHERE id = ?;', true, (int)$id);
-
- foreach ($droits as $key=>$value)
- {
- unset($droits[$key]);
- $key = str_replace('droit_', '', $key, $found);
-
- if ($found)
- {
- $droits[$key] = (int) $value;
- }
- }
-
- return $droits;
- }
-
- public function search($field, $query)
- {
- $db = DB::getInstance();
- $champs = Config::getInstance()->get('champs_membres');
-
- if ($field != 'id' && !$champs->get($field))
- {
- throw new \UnexpectedValueException($field . ' is not a valid field');
- }
-
- $champ = $champs->get($field);
-
- if ($champ['type'] == 'multiple')
- {
- $where = 'WHERE '.$field.' & (1 << '.(int)$query.')';
- $order = false;
- }
- elseif ($champ['type'] == 'tel')
- {
- $query = utils::normalizePhoneNumber($query);
- $query = preg_replace('!^0+!', '', $query);
-
- if ($query == '')
- {
- return false;
- }
-
- $where = 'WHERE '.$field.' LIKE \'%'.$db->escapeString($query).'\'';
- $order = $field;
- }
- elseif (!$champs->isText($field))
- {
- $where = 'WHERE '.$field.' = \''.$db->escapeString($query).'\'';
- $order = $field;
- }
- else
- {
- $where = 'WHERE transliterate_to_ascii('.$field.') LIKE transliterate_to_ascii(\'%'.$db->escapeString($query).'%\')';
- $order = 'transliterate_to_ascii('.$field.') COLLATE NOCASE';
- }
-
- $fields = array_keys($champs->getListedFields());
-
- if (!in_array($field, $fields))
- {
- $fields[] = $field;
- }
-
- return $db->simpleStatementFetch(
- 'SELECT id, id_categorie, ' . implode(', ', $fields) . ',
- strftime(\'%s\', date_cotisation) AS date_cotisation,
- strftime(\'%s\', date_inscription) AS date_inscription
- FROM membres ' . $where . ($order ? ' ORDER BY ' . $order : '') . '
- LIMIT 1000;',
- SQLITE3_ASSOC
- );
- }
-
- public function listByCategory($cat, $fields, $page = 1, $order = null, $desc = false)
- {
- $begin = ($page - 1) * self::ITEMS_PER_PAGE;
-
- $db = DB::getInstance();
- $champs = Config::getInstance()->get('champs_membres');
-
- if (is_int($cat) && $cat)
- $where = 'WHERE id_categorie = '.(int)$cat;
- elseif (is_array($cat))
- $where = 'WHERE id_categorie IN ('.implode(',', $cat).')';
- else
- $where = '';
-
- if (is_null($order) || !$champs->get($order))
- $order = 'id';
-
- if (!empty($fields) && $order != 'id' && $champs->isText($order))
- {
- $order = 'transliterate_to_ascii('.$order.') COLLATE NOCASE';
- }
-
- if ($desc)
- {
- $order .= ' DESC';
- }
-
- if (!in_array('email', $fields))
- {
- $fields []= 'email';
- }
-
- $fields = implode(', ', $fields);
-
- return $db->simpleStatementFetch(
- 'SELECT id, id_categorie, '.$fields.',
- strftime(\'%s\', date_cotisation) AS date_cotisation,
- strftime(\'%s\', date_inscription) AS date_inscription
- FROM membres '.$where.'
- ORDER BY '.$order.' LIMIT ?, ?;',
- SQLITE3_ASSOC,
- $begin,
- self::ITEMS_PER_PAGE
- );
- }
-
- public function countByCategory($cat = 0)
- {
- $db = DB::getInstance();
-
- if (is_int($cat) && $cat)
- $where = 'WHERE id_categorie = '.(int)$cat;
- elseif (is_array($cat))
- $where = 'WHERE id_categorie IN ('.implode(',', $cat).')';
- else
- $where = '';
-
- return $db->simpleQuerySingle('SELECT COUNT(*) FROM membres '.$where.';');
- }
-
- public function countAllButHidden()
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT COUNT(*) FROM membres WHERE id_categorie NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);');
- }
-
- static public function checkCotisation($date_membre, $duree_cotisation, $date_verif = null)
- {
- if (is_null($date_verif))
- $date_verif = time();
-
- if (!$date_membre)
- return false;
-
- $echeance = new \DateTime('@' . $date_membre);
- $echeance->setTime(0, 0);
- $echeance->modify('+'.$duree_cotisation.' months');
-
- if ($echeance->getTimestamp() < $date_verif)
- return round(($date_verif - $echeance->getTimestamp()) / 3600 / 24);
-
- return true;
- }
-
- static public function updateCotisation($id, $date)
- {
- if (preg_match('!^\d{2}/\d{2}/\d{4}$!', $date))
- $date = \DateTime::createFromFormat('d/m/Y', $date, new \DateTimeZone('UTC'));
- elseif (preg_match('!^\d{4}-\d{2}-\d{2}$!', $date))
- $date = \DateTime::createFromFormat('Y-m-d', $date, new \DateTimeZone('UTC'));
- else
- throw new UserException('Format de date invalide : '.$date);
-
- $db = DB::getInstance();
- return $db->simpleUpdate('membres',
- array('date_cotisation' => $date->format('Y-m-d H:i:s')),
- 'id = '.(int)$id
- );
- }
-
- static public function changeCategorie($id_cat, $membres)
- {
- foreach ($membres as &$id)
- {
- $id = (int) $id;
- }
-
- $db = DB::getInstance();
- return $db->simpleUpdate('membres',
- array('id_categorie' => (int)$id_cat),
- 'id IN ('.implode(',', $membres).')'
- );
- }
-
- static protected function _deleteMembres($membres)
- {
- foreach ($membres as &$id)
- {
- $id = (int) $id;
- }
-
- $membres = implode(',', $membres);
-
- $db = DB::getInstance();
- $db->exec('UPDATE wiki_revisions SET id_auteur = NULL WHERE id_auteur IN ('.$membres.');');
- $db->exec('UPDATE compta_journal SET id_auteur = NULL WHERE id_auteur IN ('.$membres.');');
- //$db->exec('DELETE FROM wiki_suivi WHERE id_membre IN ('.$membres.');');
- return $db->exec('DELETE FROM membres WHERE id IN ('.$membres.');');
- }
-
- public function sendMessageToCategory($dest, $sujet, $message, $subscribed_only = false)
- {
- $config = Config::getInstance();
-
- $headers = array(
- 'From' => '"'.$config->get('nom_asso').'" <'.$config->get('email_asso').'>',
- );
- $message .= "\n\n--\n".$config->get('nom_asso')."\n".$config->get('site_asso');
-
- if ($dest == 0)
- $where = 'id_categorie NOT IN (SELECT id FROM membres_categories WHERE cacher = 1)';
- else
- $where = 'id_categorie = '.(int)$dest;
-
- if ($subscribed_only)
- {
- $where .= ' AND lettre_infos = 1';
- }
-
- $db = DB::getInstance();
- $res = $db->query('SELECT email FROM membres WHERE LENGTH(email) > 0 AND '.$where.' ORDER BY id;');
-
- $sujet = '['.$config->get('nom_asso').'] '.$sujet;
-
- while ($row = $res->fetchArray(SQLITE3_ASSOC))
- {
- utils::mail($row['email'], $sujet, $message, $headers);
- }
-
- return true;
- }
-
- public function toCSV()
- {
- $db = DB::getInstance();
-
- $res = $db->prepare('SELECT m.id, c.nom AS "categorie", m.* FROM membres AS m
- LEFT JOIN membres_categories AS c ON m.id_categorie = c.id ORDER BY c.id;')->execute();
-
- $fp = fopen('php://output', 'w');
- $header = false;
-
- while ($row = $res->fetchArray(SQLITE3_ASSOC))
- {
- unset($row['passe']);
-
- if (!$header)
- {
- fputcsv($fp, array_keys($row));
- $header = true;
- }
-
- fputcsv($fp, $row);
- }
-
- fclose($fp);
-
- return true;
- }
-}
-
-?>
DELETED include/class.membres_categories.php
Index: include/class.membres_categories.php
==================================================================
--- include/class.membres_categories.php
+++ include/class.membres_categories.php
@@ -1,164 +0,0 @@
- Membres::DROIT_AUCUN,
- 'connexion' => Membres::DROIT_ACCES,
- 'membres' => Membres::DROIT_ACCES,
- 'compta' => Membres::DROIT_ACCES,
- 'wiki' => Membres::DROIT_ACCES,
- 'config' => Membres::DROIT_AUCUN,
- );
-
- static public function getDroitsDefaut()
- {
- return $this->droits;
- }
-
- protected function _checkData(&$data)
- {
- if (!isset($data['nom']) || !trim($data['nom']))
- {
- throw new UserException('Le nom de catégorie ne peut rester vide.');
- }
-
- if (!isset($data['montant_cotisation']) || !is_numeric($data['montant_cotisation']))
- {
- throw new UserException('Le montant de cotisation doit être un chiffre.');
- }
-
- if (isset($data['montant_cotisation']))
- {
- $data['montant_cotisation'] = (float)$data['montant_cotisation'];
- }
- else
- {
- $data['montant_cotisation'] = 0;
- }
-
- if (isset($data['duree_cotisation']))
- {
- $data['duree_cotisation'] = (int)$data['duree_cotisation'];
- }
- else
- {
- $data['duree_cotisation'] = 0;
- }
- }
-
- public function add($data)
- {
- $this->_checkData($data);
-
- if (!isset($data['duree_cotisation']) || !is_numeric($data['duree_cotisation']))
- {
- $data['duree_cotisation'] = 12;
- }
-
- if (!isset($data['description']))
- {
- $data['description'] = '';
- }
-
- foreach ($this->droits as $key=>$value)
- {
- if (!isset($data['droit_'.$key]))
- $data['droit_'.$key] = $value;
- else
- $data['droit_'.$key] = (int)$data['droit_'.$key];
- }
-
- $db = DB::getInstance();
- $db->simpleInsert('membres_categories', $data);
-
- return $db->lastInsertRowID();
- }
-
- public function edit($id, $data)
- {
- $this->_checkData($data);
-
- foreach ($this->droits as $key=>$value)
- {
- if (isset($data['droit_'.$key]))
- $data['droit_'.$key] = (int)$data['droit_'.$key];
- }
-
- if (!isset($data['cacher']) || $data['cacher'] != 1)
- $data['cacher'] = 0;
-
- $db = DB::getInstance();
- return $db->simpleUpdate('membres_categories', $data, 'id = '.(int)$id);
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
-
- return $db->simpleQuerySingle('SELECT * FROM membres_categories WHERE id = ?;',
- true, (int) $id);
- }
-
- public function remove($id)
- {
- $db = DB::getInstance();
- $config = Config::getInstance();
-
- if ($id == $config->get('categorie_membres'))
- {
- throw new UserException('Il est interdit de supprimer la catégorie définie par défaut dans la configuration.');
- }
-
- if ($db->simpleQuerySingle('SELECT 1 FROM membres WHERE id_categorie = ?;', false, (int)$id))
- {
- throw new UserException('La catégorie contient encore des membres, il n\'est pas possible de la supprimer.');
- }
-
- $db->simpleUpdate(
- 'wiki_pages',
- array(
- 'droit_lecture' => Wiki::LECTURE_NORMAL,
- 'droit_ecriture' => Wiki::ECRITURE_NORMAL,
- ),
- 'droit_lecture = '.(int)$id.' OR droit_ecriture = '.(int)$id
- );
-
- return $db->simpleExec('DELETE FROM membres_categories WHERE id = ?;', (int) $id);
- }
-
- public function listSimple()
- {
- $db = DB::getInstance();
- return $db->queryFetchAssoc('SELECT id, nom FROM membres_categories ORDER BY nom;');
- }
-
- public function listComplete()
- {
- $db = DB::getInstance();
- return $db->queryFetch('SELECT * FROM membres_categories ORDER BY nom;');
- }
-
- public function listCompleteWithStats()
- {
- $db = DB::getInstance();
- return $db->queryFetch('SELECT *, (SELECT COUNT(*) FROM membres WHERE id_categorie = membres_categories.id) AS nombre FROM membres_categories ORDER BY nom;');
- }
-
-
- public function listHidden()
- {
- $db = DB::getInstance();
- return $db->queryFetchAssoc('SELECT id, nom FROM membres_categories WHERE cacher = 1;');
- }
-
- public function listNotHidden()
- {
- $db = DB::getInstance();
- return $db->queryFetchAssoc('SELECT id, nom FROM membres_categories WHERE cacher = 0;');
- }
-}
-
-?>
DELETED include/class.sauvegarde.php
Index: include/class.sauvegarde.php
==================================================================
--- include/class.sauvegarde.php
+++ include/class.sauvegarde.php
@@ -1,263 +0,0 @@
-read())
- {
- if ($file[0] != '.' && is_file(GARRADIN_DATA_ROOT . '/' . $file)
- && preg_match('![\w\d._-]+\.' . $ext . '$!i', $file) && $file != basename(GARRADIN_DB_FILE))
- {
- $out[$file] = filemtime(GARRADIN_DATA_ROOT . '/' . $file);
- }
- }
-
- $dir->close();
-
- ksort($out);
-
- return $out;
- }
-
- /**
- * Crée une nouvelle sauvegarde
- * @param boolean $auto Si true le nom de fichier sera celui de la sauvegarde automatique courante,
- * sinon le nom sera basé sur la date (sauvegarde manuelle)
- * @return string Le nom de fichier de la sauvegarde ainsi créée
- */
- public function create($auto = false)
- {
- $backup = str_replace('.sqlite', ($auto ? '.1.auto' : date('.Y-m-d-H-i')) . '.sqlite', GARRADIN_DB_FILE);
- copy(GARRADIN_DB_FILE, $backup);
- return basename($backup);
- }
-
- /**
- * Effectue une rotation des sauvegardes automatiques
- * association.1.auto.sqlite deviendra association.2.auto.sqlite par exemple
- * @return boolean true
- */
- public function rotate()
- {
- $config = Config::getInstance();
- $nb = $config->get('nombre_sauvegardes');
-
- $list = $this->getList(true);
- krsort($list);
-
- if (count($list) >= $nb)
- {
- $this->remove(key($list));
- $list = array_shift($list);
- }
-
- foreach ($list as $f=>$d)
- {
- $new = preg_replace_callback('!\.(\d+)\.auto\.sqlite$!', function ($m) {
- return (int) $m[1] + 1;
- }, $f);
-
- rename(GARRADIN_DATA_ROOT . '/' . $f, GARRADIN_DATA_ROOT . '/' . $new);
- }
-
- return true;
- }
-
- /**
- * Crée une sauvegarde automatique si besoin est
- * @return boolean true
- */
- public function auto()
- {
- $config = Config::getInstance();
-
- // Pas besoin d'aller plus loin si on ne fait pas de sauvegarde auto
- if ($config->get('frequence_sauvegardes') == 0 || $config->get('nombre_sauvegardes') == 0)
- return true;
-
- $list = $this->getList(true);
-
- if (count($list) > 0)
- {
- $last = current($list);
- }
- else
- {
- $last = false;
- }
-
- // Test de la date de création de la dernière sauvegarde
- if ($last >= (time() - ($config->get('frequence_sauvegardes') * 3600 * 24)))
- {
- return true;
- }
-
- // Si pas de modif depuis la dernière sauvegarde, ça sert à rien d'en faire
- if ($last >= filemtime(GARRADIN_DB_FILE))
- {
- return true;
- }
-
- $this->rotate();
- $this->create(true);
-
- return true;
- }
-
- /**
- * Efface une sauvegarde locale
- * @param string $file Nom du fichier à supprimer
- * @return boolean true si le fichier a bien été supprimé, false sinon
- */
- public function remove($file)
- {
- if (preg_match('!\.\.+!', $file) || !preg_match('!^[\w\d._-]+\.sqlite$!i', $file)
- || $file == basename(GARRADIN_DB_FILE))
- {
- throw new UserException('Nom de fichier non valide.');
- }
-
- return unlink(GARRADIN_DATA_ROOT . '/' . $file);
- }
-
- /**
- * Renvoie sur la sortie courante le contenu du fichier de base de données courant
- * @return boolean true
- */
- public function dump()
- {
- $in = fopen(GARRADIN_DB_FILE, 'r');
- $out = fopen('php://output', 'w');
-
- while (!feof($in))
- {
- fwrite($out, fread($in, 8192));
- }
-
- fclose($in);
- fclose($out);
- return true;
- }
-
- /**
- * Restaure une sauvegarde locale
- * @param string $file Le nom de fichier à utiliser comme point de restauration
- * @return boolean true si la restauration a fonctionné, false sinon
- */
- public function restoreFromLocal($file)
- {
- if (preg_match('!\.\.+!', $file) || !preg_match('!^[\w\d._-]+$!i', $file))
- {
- throw new UserException('Nom de fichier non valide.');
- }
-
- if (!file_exists(GARRADIN_DATA_ROOT . '/' . $file))
- {
- throw new UserException('Le fichier fourni n\'existe pas.');
- }
-
- return $this->restoreDB(GARRADIN_DATA_ROOT . '/' . $file);
- }
-
- /**
- * Restaure une copie distante (fichier envoyé)
- * @param array $file Tableau provenant de $_FILES
- * @return boolean true
- */
- public function restoreFromUpload($file)
- {
- if (empty($file['size']) || empty($file['tmp_name']) || !empty($file['error']))
- {
- throw new UserException('Le fichier n\'a pas été correctement envoyé. Essayer de le renvoyer à nouveau.');
- }
-
- $r = $this->restoreDB($file['tmp_name']);
-
- if ($r)
- {
- unlink($file['tmp_name']);
- }
-
- return $r;
- }
-
- /**
- * Restauration de base de données, la fonction qui le fait vraiment
- * @param string $file Chemin absolu vers la base de données à utiliser
- * @return mixed true si rien ne va plus, ou self::NEED_UPGRADE si la version de la DB
- * ne correspond pas à la version de Garradin (mise à jour nécessaire).
- */
- protected function restoreDB($file)
- {
- // Essayons déjà d'ouvrir la base de données à restaurer en lecture
- try {
- $db = new \SQLite3($file, SQLITE3_OPEN_READONLY);
- }
- catch (\Exception $e)
- {
- throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' .
- 'Message d\'erreur de SQLite : ' . $e->getMessage());
- }
-
- // Regardons ensuite si la base de données n'est pas corrompue
- $check = $db->querySingle('PRAGMA integrity_check;');
-
- if (strtolower(trim($check)) != 'ok')
- {
- throw new UserException('Le fichier fourni est corrompu. SQLite a trouvé ' . $check . ' erreurs.');
- }
-
- // On ne peut pas faire de vérifications très poussées sur la structure de la base de données,
- // celle-ci pouvant changer d'une version à l'autre et on peut vouloir importer une base
- // un peu vieille, mais on vérifie quand même que ça ressemble un minimum à une base garradin
- $table = $db->querySingle('SELECT 1 FROM sqlite_master WHERE type=\'table\' AND tbl_name=\'config\';');
-
- if (!$table)
- {
- throw new UserException('Le fichier fourni ne semble pas contenir de données liées à Garradin.');
- }
-
- // On récupère la version pour plus tard
- $version = $db->querySingle('SELECT valeur FROM config WHERE cle=\'version\';');
-
- $db->close();
-
- $backup = str_replace('.sqlite', date('.Y-m-d-H-i') . '.pre-restore.sqlite', GARRADIN_DB_FILE);
-
- if (!rename(GARRADIN_DB_FILE, $backup))
- {
- throw new \RuntimeException('Unable to backup current DB file.');
- }
-
- if (!copy($file, GARRADIN_DB_FILE))
- {
- rename($backup, GARRADIN_DB_FILE);
- throw new \RuntimeException('Unable to copy backup DB to main location.');
- }
-
- if ($version != garradin_version())
- {
- return self::NEED_UPGRADE;
- }
-
- return true;
- }
-
-}
-
-?>
DELETED include/class.squelette.php
Index: include/class.squelette.php
==================================================================
--- include/class.squelette.php
+++ include/class.squelette.php
@@ -1,735 +0,0 @@
-_getType($type, $value);
-
- if ($type == self::OBJ)
- {
- $this->_content = $value->get();
- }
- else
- {
- $this->_content[] = (string) (int) $type . $value;
- }
-
- unset($value);
- }
-
- public function prepend($type = self::TEXT, $value, $pos = false)
- {
- $type = $this->_getType($type, $value);
-
- if ($type == self::OBJ)
- {
- if ($pos)
- {
- array_splice($this->_content, $pos, 0, $value->get());
- }
- else
- {
- $this->_content = array_merge($value->get(), $this->_content);
- }
- }
- else
- {
- $value = (string) (int) $type . $value;
-
- if ($pos)
- {
- array_splice($this->_content, $pos, 0, $value);
- }
- else
- {
- array_unshift($this->_content, $value);
- }
- }
-
- unset($value);
- }
-
- public function append($type = self::TEXT, $value, $pos = false)
- {
- $type = $this->_getType($type, $value);
-
- if ($type == self::OBJ)
- {
- if ($pos)
- {
- array_splice($this->_content, $pos + 1, 0, $value->get());
- }
- else
- {
- $this->_content = array_merge($this->_content, $value->get());
- }
- }
- else
- {
- $value = (string) (int) $type . $value;
-
- if ($pos)
- {
- array_splice($this->_content, $pos + 1, 0, $value);
- }
- else
- {
- array_push($this->_content, $value);
- }
- }
-
- unset($value);
- }
-
- public function output($in_php = false)
- {
- $out = '';
- $php = $in_php ?: false;
-
- foreach ($this->_content as $line)
- {
- if ($line[0] == self::PHP && !$php)
- {
- $php = true;
- $out .= '';
- }
-
- $out .= substr($line, 1);
-
- if ($line[0] == self::PHP)
- {
- $out .= "\n";
- }
- }
-
- if ($php && !$in_php)
- {
- $out .= ' ?>';
- }
-
- $this->_content = array();
-
- return $out;
- }
-
- public function __toString()
- {
- return $this->output(false);
- }
-
- public function get()
- {
- return $this->_content;
- }
-
- public function replace($key, $type = self::TEXT, $value)
- {
- $type = $this->_getType($type, $value);
-
- if ($type == self::OBJ)
- {
- array_splice($this->_content, $key, 1, $value->get());
- }
- else
- {
- $this->_content[$key] = (string) (int) $type . $value;
- }
-
- unset($value);
- }
-}
-
-class Squelette extends \miniSkel
-{
- private $parent = null;
- private $current = null;
- private $_vars = array();
-
- private function _registerDefaultModifiers()
- {
- foreach (Squelette_Filtres::$filtres_php as $func=>$name)
- {
- if (is_string($func))
- $this->register_modifier($name, $func);
- else
- $this->register_modifier($name, $name);
- }
-
- foreach (get_class_methods('Garradin\Squelette_Filtres') as $name)
- {
- $this->register_modifier($name, array('Garradin\Squelette_Filtres', $name));
- }
-
- foreach (Squelette_Filtres::$filtres_alias as $name=>$func)
- {
- $this->register_modifier($name, array('Garradin\Squelette_Filtres', $func));
- }
- }
-
- public function __construct()
- {
- $this->_registerDefaultModifiers();
-
- $config = Config::getInstance();
-
- $this->assign('nom_asso', $config->get('nom_asso'));
- $this->assign('adresse_asso', $config->get('adresse_asso'));
- $this->assign('email_asso', $config->get('email_asso'));
- $this->assign('site_asso', $config->get('site_asso'));
-
- $this->assign('url_racine', WWW_URL);
- $this->assign('url_site', WWW_URL);
- $this->assign('url_atom', WWW_URL . 'feed/atom/');
- $this->assign('url_elements', WWW_URL . 'elements/');
- $this->assign('url_admin', WWW_URL . 'admin/');
- }
-
- protected function processInclude($args)
- {
- if (empty($args))
- throw new \miniSkelMarkupException("Le tag INCLURE demande à préciser le fichier à inclure.");
-
- $file = key($args);
-
- if (empty($file) || !preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!', $file))
- throw new \miniSkelMarkupException("INCLURE: le nom de fichier ne peut contenir que des caractères alphanumériques.");
-
- return new Squelette_Snippet(1, '$this->fetch("'.$file.'", false);');
- }
-
- protected function processVariable($name, $value, $applyDefault, $modifiers, $pre, $post, $context)
- {
- if ($context == self::CONTEXT_IN_ARG)
- {
- $out = new Squelette_Snippet(1, '$this->getVariable(\''.$name.'\')');
-
- if ($pre)
- {
- $out->prepend(2, $pre);
- }
-
- if ($post)
- {
- $out->append(2, $post);
- }
-
- return $out;
- }
-
- $out = new Squelette_Snippet(1, '$value = $this->getVariable(\''.$name.'\');');
-
- // We process modifiers
- foreach ($modifiers as &$modifier)
- {
- if (!isset($this->modifiers[$modifier['name']]))
- {
- throw new \miniSkelMarkupException('Filtre '.$modifier['name'].' inconnu !');
- }
-
- $out->append(1, '$value = call_user_func_array('.var_export($this->modifiers[$modifier['name']], true).', array($value, ');
-
- foreach ($modifier['arguments'] as $arg)
- {
- if ($arg == 'debut_liste')
- {
- $out->append(1, '$this->getVariable(\'debut_liste\')');
- }
- elseif ($arg instanceOf Squelette_Snippet)
- {
- $out->append(3, $arg);
- }
- else
- {
- //if (preg_match('!getVariable!', $arg)) throw new Exception("lol");
- $out->append(1, '"'.str_replace('"', '\\"', $arg).'"');
- }
-
- $out->append(1, ', ');
- }
-
- $out->append(1, '));');
-
- if (in_array($modifier['name'], Squelette_Filtres::$desactiver_defaut))
- {
- $applyDefault = false;
- }
- }
-
- if ($applyDefault)
- {
- $out->append(1, 'if (is_string($value) && trim($value)) $value = htmlspecialchars($value, ENT_QUOTES, \'UTF-8\', false);');
- }
-
- $out->append(1, 'if ($value === true || trim($value) !== \'\'):');
-
- // Getting pre-content
- if ($pre)
- {
- $out->append(2, $pre);
- }
-
- $out->append(1, 'echo is_bool($value) ? "" : $value;');
-
- // Getting post-content
- if ($post)
- {
- $out->append(2, $post);
- }
-
- $out->append(1, 'endif;');
-
- return $out;
- }
-
- protected function processLoop($loopName, $loopType, $loopCriterias, $loopContent, $preContent, $postContent, $altContent)
- {
- if ($loopType != 'articles' && $loopType != 'rubriques' && $loopType != 'pages')
- {
- throw new \miniSkelMarkupException("Le type de boucle '".$loopType."' est inconnu.");
- }
-
- $loopStart = '';
- $query = $where = $order = '';
- $limit = $begin = 0;
-
- $query = 'SELECT w.*, strftime(\\\'%s\\\', w.date_creation) AS date_creation, strftime(\\\'%s\\\', w.date_modification) AS date_modification';
-
- if (trim($loopContent))
- {
- $query .= ', r.contenu AS texte FROM wiki_pages AS w LEFT JOIN wiki_revisions AS r ON (w.id = r.id_page AND w.revision = r.revision) ';
- }
- else
- {
- $query .= '\'\' AS texte ';
- }
-
- $where = 'WHERE w.droit_lecture = -1 ';
-
- if ($loopType == 'articles')
- {
- $where .= 'AND (SELECT COUNT(id) FROM wiki_pages WHERE parent = w.id) = 0 ';
- }
- elseif ($loopType == 'rubriques')
- {
- $where .= 'AND (SELECT COUNT(id) FROM wiki_pages WHERE parent = w.id) > 0 ';
- }
-
- $allowed_fields = array('id', 'uri', 'titre', 'date', 'date_creation', 'date_modification',
- 'parent', 'rubrique', 'revision', 'points', 'recherche', 'texte');
- $search = $search_rank = false;
-
- foreach ($loopCriterias as $criteria)
- {
- if (isset($criteria['field']))
- {
- if (!in_array($criteria['field'], $allowed_fields))
- {
- throw new \miniSkelMarkupException("Critère '".$criteria['field']."' invalide pour la boucle '$loopName' de type '$loopType'.");
- }
- elseif ($criteria['field'] == 'rubrique')
- {
- $criteria['field'] = 'parent';
- }
- elseif ($criteria['field'] == 'date')
- {
- $criteria['field'] = 'date_creation';
- }
- elseif ($criteria['field'] == 'points')
- {
- if ($criteria['action'] != \miniSkel::ACTION_ORDER_BY)
- {
- throw new \miniSkelMarkupException("Le critère 'points' n\'est pas valide dans ce contexte.");
- }
-
- $search_rank = true;
- }
- }
-
- switch ($criteria['action'])
- {
- case \miniSkel::ACTION_ORDER_BY:
- if (!$order)
- $order = 'ORDER BY '.$criteria['field'].'';
- else
- $order .= ', '.$criteria['field'].'';
- break;
- case \miniSkel::ACTION_ORDER_DESC:
- if ($order)
- $order .= ' DESC';
- break;
- case \miniSkel::ACTION_LIMIT:
- $begin = $criteria['begin'];
- $limit = $criteria['number'];
- break;
- case \miniSkel::ACTION_MATCH_FIELD_BY_VALUE:
- $where .= ' AND '.$criteria['field'].' '.$criteria['comparison'].' \\\'\'.$db->escapeString(\''.$criteria['value'].'\').\'\\\'';
- break;
- case \miniSkel::ACTION_MATCH_FIELD:
- {
- if ($criteria['field'] == 'recherche')
- {
- $query = 'SELECT w.*, r.contenu AS texte, rank(matchinfo(wiki_recherche), 0, 1.0, 1.0) AS points FROM wiki_pages AS w INNER JOIN wiki_recherche AS r ON (w.id = r.id) ';
- $where .= ' AND wiki_recherche MATCH \\\'\'.$db->escapeString($this->getVariable(\''.$criteria['field'].'\')).\'\\\'';
- $search = true;
- }
- else
- {
- if ($criteria['field'] == 'parent')
- $field = 'id';
- else
- $field = $criteria['field'];
-
- $where .= ' AND '.$criteria['field'].' = \\\'\'.$db->escapeString($this->getVariable(\''.$field.'\')).\'\\\'';
- }
- break;
- }
- default:
- break;
- }
- }
-
- if ($search_rank && !$search)
- {
- throw new \miniSkelMarkupException("Le critère par points n'est possible que dans les boucles de recherche.");
- }
-
- if (trim($loopContent))
- {
- $loopStart .= '$row[\'url\'] = WWW_URL . $row[\'uri\']; ';
- }
-
- $query .= $where . ' ' . $order;
-
- if (!$limit || $limit > 100)
- $limit = 100;
-
- if ($limit)
- {
- $query .= ' LIMIT '.(is_numeric($begin) ? (int) $begin : '\'.$this->variables[\'debut_liste\'].\'').','.(int)$limit;
- }
-
- $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;');
-
- if ($search)
- {
- $out->append(1, 'if (trim($this->getVariable(\'recherche\'))) { ');
- }
-
- $out->append(1, '$result_'.$hash.' = $db->query(\''.$query.'\'); ');
- $out->append(1, '$nb_rows = $db->countRows($result_'.$hash.'); ');
-
- if ($search)
- {
- $out->append(1, '} else { $result_'.$hash.' = false; $nb_rows = 0; }');
- }
-
- $out->append(1, '$this->_vars[\''.$hash.'\'] = array(\'_self_hash\' => \''.$hash.'\', \'_parent_hash\' => $parent_hash, \'total_boucle\' => $nb_rows, \'compteur_boucle\' => 0);');
- $out->append(1, '$this->current =& $this->_vars[\''.$hash.'\']; ');
- $out->append(1, 'if ($nb_rows > 0):');
-
- if ($preContent)
- {
- $out->append(2, $this->parse($preContent, $loopName, self::PRE_CONTENT));
- }
-
- $out->append(1, 'while ($row = $result_'.$hash.'->fetchArray(SQLITE3_ASSOC)): ');
- $out->append(1, '$this->_vars[\''.$hash.'\'][\'compteur_boucle\'] += 1; ');
- $out->append(1, $loopStart);
- $out->append(1, '$this->_vars[\''.$hash.'\'] = array_merge($this->_vars[\''.$hash.'\'], $row); ');
-
- $out->append(2, $this->parseVariables($loopContent));
-
- $out->append(1, 'endwhile;');
-
- // we put the post-content after the loop content
- if ($postContent)
- {
- $out->append(2, $this->parse($postContent, $loopName, self::POST_CONTENT));
- }
-
- if ($altContent)
- {
- $out->append(1, 'else:');
- $out->append(2, $this->parse($altContent, $loopName, self::ALT_CONTENT));
- }
-
- $out->append(1, 'endif; ');
- $out->append(1, '$parent_hash = $this->_vars[\''.$hash.'\'][\'_parent_hash\']; ');
- $out->append(1, 'unset($result_'.$hash.', $nb_rows, $this->_vars[\''.$hash.'\']); ');
- $out->append(1, 'if ($parent_hash) { $this->current =& $this->_vars[$parent_hash]; $parent_hash = $this->current[\'_parent_hash\']; } ');
- $out->append(1, 'else { $this->current = null; }');
- $out->append(1, '$this->parent =& $parent_hash ? $this->_vars[$_parent_hash] : null;');
-
- return $out;
- }
-
- public function fetch($template, $no_display = false)
- {
- $this->currentTemplate = $template;
-
- $path = file_exists(GARRADIN_DATA_ROOT . '/squelettes/' . $template)
- ? GARRADIN_DATA_ROOT . '/squelettes/' . $template
- : GARRADIN_ROOT . '/squelettes-dist/' . $template;
-
- $tpl_id = basename(dirname($path)) . '/' . $template;
-
- if (!self::compile_check($tpl_id, $path))
- {
- if (!file_exists($path))
- {
- throw new \miniSkelMarkupException('Le squelette "'.$tpl_id.'" n\'existe pas.');
- }
-
- $content = file_get_contents($path);
- $content = strtr($content, array(' '<?php', '' => ''));
-
- $out = new Squelette_Snippet(2, $this->parse($content));
- $out->prepend(1, '/* '.$tpl_id.' */ '.
- 'namespace Garradin; $db = DB::getInstance(); '.
- 'if ($this->parent) $parent_hash = $this->parent[\'_self_hash\']; '. // For included files
- 'else $parent_hash = false;');
-
- if (!$no_display)
- {
- self::compile_store($tpl_id, $out);
- }
- }
-
- if (!$no_display)
- {
- require self::compile_get_path($tpl_id);
- }
- else
- {
- eval($tpl_id);
- }
-
- return null;
- }
-
- public function dispatchURI()
- {
- $uri = !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
-
- header('HTTP/1.1 200 OK', 200, true);
-
- if ($pos = strpos($uri, '?'))
- {
- $uri = substr($uri, 0, $pos);
- }
- else
- {
- // WWW_URI inclus toujours le slash final, mais on veut le conserver ici
- $uri = substr($uri, strlen(WWW_URI) - 1);
- }
-
- if ($uri == '/')
- {
- $skel = 'sommaire.html';
- }
- elseif ($uri == '/feed/atom/')
- {
- header('Content-Type: application/atom+xml');
- $skel = 'atom.xml';
- }
- elseif (substr($uri, -1) == '/')
- {
- $skel = 'rubrique.html';
- $_GET['uri'] = $_REQUEST['uri'] = substr($uri, 1, -1);
- }
- elseif (preg_match('!^/admin/!', $uri))
- {
- throw new UserException('Cette page n\'existe pas.');
- }
- else
- {
- $_GET['uri'] = $_REQUEST['uri'] = substr($uri, 1);
-
- if (preg_match('!^[\w\d_-]+$!i', $_GET['uri'])
- && file_exists(GARRADIN_DATA_ROOT . '/squelettes/' . strtolower($_GET['uri']) . '.html'))
- {
- $skel = strtolower($_GET['uri']) . '.html';
- }
- else
- {
- $skel = 'article.html';
- }
- }
-
- $this->display($skel);
- }
-
- static private function compile_get_path($path)
- {
- $hash = sha1($path);
- return GARRADIN_DATA_ROOT . '/cache/compiled/s_' . $hash . '.php';
- }
-
- static private function compile_check($tpl, $check)
- {
- if (!file_exists(self::compile_get_path($tpl)))
- return false;
-
- $time = filemtime(self::compile_get_path($tpl));
-
- if (empty($time))
- {
- return false;
- }
-
- if ($time < filemtime($check))
- return false;
- return $time;
- }
-
- static private function compile_store($tpl, $content)
- {
- $path = self::compile_get_path($tpl);
-
- if (!file_exists(dirname($path)))
- {
- mkdir(dirname($path));
- }
-
- file_put_contents($path, $content);
- return true;
- }
-
- static public function compile_clear($tpl)
- {
- $path = self::compile_get_path($tpl);
-
- if (file_exists($path))
- unlink($path);
-
- return true;
- }
-
- protected function getVariable($var)
- {
- if (isset($this->current[$var]))
- {
- return $this->current[$var];
- }
- elseif (isset($this->parent[$var]))
- {
- return $this->parent[$var];
- }
- elseif (isset($this->variables[$var]))
- {
- return $this->variables[$var];
- }
- elseif (isset($_REQUEST[$var]))
- {
- return $_REQUEST[$var];
- }
- else
- {
- return null;
- }
- }
-
- static public function getSource($template)
- {
- if (!preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!', $template))
- return false;
-
- $path = file_exists(GARRADIN_DATA_ROOT . '/squelettes/' . $template)
- ? GARRADIN_DATA_ROOT . '/squelettes/' . $template
- : GARRADIN_ROOT . '/squelettes-dist/' . $template;
-
- if (!file_exists($path))
- return false;
-
- return file_get_contents($path);
- }
-
- static public function editSource($template, $content)
- {
- if (!preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!', $template))
- return false;
-
- $path = GARRADIN_DATA_ROOT . '/squelettes/' . $template;
-
- return file_put_contents($path, $content);
- }
-
- static public function resetSource($template)
- {
- if (!preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!', $template))
- return false;
-
- if (file_exists(GARRADIN_DATA_ROOT . '/squelettes/' . $template))
- {
- unlink(GARRADIN_DATA_ROOT . '/squelettes/' . $template);
- }
-
- return true;
- }
-
- static public function listSources()
- {
- $sources = array();
-
- $dir = dir(GARRADIN_ROOT . '/squelettes-dist');
-
- while ($file = $dir->read())
- {
- if ($file[0] != '.')
- $sources[] = $file;
- }
-
- $dir->close();
-
- $dir = dir(GARRADIN_DATA_ROOT . '/squelettes');
-
- while ($file = $dir->read())
- {
- if ($file[0] != '.')
- $sources[] = $file;
- }
-
- $dir->close();
-
- $sources = array_unique($sources);
- sort($sources);
-
- return $sources;
- }
-
-}
-
-?>
DELETED include/class.transactions.php
Index: include/class.transactions.php
==================================================================
--- include/class.transactions.php
+++ include/class.transactions.php
@@ -1,141 +0,0 @@
-simpleQuerySingle('SELECT 1 FROM compta_categories WHERE id = ?;', false, (int) $data['id_categorie_compta']))
- {
- throw new UserException('Catégorie comptable inconnue');
- }
-
- $data['id_categorie_compta'] = (int) $data['id_categorie_compta'];
- }
- }
-
- /**
- * Ajouter une transaction
- * @param array $data Tableau des champs à insérer
- * @return integer ID de la transaction créée
- */
- public function add($data)
- {
- $db = DB::getInstance();
-
- $this->_checkFields($data);
-
- $db->simpleInsert('transactions', $data);
- $id = $db->lastInsertRowId();
-
- return $id;
- }
-
- /**
- * Modifier une transaction
- * @param integer $id ID de la transaction à modifier
- * @param array $data Tableau des champs à modifier
- * @return bool true si succès
- */
- public function edit($id, $data)
- {
- $db = DB::getInstance();
-
- $this->_checkFields($data);
-
- return $db->simpleUpdate('transactions', $data, 'id = \''.(int) $id.'\'');
- }
-
- /**
- * Supprimer une transaction
- * @param integer $id ID de la transaction à supprimer
- * @return integer true en cas de succès
- */
- public function delete($id)
- {
- $db = DB::getInstance();
-
- if ($db->simpleQuerySingle('SELECT 1 FROM membres_transactions WHERE id_transaction = ? LIMIT 1;', false, (int) $id))
- {
- throw new UserException('Il existe des transactions utilisant cette catégorie de transaction.');
- }
-
- return $db->simpleExec('DELETE FROM transactions WHERE id = ?;', (int) $id);
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT * FROM transactions WHERE id = ?;', true, (int) $id);
- }
-
- public function listByName()
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetch('SELECT * FROM transactions ORDER BY intitule;');
- }
-}
-
-?>
DELETED include/class.wiki.php
Index: include/class.wiki.php
==================================================================
--- include/class.wiki.php
+++ include/class.wiki.php
@@ -1,518 +0,0 @@
-simpleQuerySingle('SELECT 1 FROM wiki_pages WHERE id = ?;', false, $data['parent']))
- {
- $data['parent'] = 0;
- }
- }
-
- return true;
- }
-
- public function create($data = array())
- {
- $this->_checkFields($data);
- $db = DB::getInstance();
-
- if (!empty($data['uri']))
- {
- $data['uri'] = self::transformTitleToURI($data['uri']);
-
- if ($db->simpleQuerySingle('SELECT 1 FROM wiki_pages WHERE uri = ? LIMIT 1;', false, $data['uri']))
- {
- throw new UserException('Cette adresse de page est déjà utilisée pour une autre page, il faut en choisir une autre.');
- }
- }
- else
- {
- $data['uri'] = self::transformTitleToURI($data['titre']);
-
- if (!trim($data['uri']) || $db->simpleQuerySingle('SELECT 1 FROM wiki_pages WHERE uri = ? LIMIT 1;', false, $data['uri']))
- {
- $data['uri'] .= '_' . date('d-m-Y_H-i-s');
- }
- }
-
- $db->simpleInsert('wiki_pages', $data);
- $id = $db->lastInsertRowId();
-
- // On ne peut utiliser un trigger pour insérer dans la recherche
- // car les tables virtuelles font des opérations qui modifient
- // last_insert_rowid() et donc résultat incohérent
- $db->simpleInsert('wiki_recherche', array('id' => $id, 'titre' => $data['titre']));
-
- return $id;
- }
-
- public function edit($id, $data = array())
- {
- $db = DB::getInstance();
- $this->_checkFields($data);
-
- if (isset($data['uri']))
- {
- $data['uri'] = self::transformTitleToURI($data['uri']);
-
- if ($db->simpleQuerySingle('SELECT 1 FROM wiki_pages WHERE uri = ? AND id != ? LIMIT 1;', false, $data['uri'], (int)$id))
- {
- throw new UserException('Cette adresse de page est déjà utilisée pour une autre page, il faut en choisir une autre.');
- }
- }
-
- if (isset($data['droit_lecture']) && $data['droit_lecture'] >= self::LECTURE_CATEGORIE)
- {
- $data['droit_ecriture'] = $data['droit_lecture'];
- }
-
- if (isset($data['parent']) && (int)$data['parent'] == (int)$id)
- {
- $data['parent'] = 0;
- }
-
- $data['date_modification'] = new SQLite3_Instruction('CURRENT_TIMESTAMP');
-
- if (isset($data['date_creation']) && !($data['date_creation'] > 0))
- {
- unset($data['date_creation']);
- }
- else
- {
- $data['date_creation'] = new SQLite3_Instruction('datetime('.(int)$data['date_creation'].', \'unixepoch\')');
- }
-
- $db->simpleUpdate('wiki_pages', $data, 'id = '.(int)$id);
- return true;
- }
-
- public function delete($id)
- {
- $db = DB::getInstance();
-
- if ($db->simpleQuerySingle('SELECT COUNT(*) FROM wiki_pages WHERE parent = ?;', false, (int)$id))
- {
- return false;
- }
-
- $db->simpleExec('DELETE FROM wiki_revisions WHERE id_page = ?;', (int)$id);
- //$db->simpleExec('DELETE FROM wiki_suivi WHERE id_page = ?;', (int)$id); FIXME
- $db->simpleExec('DELETE FROM wiki_recherche WHERE id = ?;', (int)$id);
- $db->simpleExec('DELETE FROM wiki_pages WHERE id = ?;', (int)$id);
- return true;
- }
-
- public function get($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT *,
- strftime(\'%s\', date_creation) AS date_creation,
- strftime(\'%s\', date_modification) AS date_modification
- FROM wiki_pages WHERE id = ? LIMIT 1;', true, (int)$id);
- }
-
- public function getTitle($id)
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT titre FROM wiki_pages WHERE id = ? LIMIT 1;', false, (int)$id);
- }
-
- public function getRevision($id, $rev)
- {
- $db = DB::getInstance();
- // FIXME pagination au lieu de bloquer à 1000
- return $db->simpleQuerySingle('SELECT r.revision, r.modification, r.id_auteur, r.contenu,
- strftime(\'%s\', r.date) AS date, LENGTH(r.contenu) AS taille, m.nom AS nom_auteur,
- r.chiffrement
- FROM wiki_revisions AS r LEFT JOIN membres AS m ON m.id = r.id_auteur
- WHERE r.id_page = ? AND revision = ? LIMIT 1;', true, (int) $id, (int) $rev);
- }
-
- public function listRevisions($id)
- {
- $db = DB::getInstance();
- // FIXME pagination au lieu de bloquer à 1000
- return $db->simpleStatementFetch('SELECT r.revision, r.modification, r.id_auteur,
- strftime(\'%s\', r.date) AS date, LENGTH(r.contenu) AS taille, m.nom AS nom_auteur,
- LENGTH(r.contenu) - (SELECT LENGTH(contenu) FROM wiki_revisions WHERE id_page = r.id_page AND revision < r.revision ORDER BY revision DESC LIMIT 1)
- AS diff_taille, r.chiffrement
- FROM wiki_revisions AS r LEFT JOIN membres AS m ON m.id = r.id_auteur
- WHERE r.id_page = ? ORDER BY r.revision DESC LIMIT 1000;', SQLITE3_ASSOC, (int) $id);
- }
-
- public function editRevision($id, $revision_edition = 0, $data)
- {
- $db = DB::getInstance();
-
- $revision = $db->simpleQuerySingle('SELECT revision FROM wiki_pages WHERE id = ?;', false, (int)$id);
-
- // ?! L'ID fournit ne correspond à rien ?
- if ($revision === false)
- {
- throw new \RuntimeException('La page demandée n\'existe pas.');
- }
-
- // Pas de révision
- if ($revision == 0 && !trim($data['contenu']))
- {
- return true;
- }
-
- // Il faut obligatoirement fournir un ID d'auteur
- if (empty($data['id_auteur']) && $data['id_auteur'] !== null)
- {
- throw new \BadMethodCallException('Aucun ID auteur de fourni.');
- }
-
- $contenu = $db->simpleQuerySingle('SELECT contenu FROM wiki_revisions WHERE revision = ? AND id_page = ?;', false, (int)$revision, (int)$id);
-
- // Pas de changement au contenu, pas la peine d'enregistrer une nouvelle révision
- if (trim($contenu) == trim($data['contenu']))
- {
- return true;
- }
-
- // Révision sur laquelle est basée la nouvelle révision
- // utilisé pour vérifier que le contenu n'a pas été modifié depuis qu'on
- // a chargé la page d'édition
- if ($revision > $revision_edition)
- {
- throw new UserException('La page a été modifiée depuis le début de votre modification.');
- }
-
- if (empty($data['chiffrement']))
- $data['chiffrement'] = 0;
-
- if (!isset($data['modification']) || !trim($data['modification']))
- $data['modification'] = null;
-
- // Incrémentons le numéro de révision
- $revision++;
-
- $data['id_page'] = $id;
- $data['revision'] = $revision;
-
- $db->simpleInsert('wiki_revisions', $data);
- $db->simpleUpdate('wiki_pages', array(
- 'revision' => $revision,
- 'date_modification' => new SQLite3_Instruction('CURRENT_TIMESTAMP'),
- ), 'id = '.(int)$id);
-
- return true;
- }
-
- public function search($query)
- {
- $db = DB::getInstance();
- return $db->simpleStatementFetch('SELECT
- p.uri, r.*, snippet(wiki_recherche, "", "", "...", -1, -50) AS snippet,
- rank(matchinfo(wiki_recherche), 0, 1.0, 1.0) AS points
- FROM wiki_recherche AS r INNER JOIN wiki_pages AS p ON p.id = r.id
- WHERE '.$this->_getLectureClause('p.').' AND wiki_recherche MATCH \''.$db->escapeString($query).'\'
- ORDER BY points DESC LIMIT 0,50;');
- }
-
- public function setRestrictionCategorie($id, $droit_wiki)
- {
- $this->restriction_categorie = $id;
- $this->restriction_droit = $droit_wiki;
- return true;
- }
-
- protected function _getLectureClause($prefix = '')
- {
- if (is_null($this->restriction_categorie))
- {
- throw new \UnexpectedValueException('setRestrictionCategorie doit être appelé auparavant.');
- }
-
- if ($this->restriction_droit == Membres::DROIT_AUCUN)
- {
- throw new UserException('Vous n\'avez pas accès au wiki.');
- }
-
- if ($this->restriction_droit == Membres::DROIT_ADMIN)
- return '1';
-
- return '('.$prefix.'droit_lecture = '.self::LECTURE_NORMAL.' OR '.$prefix.'droit_lecture = '.self::LECTURE_PUBLIC.'
- OR '.$prefix.'droit_lecture = '.(int)$this->restriction_categorie.')';
- }
-
- public function canReadPage($lecture)
- {
- if (is_null($this->restriction_categorie))
- {
- throw new \UnexpectedValueException('setRestrictionCategorie doit être appelé auparavant.');
- }
-
- if ($this->restriction_droit < Membres::DROIT_ACCES)
- {
- return false;
- }
-
- if ($this->restriction_droit == Membres::DROIT_ADMIN
- || $lecture == self::LECTURE_NORMAL || $lecture == self::LECTURE_PUBLIC
- || $lecture == $this->restriction_categorie)
- return true;
-
- return false;
- }
-
- public function canWritePage($ecriture)
- {
- if (is_null($this->restriction_categorie))
- {
- throw new \UnexpectedValueException('setRestrictionCategorie doit être appelé auparavant.');
- }
-
- if ($this->restriction_droit < Membres::DROIT_ECRITURE)
- {
- return false;
- }
-
- if ($this->restriction_droit == Membres::DROIT_ADMIN
- || $ecriture == self::ECRITURE_NORMAL
- || $ecriture == $this->restriction_categorie)
- return true;
-
- return false;
- }
-
- public function getList($parent = 0)
- {
- $db = DB::getInstance();
-
- return $db->simpleStatementFetch(
- 'SELECT id, revision, uri, titre,
- strftime(\'%s\', date_creation) AS date_creation,
- strftime(\'%s\', date_modification) AS date_modification
- FROM wiki_pages
- WHERE parent = ? AND '.$this->_getLectureClause().'
- ORDER BY transliterate_to_ascii(titre) COLLATE NOCASE LIMIT 500;',
- SQLITE3_ASSOC,
- (int) $parent
- );
- }
-
- public function getById($id)
- {
- $db = DB::getInstance();
- $page = $db->simpleQuerySingle('SELECT *,
- strftime(\'%s\', date_creation) AS date_creation,
- strftime(\'%s\', date_modification) AS date_modification
- FROM wiki_pages
- WHERE id = ?;', true, (int)$id);
-
- if (!$page)
- {
- return false;
- }
-
- if ($page['revision'] > 0)
- {
- $page['contenu'] = $db->simpleQuerySingle('SELECT * FROM wiki_revisions
- WHERE id_page = ? AND revision = ?;', true, (int)$page['id'], (int)$page['revision']);
- }
- else
- {
- $page['contenu'] = false;
- }
-
- return $page;
- }
-
- public function getByURI($uri)
- {
- $db = DB::getInstance();
- $page = $db->simpleQuerySingle('SELECT *,
- strftime(\'%s\', date_creation) AS date_creation,
- strftime(\'%s\', date_modification) AS date_modification
- FROM wiki_pages
- WHERE uri = ?;', true, trim($uri));
-
- if (!$page)
- {
- return false;
- }
-
- if ($page['revision'] > 0)
- {
- $page['contenu'] = $db->simpleQuerySingle('SELECT * FROM wiki_revisions
- WHERE id_page = ? AND revision = ?;', true, (int)$page['id'], (int)$page['revision']);
- }
- else
- {
- $page['contenu'] = false;
- }
-
- return $page;
- }
-
- public function listRecentModifications($page = 1)
- {
- $begin = ($page - 1) * self::ITEMS_PER_PAGE;
-
- $db = DB::getInstance();
-
- return $db->simpleStatementFetch('SELECT *,
- strftime(\'%s\', date_creation) AS date_creation,
- strftime(\'%s\', date_modification) AS date_modification
- FROM wiki_pages
- WHERE '.$this->_getLectureClause().'
- ORDER BY date_modification DESC;', SQLITE3_ASSOC);
- }
-
- public function countRecentModifications()
- {
- $db = DB::getInstance();
- return $db->simpleQuerySingle('SELECT COUNT(*) FROM wiki_pages WHERE '.$this->_getLectureClause().';');
- }
-
- public function listBackBreadCrumbs($id)
- {
- if ($id == 0)
- return array();
-
- $db = DB::getInstance();
- $flat = array();
-
- while ($id > 0)
- {
- $res = $db->simpleQuerySingle('SELECT parent, titre, uri
- FROM wiki_pages WHERE id = ? LIMIT 1;', true, (int)$id);
-
- $flat[] = array(
- 'id' => $id,
- 'titre' => $res['titre'],
- 'uri' => $res['uri'],
- );
-
- $id = (int)$res['parent'];
- }
-
- return array_reverse($flat);
- }
-
- public function listBackParentTree($id)
- {
- $db = DB::getInstance();
- $flat = array(
- array(
- 'id' => 0,
- 'parent' => null,
- 'titre' => 'Racine',
- 'children' => $db->simpleStatementFetchAssocKey('SELECT id, parent, titre FROM wiki_pages
- WHERE parent = ? ORDER BY transliterate_to_ascii(titre) COLLATE NOCASE;',
- SQLITE3_ASSOC, 0)
- )
- );
-
- do
- {
- $parent = $db->simpleQuerySingle('SELECT parent FROM wiki_pages WHERE id = ? LIMIT 1;', false, (int)$id);
-
- $flat[$id] = array(
- 'id' => $id,
- 'parent' => $id ? (int)$parent : null,
- 'titre' => $id ? (string)$db->simpleQuerySingle('SELECT titre FROM wiki_pages WHERE id = ? LIMIT 1;', false, (int)$id) : 'Racine',
- 'children' => $db->simpleStatementFetchAssocKey('SELECT id, parent, titre FROM wiki_pages
- WHERE parent = ? ORDER BY transliterate_to_ascii(titre) COLLATE NOCASE;',
- SQLITE3_ASSOC, (int)$id)
- );
-
- $id = (int)$parent;
- }
- while ($id != 0);
-
- $tree = array();
- foreach ($flat as $id=>&$node)
- {
- if (is_null($node['parent']))
- {
- $tree[$id] = &$node;
- }
- else
- {
- if (!isset($flat[$node['parent']]['children']))
- {
- $flat[$node['parent']]['children'] = array();
- }
-
- $flat[$node['parent']]['children'][$id] = &$node;
- }
- }
-
- return $tree;
- }
-}
-
-?>
DELETED include/data/0.4.0.sql
Index: include/data/0.4.0.sql
==================================================================
--- include/data/0.4.0.sql
+++ include/data/0.4.0.sql
@@ -1,103 +0,0 @@
-CREATE TABLE compta_exercices
--- Exercices
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
-
- debut TEXT NOT NULL DEFAULT CURRENT_DATE,
- fin TEXT NULL DEFAULT NULL,
-
- clos INTEGER NOT NULL DEFAULT 0
-);
-
-
-CREATE TABLE compta_comptes
--- Plan comptable
-(
- id TEXT PRIMARY KEY,
- parent TEXT NOT NULL DEFAULT 0,
-
- libelle TEXT NOT NULL,
-
- position INTEGER NOT NULL, -- position actif/passif/charge/produit
- plan_comptable INTEGER NOT NULL DEFAULT 1 -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
-);
-
-CREATE INDEX compta_comptes_parent ON compta_comptes (parent);
-
-CREATE TABLE compta_comptes_bancaires
--- Comptes bancaires
-(
- id TEXT PRIMARY KEY,
-
- banque TEXT NOT NULL,
-
- iban TEXT,
- bic TEXT,
-
- FOREIGN KEY(id) REFERENCES compta_comptes(id)
-);
-
-CREATE TABLE compta_journal
--- Journal des opérations comptables
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
- remarques TEXT,
- numero_piece TEXT, -- N° de pièce comptable
-
- montant REAL,
-
- date TEXT DEFAULT CURRENT_DATE,
- moyen_paiement TEXT DEFAULT NULL,
- numero_cheque TEXT DEFAULT NULL,
-
- compte_debit INTEGER, -- N° du compte dans le plan
- compte_credit INTEGER, -- N° du compte dans le plan
-
- id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
- id_auteur INTEGER NOT NULL,
- id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
-
- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
- FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
- FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
- FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
- FOREIGN KEY(id_auteur) REFERENCES membres(id),
- FOREIGN KEY(id_categorie) REFERENCES compta_categories(id)
-);
-
-CREATE INDEX compta_operations_exercice ON compta_journal (id_exercice);
-CREATE INDEX compta_operations_date ON compta_journal (date);
-CREATE INDEX compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
-CREATE INDEX compta_operations_auteur ON compta_journal (id_auteur);
-
-CREATE TABLE compta_moyens_paiement
--- Moyens de paiement
-(
- code TEXT PRIMARY KEY,
- nom TEXT
-);
-
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');
-
-CREATE TABLE compta_categories
--- Catégories pour simplifier le plan comptable
-(
- id INTEGER PRIMARY KEY,
- type INTEGER DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)
-
- intitule TEXT NOT NULL,
- description TEXT,
-
- compte TEXT NOT NULL, -- Compte affecté par cette catégorie
-
- FOREIGN KEY(compte) REFERENCES compta_comptes(id)
-);
DELETED include/data/0.4.3.sql
Index: include/data/0.4.3.sql
==================================================================
--- include/data/0.4.3.sql
+++ include/data/0.4.3.sql
@@ -1,79 +0,0 @@
-DROP TABLE compta_exercices;
-
-CREATE TABLE compta_exercices
--- Exercices
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
-
- debut TEXT NOT NULL DEFAULT CURRENT_DATE,
- fin TEXT NULL DEFAULT NULL,
-
- cloture INTEGER NOT NULL DEFAULT 0
-);
-
-INSERT INTO compta_exercices (libelle, debut, fin, cloture)
- VALUES (
- 'Premier exercice',
- (CASE WHEN
- (SELECT strftime('%Y-01-01', date) FROM compta_journal ORDER BY date ASC LIMIT 1)
- IS NOT NULL THEN (SELECT strftime('%Y-01-01', date) FROM compta_journal ORDER BY date ASC LIMIT 1)
- ELSE strftime('%Y-01-01', 'now') END
- ),
- (CASE WHEN
- (SELECT strftime('%Y-12-31', date) FROM compta_journal ORDER BY date DESC LIMIT 1)
- IS NOT NULL THEN (SELECT strftime('%Y-12-31', date) FROM compta_journal ORDER BY date DESC LIMIT 1)
- ELSE strftime('%Y-12-31', 'now') END
- ),
- 0
- );
-
-BEGIN;
-ALTER TABLE compta_journal RENAME TO old_compta_journal;
-DROP INDEX compta_operations_exercice;
-DROP INDEX compta_operations_date;
-DROP INDEX compta_operations_comptes;
-DROP INDEX compta_operations_auteur;
-
-CREATE TABLE compta_journal
--- Journal des opérations comptables
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
- remarques TEXT,
- numero_piece TEXT, -- N° de pièce comptable
-
- montant REAL,
-
- date TEXT DEFAULT CURRENT_DATE,
- moyen_paiement TEXT DEFAULT NULL,
- numero_cheque TEXT DEFAULT NULL,
-
- compte_debit INTEGER, -- N° du compte dans le plan
- compte_credit INTEGER, -- N° du compte dans le plan
-
- id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
- id_auteur INTEGER NULL,
- id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
-
- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
- FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
- FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
- FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
- FOREIGN KEY(id_auteur) REFERENCES membres(id),
- FOREIGN KEY(id_categorie) REFERENCES compta_categories(id)
-);
-
-CREATE INDEX compta_operations_exercice ON compta_journal (id_exercice);
-CREATE INDEX compta_operations_date ON compta_journal (date);
-CREATE INDEX compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
-CREATE INDEX compta_operations_auteur ON compta_journal (id_auteur);
-
-INSERT INTO compta_journal SELECT * FROM old_compta_journal;
-
-UPDATE compta_journal SET id_exercice = 1;
-
-DROP TABLE old_compta_journal;
-END;
DELETED include/data/0.6.0.sql
Index: include/data/0.6.0.sql
==================================================================
--- include/data/0.6.0.sql
+++ include/data/0.6.0.sql
@@ -1,112 +0,0 @@
--- nouveau moyen de paiement
---INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
-
-CREATE TABLE transactions
--- Paiements possibles
-(
- id INTEGER PRIMARY KEY,
- id_categorie_compta INTEGER NULL, -- NULL si le type n'est pas associé automatiquement à la compta
-
- intitule TEXT NOT NULL,
- description TEXT NOT NULL,
- montant REAL NOT NULL,
-
- duree INTEGER NULL, -- En jours
- debut TEXT NULL, -- timestamp
- fin TEXT NULL,
-
- FOREIGN KEY (id_categorie_compta) REFERENCES compta_categories (id)
-);
-
-CREATE TABLE rappels
--- Rappels de devoir renouveller une transaction
-(
- id INTEGER PRIMARY KEY,
- id_transaction INTEGER NULL,
-
- delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel
-
- sujet TEXT NOT NULL,
- texte TEXT NOT NULL,
-
- FOREIGN KEY (id_transaction) REFERENCES transactions (id)
-);
-
-CREATE TABLE rappels_envoyes
--- Enregistrement des rappels envoyés à qui et quand
-(
- id_membre INTEGER NOT NULL,
- id_rappel INTEGER NOT NULL,
- date TEXT NOT NULL DEFAUT CURRENT_TIMESTAMP,
- media INTEGER NOT NULL, -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
-
- FOREIGN KEY (id_membre) REFERENCES membres (id),
- FOREIGN KEY (id_rappel) REFERENCES rappels (id),
-
- PRIMARY KEY(id_membre, id_rappel, date)
-);
-
-CREATE TABLE membres_transactions
--- Paiements enregistrés
-(
- id_membre INTEGER NOT NULL,
- id_transaction INTEGER NULL, -- NULL si n'est pas relié à une transaction prévue
-
- libelle TEXT NULL,
-
- date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
- montant REAL NOT NULL,
-
- FOREIGN KEY (id_membre) REFERENCES membres (id),
- FOREIGN KEY (id_transaction) REFERENCES transactions (id)
-);
-
-CREATE TABLE membres_transactions_operations
--- Liaison paiements enregistrés avec écritures comptables
-(
- id_operation INTEGER NOT NULL,
- id_membre_transaction INTEGER NOT NULL,
-
- FOREIGN KEY (id_operation) REFERENCES compta_journal (id),
- FOREIGN KEY (id_membre_transaction) REFERENCES membres_transactions (id)
-);
-
--- Mise à jour des catégories
-
-CREATE TABLE membres_categories_tmp
--- Catégories de membres
-(
- id INTEGER PRIMARY KEY,
- nom TEXT,
- description TEXT,
-
- droit_wiki INT DEFAULT 1,
- droit_membres INT DEFAULT 1,
- droit_compta INT DEFAULT 1,
- droit_inscription INT DEFAULT 0,
- droit_connexion INT DEFAULT 1,
- droit_config INT DEFAULT 0,
- cacher INT DEFAULT 0,
-
- id_transaction_obligatoire INTEGER NULL,
-
- FOREIGN KEY (id_transaction_obligatoire) REFERENCES transactions (id)
-);
-
--- Remise des anciennes infos
-INSERT INTO membres_categories_tmp SELECT id, nom, description, droit_wiki, droit_membres,
- droit_compta, droit_inscription, droit_connexion, droit_config, cacher FROM membres_categories;
-
--- Conversion des cotisations de catégories en transactions
-INSERT INTO transactions (id_categorie_comptable, intitule, montant, duree)
- SELECT
- (SELECT id FROM compta_categories WHERE compte = 756 LIMIT 1), -- Numéro de catégorie comptable
- nom, montant_cotisation, duree_cotisation
- FROM membres_categories;
-
--- Suppression de l'ancienne table et renommage de la nouvelle
-DROP TABLE membres_categories;
-ALTER TABLE membres_categories_tmp RENAME TO membres_categories;
-
--- Ajout id transaction aux écritures comptables
-ALTER TABLE compta_operations ADD COLUMN id_transaction INTEGER NULL REFERENCES transactions (id);
DELETED include/data/categories_comptables.sql
Index: include/data/categories_comptables.sql
==================================================================
--- include/data/categories_comptables.sql
+++ include/data/categories_comptables.sql
@@ -1,22 +0,0 @@
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Prestations de service','','604');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Achat de marchandises à vendre','Marchandises destinées à être revendues en l''état.','607');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Achat de fournitures consommables','','6068');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Publicité et relations publiques','','623');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais de déplacement des membres','Billet SNCF, remboursement de frais kilométrique, etc.','625');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Locations','Locations versées pour un local ou du matériel.','613');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Fournitures non stockables : eau, électricité...','Facture d''eau, d''opérateur électrique, etc.','6061');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Fournitures administratives','Cartouches d''encre, papier, matériel bureautique, etc.','6064');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais d''actes et de contentieux','Insertion au Journal Officiel, frais de justice, etc.','6227');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Frais postaux et télécommunications','Facture d''accès à Internet, timbres, etc.','626');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Prime d''assurance','','616');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Services bancaires','','627');
-INSERT INTO "compta_categories" VALUES(NULL,-1,'Divers','','658');
-
-INSERT INTO "compta_categories" VALUES(NULL,1,'Vente de produits finis','Vente de produits fabriqués par l''association.','701');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Prestation de service','','706');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Revente de marchandises','','707');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Manifestations diverses','Revenus provenant de manifestations au profit de l''association : droit d''entrée, location d''emplacement en vide grenier, ventes, etc.','7780');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Cotisations','','756');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Dons et collectes','','754');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Subventions','','740');
-INSERT INTO "compta_categories" VALUES(NULL,1,'Divers','','758');
DELETED include/data/champs_membres.ini
Index: include/data/champs_membres.ini
==================================================================
--- include/data/champs_membres.ini
+++ include/data/champs_membres.ini
@@ -1,136 +0,0 @@
-; Ce fichier contient la configuration par défaut des champs des fiches membres.
-; La configuration est ensuite enregistrée au format INI dans la table
-; config de la base de données.
-;
-; Syntaxe :
-;
-; [nom_du_champ] ; Nom unique du champ, ne peut contenir que des lettres et des tirets bas
-; type = text
-; title = "Super champ trop cool"
-; mandatory = true
-; editable = false
-;
-; Description des options possibles pour chaque champ :
-;
-; type: (défaut: text) OBLIGATOIRE
-; certains types gérés par de HTML5 :
-; text, number, date, datetime, url, email, checkbox, file, password, tel
-; champs spécifiques :
-; - country = sélecteur de pays
-; - textarea = texte multi lignes
-; - multiple = multiples cases à cocher (jusqu'à 32, binaire)
-; - select = un choix parmis plusieurs
-; title: OBLIGATOIRE
-; Titre du champ
-; help:
-; Texte d'aide sur les fiches membres
-; options[]:
-; pour définir les options d'un champ de type select ou multiple
-; editable:
-; true = modifiable par le membre
-; false = modifiable uniquement par un admin (défaut)
-; mandatory:
-; true = obligatoire, la fiche membre ne pourra être enregistrée si ce champ est vide
-; false = facultatif (défaut)
-; private:
-; true = non visible par le membre lui-même
-; false = visible par le membre (défaut)
-; list_row:
-; Si absent ou zéro ('0') ou false, ce champ n'apparaîtra pas dans la liste des membres
-; Si présent et un chiffre supérieur à 0, alors le champ apparaîtra dans la liste des membres
-; dans l'ordre défini par le chiffre (si nom est à 2 et email à 1, alors email sera
-; la première colonne et nom la seconde)
-; install:
-; true = sera ajouté aux fiches membres à l'installation
-; false = sera seulement présent dans les champs supplémentaires possibles (défaut)
-
-[nom]
-type = text
-title = "Nom & prénom"
-mandatory = true
-install = true
-editable = true
-list_row = 1
-
-[email]
-; ce champ est obligatoirement présent et de type 'email'
-type = email
-title = "Adresse E-Mail"
-mandatory = true
-install = true
-editable = true
-
-[passe]
-; ce champ est obligatoirement présent et de type 'password'
-; le titre ne peut être modifié
-type = password
-mandatory = true
-install = true
-editable = true
-
-[adresse]
-type = textarea
-title = "Adresse postale"
-help = "Indiquer ici le numéro, le type de voie, etc."
-install = true
-editable = true
-
-[code_postal]
-type = text
-title = "Code postal"
-install = true
-editable = true
-list_row = 2
-
-[ville]
-type = text
-title = "Ville"
-install = true
-editable = true
-list_row = 3
-
-[pays]
-type = country
-title = "Pays"
-install = true
-editable = true
-
-[telephone]
-type = tel
-title = "Numéro de téléphone"
-install = true
-editable = true
-
-[lettre_infos]
-type = checkbox
-title = "Inscription à la lettre d'information"
-install = true
-editable = true
-
-[groupe_travail]
-type = multiple
-title = "Groupes de travail"
-editable = false
-options[] = "Télécoms"
-options[] = "Trésorerie"
-options[] = "Relations publiques"
-options[] = "Communication presse"
-options[] = "Organisation d'événements"
-
-[date_naissance]
-type = date
-title = "Date de naissance"
-editable = true
-
-[notes]
-type = textarea
-title = "Notes"
-editable = false
-private = true
-
-[date_inscription]
-type = date
-title = "Date d'inscription"
-editable = false
-mandatory = true
-private = true
DELETED include/data/plan_comptable.json
Index: include/data/plan_comptable.json
==================================================================
--- include/data/plan_comptable.json
+++ include/data/plan_comptable.json
@@ -1,1941 +0,0 @@
-{
- "1":
- {
- "code": 1,
- "nom": "Classe 1 — Comptes de capitaux (Fonds propres, emprunts et dettes assimilés)",
- "parent": 0,
- "position": 1
- },
- "10":
- {
- "code": 10,
- "nom": "FONDS ASSOCIATIFS ET RÉSERVES",
- "parent": 1,
- "position": 1
- },
- "102":
- {
- "code": 102,
- "nom": "Fonds associatif sans droit de reprise",
- "parent": 10,
- "position": 1
- },
- "1021":
- {
- "code": 1021,
- "nom": "Valeur du patrimoine intégré",
- "parent": 102,
- "position": 1
- },
- "1022":
- {
- "code": 1022,
- "nom": "Fonds statutaire",
- "parent": 102,
- "position": 1
- },
- "1024":
- {
- "code": 1024,
- "nom": "Apports sans droit de reprise",
- "parent": 102,
- "position": 1
- },
- "103":
- {
- "code": 103,
- "nom": "Fonds associatif avec droit de reprise",
- "parent": 10,
- "position": 1
- },
- "1034":
- {
- "code": 1034,
- "nom": "Apports avec droit de reprise",
- "parent": 103,
- "position": 1
- },
- "105":
- {
- "code": 105,
- "nom": "Écarts de réévaluation",
- "parent": 10,
- "position": 1
- },
- "106":
- {
- "code": 106,
- "nom": "Réserves",
- "parent": 10,
- "position": 1
- },
- "1063":
- {
- "code": 1063,
- "nom": "Réserves statutaires ou contractuelles",
- "parent": 106,
- "position": 1
- },
- "1064":
- {
- "code": 1064,
- "nom": "Réserves réglementées",
- "parent": 106,
- "position": 1
- },
- "1068":
- {
- "code": 1068,
- "nom": "Autres réserves (dont réserves pour projet associatif)",
- "parent": 106,
- "position": 1
- },
- "11":
- {
- "code": 11,
- "nom": "REPORT À NOUVEAU",
- "parent": 1,
- "position": 1
- },
- "110":
- {
- "code": 110,
- "nom": "Report à nouveau (Solde créditeur)",
- "parent": 11,
- "position": 1
- },
- "119":
- {
- "code": 119,
- "nom": "Report à nouveau (Solde débiteur)",
- "parent": 11,
- "position": 1
- },
- "12":
- {
- "code": 12,
- "nom": "RÉSULTAT NET DE L'EXERCICE",
- "parent": 1,
- "position": 3
- },
- "120":
- {
- "code": 120,
- "nom": "Résultat de l'exercice (excédent)",
- "parent": 12,
- "position": 1
- },
- "129":
- {
- "code": 129,
- "nom": "Résultat de l'exercice (déficit)",
- "parent": 12,
- "position": 2
- },
- "13":
- {
- "code": 13,
- "nom": "SUBVENTIONS D'INVESTISSEMENT AFFECTÉES A DES BIENS NON RENOUVELABLES",
- "parent": 1,
- "position": 1
- },
- "131":
- {
- "code": 131,
- "nom": "Subventions d'investissement (renouvelables)",
- "parent": 13,
- "position": 1
- },
- "139":
- {
- "code": 139,
- "nom": "Subventions d'investissement inscrites au compte de résultat",
- "parent": 13,
- "position": 2
- },
- "14":
- {
- "code": 14,
- "nom": "PROVISIONS REGLEMENTÉES",
- "parent": 1,
- "position": 1
- },
- "15":
- {
- "code": 15,
- "nom": "PROVISIONS",
- "parent": 1,
- "position": 1
- },
- "151":
- {
- "code": 151,
- "nom": "Provisions pour risques",
- "parent": 15,
- "position": 1
- },
- "157":
- {
- "code": 157,
- "nom": "Provisions pour charges à répartir sur plusieurs exercices",
- "parent": 15,
- "position": 1
- },
- "158":
- {
- "code": 158,
- "nom": "Autres provisions pour charges",
- "parent": 15,
- "position": 1
- },
- "16":
- {
- "code": 16,
- "nom": "EMPRUNTS ET DETTES ASSIMILÉES",
- "parent": 1,
- "position": 1
- },
- "164":
- {
- "code": 164,
- "nom": "Emprunts auprès des établissements de crédits",
- "parent": 16,
- "position": 1
- },
- "165":
- {
- "code": 165,
- "nom": "Dépôts et cautionnements reçus",
- "parent": 16,
- "position": 1
- },
- "167":
- {
- "code": 167,
- "nom": "Emprunts et dettes assorties de conditions particulières",
- "parent": 16,
- "position": 1
- },
- "168":
- {
- "code": 168,
- "nom": "Autres emprunts et dettes assimilés",
- "parent": 16,
- "position": 1
- },
- "17":
- {
- "code": 17,
- "nom": "DETTES RATTACHÉES À DES PARTICIPATIONS",
- "parent": 1,
- "position": 1
- },
- "18":
- {
- "code": 18,
- "nom": "COMPTES DE LIAISON DES ÉTABLISSEMENTS",
- "parent": 1,
- "position": 1
- },
- "181":
- {
- "code": 181,
- "nom": "Apports permanents entre siège social et établissements",
- "parent": 18,
- "position": 1
- },
- "185":
- {
- "code": 185,
- "nom": "Biens et prestations de services échangés entre établissements et siège social",
- "parent": 18,
- "position": 1
- },
- "186":
- {
- "code": 186,
- "nom": "Biens et prestations de services échangés entre établissements (charges)",
- "parent": 18,
- "position": 1
- },
- "187":
- {
- "code": 187,
- "nom": "Biens et prestations de services échangés entre établissements (produits)",
- "parent": 18,
- "position": 1
- },
- "19":
- {
- "code": 19,
- "nom": "FONDS DÉDIÉS",
- "parent": 1,
- "position": 1
- },
- "194":
- {
- "code": 194,
- "nom": "Fonds dédiés sur subventions de fonctionnement",
- "parent": 19,
- "position": 1
- },
- "195":
- {
- "code": 195,
- "nom": "Fonds dédiés sur dons manuels affectés",
- "parent": 19,
- "position": 1
- },
- "197":
- {
- "code": 197,
- "nom": "Fonds dédiés sur legs et donations affectés",
- "parent": 19,
- "position": 1
- },
- "198":
- {
- "code": 198,
- "nom": "Excédent disponible après affectation au projet associatif",
- "parent": 19,
- "position": 1
- },
- "199":
- {
- "code": 199,
- "nom": "Reprise des fonds affectés au projet associatif",
- "parent": 19,
- "position": 1
- },
- "2":
- {
- "code": 2,
- "nom": "Classe 2 — Comptes d'immobilisations",
- "parent": 0,
- "position": 2
- },
- "20":
- {
- "code": 20,
- "nom": "IMMOBILISATIONS INCORPORELLES",
- "parent": 2,
- "position": 2
- },
- "200":
- {
- "code": 200,
- "nom": "Immobilisations incorporelles",
- "parent": 20,
- "position": 2
- },
- "21":
- {
- "code": 21,
- "nom": "IMMOBILISATIONS CORPORELLES",
- "parent": 2,
- "position": 2
- },
- "210":
- {
- "code": 210,
- "nom": "Investissements",
- "parent": 21,
- "position": 2
- },
- "22":
- {
- "code": 22,
- "nom": "IMMOBILISATIONS GREVÉES DE DROITS",
- "parent": 2,
- "position": 2
- },
- "228":
- {
- "code": 228,
- "nom": "Immobilisations grevées de droits",
- "parent": 22,
- "position": 2
- },
- "229":
- {
- "code": 229,
- "nom": "Droits des propriétaires",
- "parent": 22,
- "position": 2
- },
- "26":
- {
- "code": 26,
- "nom": "PARTICIPATIONS ET CRÉANCES RATTACHÉES A DES PARTICIPATIONS",
- "parent": 2,
- "position": 2
- },
- "261":
- {
- "code": 261,
- "nom": "Titres de participation",
- "parent": 26,
- "position": 2
- },
- "27":
- {
- "code": 27,
- "nom": "AUTRES IMMOBILISATIONS FINANCIÈRES",
- "parent": 2,
- "position": 2
- },
- "270":
- {
- "code": 270,
- "nom": "Participations financières",
- "parent": 27,
- "position": 2
- },
- "275":
- {
- "code": 275,
- "nom": "Dépôts et cautionnements versés",
- "parent": 27,
- "position": 2
- },
- "28":
- {
- "code": 28,
- "nom": "AMORTISSEMENTS DES IMMOBILISATIONS",
- "parent": 2,
- "position": 2
- },
- "280":
- {
- "code": 280,
- "nom": "Amortissements des immobilisations incorporelles",
- "parent": 28,
- "position": 2
- },
- "281":
- {
- "code": 281,
- "nom": "Amortissements des immobilisations corporelles",
- "parent": 28,
- "position": 2
- },
- "29":
- {
- "code": 29,
- "nom": "DÉPRÉCIATION DES IMMOBILISATIONS",
- "parent": 2,
- "position": 2
- },
- "290":
- {
- "code": 290,
- "nom": "Dépréciation des immobilisations incorporelles",
- "parent": 29,
- "position": 2
- },
- "291":
- {
- "code": 291,
- "nom": "Dépréciation des immobilisations corporelles",
- "parent": 29,
- "position": 2
- },
- "3":
- {
- "code": 3,
- "nom": "Classe 3 — Comptes de stocks",
- "parent": 0,
- "position": 2
- },
- "31":
- {
- "code": 31,
- "nom": "MATIERES PREMIERES ET FOURNITURES",
- "parent": 3,
- "position": 2
- },
- "311":
- {
- "code": 311,
- "nom": "Matières",
- "parent": 31,
- "position": 2
- },
- "317":
- {
- "code": 317,
- "nom": "Fournitures",
- "parent": 31,
- "position": 2
- },
- "32":
- {
- "code": 32,
- "nom": "AUTRES APPROVISIONNEMENTS",
- "parent": 3,
- "position": 2
- },
- "321":
- {
- "code": 321,
- "nom": "Matières consommables",
- "parent": 32,
- "position": 2
- },
- "322":
- {
- "code": 322,
- "nom": "Fournitures consommables",
- "parent": 32,
- "position": 2
- },
- "33":
- {
- "code": 33,
- "nom": "EN-COURS DE PRODUCTION DE BIENS",
- "parent": 3,
- "position": 2
- },
- "331":
- {
- "code": 331,
- "nom": "Produits en cours",
- "parent": 33,
- "position": 2
- },
- "335":
- {
- "code": 335,
- "nom": "Travaux en cours",
- "parent": 33,
- "position": 2
- },
- "34":
- {
- "code": 34,
- "nom": "EN-COURS DE PRODUCTION DE SERVICES",
- "parent": 3,
- "position": 2
- },
- "35":
- {
- "code": 35,
- "nom": "STOCKS DE PRODUITS",
- "parent": 3,
- "position": 2
- },
- "351":
- {
- "code": 351,
- "nom": "Produits intermédiaires",
- "parent": 35,
- "position": 2
- },
- "355":
- {
- "code": 355,
- "nom": "Produits finis",
- "parent": 35,
- "position": 2
- },
- "358":
- {
- "code": 358,
- "nom": "Produits résiduels",
- "parent": 35,
- "position": 2
- },
- "3581":
- {
- "code": 3581,
- "nom": "Déchets",
- "parent": 358,
- "position": 2
- },
- "3585":
- {
- "code": 3585,
- "nom": "Rebuts",
- "parent": 358,
- "position": 2
- },
- "3586":
- {
- "code": 3586,
- "nom": "Matière de récupération",
- "parent": 358,
- "position": 2
- },
- "37":
- {
- "code": 37,
- "nom": "STOCKS DE MARCHANDISES",
- "parent": 3,
- "position": 2
- },
- "370":
- {
- "code": 370,
- "nom": "Autres stocks de marchandises",
- "parent": 37,
- "position": 2
- },
- "39":
- {
- "code": 39,
- "nom": "PROVISIONS POUR DEPRECIATION DES STOCKS ET EN-COURS",
- "parent": 3,
- "position": 2
- },
- "391":
- {
- "code": 391,
- "nom": "Provisions pour dépréciation des matières premières et fournitures",
- "parent": 39,
- "position": 2
- },
- "4":
- {
- "code": 4,
- "nom": "Classe 4 — Comptes de tiers",
- "parent": 0,
- "position": 3
- },
- "40":
- {
- "code": 40,
- "nom": "FOURNISSEURS ET COMPTES RATTACHÉS",
- "parent": 4,
- "position": 3
- },
- "401":
- {
- "code": 401,
- "nom": "Fournisseurs",
- "parent": 40,
- "position": 1
- },
- "4010":
- {
- "code": 4010,
- "nom": "Autres fournisseurs",
- "parent": 401,
- "position": 1
- },
- "408":
- {
- "code": 408,
- "nom": "Fournisseurs - Factures non parvenues",
- "parent": 40,
- "position": 2
- },
- "409":
- {
- "code": 409,
- "nom": "Avances aux fournisseurs",
- "parent": 40,
- "position": 2
- },
- "41":
- {
- "code": 41,
- "nom": "USAGERS ET COMPTES RATTACHÉS",
- "parent": 4,
- "position": 3
- },
- "411":
- {
- "code": 411,
- "nom": "Usagers",
- "parent": 41,
- "position": 1
- },
- "4110":
- {
- "code": 4110,
- "nom": "Autres usagers",
- "parent": 411,
- "position": 1
- },
- "419":
- {
- "code": 419,
- "nom": "Avances aux usagers",
- "parent": 41,
- "position": 2
- },
- "42":
- {
- "code": 42,
- "nom": "PERSONNEL ET COMPTES RATTACHÉS",
- "parent": 4,
- "position": 3
- },
- "421":
- {
- "code": 421,
- "nom": "Personnel - Rémunérations dues",
- "parent": 42,
- "position": 1
- },
- "4210":
- {
- "code": 4210,
- "nom": "Autres membres du personnel",
- "parent": 421,
- "position": 1
- },
- "425":
- {
- "code": 425,
- "nom": "Personnel - Avances et acomptes",
- "parent": 42,
- "position": 2
- },
- "428":
- {
- "code": 428,
- "nom": "Personnel - Charges à payer et produits à recevoir",
- "parent": 42,
- "position": 2
- },
- "43":
- {
- "code": 43,
- "nom": "SÉCURITÉ SOCIALE ET AUTRES ORGANISMES SOCIAUX",
- "parent": 4,
- "position": 3
- },
- "430":
- {
- "code": 430,
- "nom": "Dettes et crédits envers les organismes sociaux",
- "parent": 43,
- "position": 1
- },
- "431":
- {
- "code": 431,
- "nom": "Sécurité sociale",
- "parent": 43,
- "position": 2
- },
- "437":
- {
- "code": 437,
- "nom": "Autres organismes sociaux",
- "parent": 43,
- "position": 2
- },
- "4372":
- {
- "code": 4372,
- "nom": "Mutuelles",
- "parent": 437,
- "position": 2
- },
- "4373":
- {
- "code": 4373,
- "nom": "Caisse de retraite et de prévoyance",
- "parent": 437,
- "position": 2
- },
- "4374":
- {
- "code": 4374,
- "nom": "Caisse d'allocations de chômage - Pôle emploi",
- "parent": 437,
- "position": 2
- },
- "4375":
- {
- "code": 4375,
- "nom": "AGESSA",
- "parent": 437,
- "position": 2
- },
- "4378":
- {
- "code": 4378,
- "nom": "Autres organismes sociaux - Divers",
- "parent": 437,
- "position": 2
- },
- "438":
- {
- "code": 438,
- "nom": "Organismes sociaux - Charges à payer et produits à recevoir",
- "parent": 43,
- "position": 2
- },
- "4382":
- {
- "code": 4382,
- "nom": "Charges sociales sur congés à payer",
- "parent": 438,
- "position": 2
- },
- "4386":
- {
- "code": 4386,
- "nom": "Autres charges à payer",
- "parent": 438,
- "position": 2
- },
- "4387":
- {
- "code": 4387,
- "nom": "Produits à recevoir",
- "parent": 438,
- "position": 2
- },
- "439":
- {
- "code": 439,
- "nom": "Avances auprès des organismes sociaux",
- "parent": 43,
- "position": 2
- },
- "44":
- {
- "code": 44,
- "nom": "ÉTAT ET AUTRES COLLECTIVITÉS PUBLIQUES",
- "parent": 4,
- "position": 3
- },
- "441":
- {
- "code": 441,
- "nom": "État - Subventions à recevoir",
- "parent": 44,
- "position": 2
- },
- "4411":
- {
- "code": 4411,
- "nom": "Subventions d'investissement",
- "parent": 441,
- "position": 2
- },
- "4417":
- {
- "code": 4417,
- "nom": "Subventions d'exploitation",
- "parent": 441,
- "position": 2
- },
- "4418":
- {
- "code": 4418,
- "nom": "Subventions d'équilibre",
- "parent": 441,
- "position": 2
- },
- "4419":
- {
- "code": 4419,
- "nom": "Avances sur subventions",
- "parent": 441,
- "position": 2
- },
- "442":
- {
- "code": 442,
- "nom": "État - Impôts et taxes recouvrables sur des tiers",
- "parent": 44,
- "position": 2
- },
- "444":
- {
- "code": 444,
- "nom": "État - Impôts sur les bénéfices",
- "parent": 44,
- "position": 2
- },
- "445":
- {
- "code": 445,
- "nom": "État - Taxes sur le chiffre d'affaires",
- "parent": 44,
- "position": 2
- },
- "4455":
- {
- "code": 4455,
- "nom": "Taxes sur le chiffre d'affaires à décaisser",
- "parent": 445,
- "position": 2
- },
- "44551":
- {
- "code": 44551,
- "nom": "TVA à décaisser",
- "parent": 4455,
- "position": 2
- },
- "44558":
- {
- "code": 44558,
- "nom": "Taxes assimilées à la TVA",
- "parent": 4455,
- "position": 2
- },
- "4456":
- {
- "code": 4456,
- "nom": "Taxes sur le chiffre d'affaires déductibles",
- "parent": 445,
- "position": 2
- },
- "44562":
- {
- "code": 44562,
- "nom": "TVA sur immobilisations",
- "parent": 4456,
- "position": 2
- },
- "44566":
- {
- "code": 44566,
- "nom": "TVA sur autres biens et services",
- "parent": 4456,
- "position": 2
- },
- "4457":
- {
- "code": 4457,
- "nom": "Taxes sur le chiffre d'affaires collectées par l'association",
- "parent": 445,
- "position": 2
- },
- "4458":
- {
- "code": 4458,
- "nom": "Taxes sur le chiffre d'affaires à régulariser ou en attente",
- "parent": 445,
- "position": 2
- },
- "44581":
- {
- "code": 44581,
- "nom": "Acomptes - Régime simplifié d'imposition",
- "parent": 4458,
- "position": 2
- },
- "44582":
- {
- "code": 44582,
- "nom": "Acomptes - Régime du forfait",
- "parent": 4458,
- "position": 2
- },
- "44583":
- {
- "code": 44583,
- "nom": "Remboursement de taxes sur le chiffre d'affaires demandé",
- "parent": 4458,
- "position": 2
- },
- "44584":
- {
- "code": 44584,
- "nom": "TVA récupérée d'avance",
- "parent": 4458,
- "position": 2
- },
- "44586":
- {
- "code": 44586,
- "nom": "Taxes sur le chiffre d'affaires sur factures non parvenues",
- "parent": 4458,
- "position": 2
- },
- "44587":
- {
- "code": 44587,
- "nom": "Taxes sur le chiffre d'affaires sur factures à établir",
- "parent": 4458,
- "position": 2
- },
- "447":
- {
- "code": 447,
- "nom": "Autres impôts, taxes et versements assimilés",
- "parent": 44,
- "position": 2
- },
- "4471":
- {
- "code": 4471,
- "nom": "Autres impôts, taxes et versements assimilés sur rémunérations (Administration des impôts)",
- "parent": 447,
- "position": 2
- },
- "44711":
- {
- "code": 44711,
- "nom": "Taxe sur les salaires",
- "parent": 4471,
- "position": 2
- },
- "44713":
- {
- "code": 44713,
- "nom": "Participation des employeurs à la formation professionnelle continue",
- "parent": 4471,
- "position": 2
- },
- "44714":
- {
- "code": 44714,
- "nom": "Cotisation par défaut d'investissement obligatoire dans la construction",
- "parent": 4471,
- "position": 2
- },
- "44718":
- {
- "code": 44718,
- "nom": "Autres impôts, taxes et versements assimilés",
- "parent": 4471,
- "position": 2
- },
- "4473":
- {
- "code": 4473,
- "nom": "Autres impôts, taxes et versements assimilés sur rémunérations (Autres organismes)",
- "parent": 447,
- "position": 2
- },
- "44733":
- {
- "code": 44733,
- "nom": "Participation des employeurs à la formation professionnelle continue",
- "parent": 4473,
- "position": 2
- },
- "44734":
- {
- "code": 44734,
- "nom": "Participation des employeurs à l'effort de construction (versements à fonds perdus)",
- "parent": 4473,
- "position": 2
- },
- "4475":
- {
- "code": 4475,
- "nom": "Autres impôts, taxes et versements assimilés (Administration des impôts)",
- "parent": 447,
- "position": 2
- },
- "4477":
- {
- "code": 4477,
- "nom": "Autres impôts, taxes et versements assimilés (Autres organismes)",
- "parent": 447,
- "position": 2
- },
- "448":
- {
- "code": 448,
- "nom": "État - Charges à payer et produits à recevoir",
- "parent": 44,
- "position": 2
- },
- "4482":
- {
- "code": 4482,
- "nom": "Charges fiscales sur congés à payer",
- "parent": 448,
- "position": 2
- },
- "4486":
- {
- "code": 4486,
- "nom": "Autres charges à payer",
- "parent": 448,
- "position": 2
- },
- "4487":
- {
- "code": 4487,
- "nom": "Produits à recevoir",
- "parent": 448,
- "position": 2
- },
- "449":
- {
- "code": 449,
- "nom": "Avances auprès de l'état et des collectivités publiques",
- "parent": 44,
- "position": 2
- },
- "45":
- {
- "code": 45,
- "nom": "CONFÉDÉRATION, FÉDÉRATION, UNIONS ET ASSOCIATIONS AFFILIÉES",
- "parent": 4,
- "position": 3
- },
- "451":
- {
- "code": 451,
- "nom": "Confédération, fédération et associations affiliées - Compte courant",
- "parent": 45,
- "position": 2
- },
- "455":
- {
- "code": 455,
- "nom": "Sociétaires - Comptes courants",
- "parent": 45,
- "position": 2
- },
- "46":
- {
- "code": 46,
- "nom": "DÉBITEURS DIVERS ET CRÉDITEURS DIVERS",
- "parent": 4,
- "position": 3
- },
- "467":
- {
- "code": 467,
- "nom": "Autres comptes débiteurs et créditeurs",
- "parent": 46,
- "position": 2
- },
- "468":
- {
- "code": 468,
- "nom": "Divers - Charges à payer et produits à recevoir",
- "parent": 46,
- "position": 1
- },
- "4686":
- {
- "code": 4686,
- "nom": "Charges à payer",
- "parent": 468,
- "position": 1
- },
- "4687":
- {
- "code": 4687,
- "nom": "Produits à recevoir",
- "parent": 468,
- "position": 1
- },
- "47":
- {
- "code": 47,
- "nom": "COMPTES TRANSITOIRES OU D'ATTENTE",
- "parent": 4,
- "position": 3
- },
- "471":
- {
- "code": 471,
- "nom": "Recettes à classer",
- "parent": 47,
- "position": 2
- },
- "472":
- {
- "code": 472,
- "nom": "Dépenses à classer et à régulariser",
- "parent": 47,
- "position": 1
- },
- "48":
- {
- "code": 48,
- "nom": "COMPTES DE RÉGULARISATION",
- "parent": 4,
- "position": 3
- },
- "481":
- {
- "code": 481,
- "nom": "Charges à répartir sur plusieurs exercices",
- "parent": 48,
- "position": 2
- },
- "486":
- {
- "code": 486,
- "nom": "Charges constatées d'avance",
- "parent": 48,
- "position": 2
- },
- "487":
- {
- "code": 487,
- "nom": "Produits constatés d'avance",
- "parent": 48,
- "position": 1
- },
- "49":
- {
- "code": 49,
- "nom": "DEPRECIATION DES COMPTES DE TIERS",
- "parent": 4,
- "position": 3
- },
- "491":
- {
- "code": 491,
- "nom": "Dépréciation des comptes clients",
- "parent": 49,
- "position": 2
- },
- "496":
- {
- "code": 496,
- "nom": "Dépréciation des comptes débiteurs divers",
- "parent": 49,
- "position": 2
- },
- "5":
- {
- "code": 5,
- "nom": "Classe 5 — Comptes financiers",
- "parent": 0,
- "position": 2
- },
- "51":
- {
- "code": 51,
- "nom": "BANQUES, ÉTABLISSEMENTS FINANCIERS ET ASSIMILÉS",
- "parent": 5,
- "position": 2
- },
- "512":
- {
- "code": 512,
- "nom": "Banques",
- "parent": 51,
- "position": 2
- },
- "53":
- {
- "code": 53,
- "nom": "CAISSE",
- "parent": 5,
- "position": 2
- },
- "530":
- {
- "code": 530,
- "nom": "Caisse",
- "parent": 53,
- "position": 2
- },
- "58":
- {
- "code": 58,
- "nom": "VIREMENTS INTERNES",
- "parent": 5,
- "position": 2
- },
- "6":
- {
- "code": 6,
- "nom": "Classe 6 — Comptes de charges",
- "parent": 0,
- "position": 8
- },
- "60":
- {
- "code": 60,
- "nom": "ACHATS",
- "parent": 6,
- "position": 8
- },
- "601":
- {
- "code": 601,
- "nom": "Achats stockés - Matières premières et fournitures",
- "parent": 60,
- "position": 8
- },
- "602":
- {
- "code": 602,
- "nom": "Achats stockés - Autres approvisionnements",
- "parent": 60,
- "position": 8
- },
- "604":
- {
- "code": 604,
- "nom": "Achat d'études et prestations de services",
- "parent": 60,
- "position": 8
- },
- "606":
- {
- "code": 606,
- "nom": "Achats non stockés de matières et fournitures",
- "parent": 60,
- "position": 8
- },
- "6061":
- {
- "code": 6061,
- "nom": "Fournitures non stockables (eau, énergie...)",
- "parent": 606,
- "position": 8
- },
- "6063":
- {
- "code": 6063,
- "nom": "Fournitures d'entretien et de petit équipement",
- "parent": 606,
- "position": 8
- },
- "6064":
- {
- "code": 6064,
- "nom": "Fournitures administratives",
- "parent": 606,
- "position": 8
- },
- "6068":
- {
- "code": 6068,
- "nom": "Autres matières et fournitures",
- "parent": 606,
- "position": 8
- },
- "607":
- {
- "code": 607,
- "nom": "Achats de marchandises",
- "parent": 60,
- "position": 8
- },
- "61":
- {
- "code": 61,
- "nom": "SERVICES EXTÉRIEURS",
- "parent": 6,
- "position": 8
- },
- "611":
- {
- "code": 611,
- "nom": "Sous-traitance générale",
- "parent": 61,
- "position": 8
- },
- "612":
- {
- "code": 612,
- "nom": "Redevances de crédit-bail",
- "parent": 61,
- "position": 8
- },
- "613":
- {
- "code": 613,
- "nom": "Locations",
- "parent": 61,
- "position": 8
- },
- "614":
- {
- "code": 614,
- "nom": "Charges locatives et de co-propriété",
- "parent": 61,
- "position": 8
- },
- "615":
- {
- "code": 615,
- "nom": "Entretiens et réparations",
- "parent": 61,
- "position": 8
- },
- "616":
- {
- "code": 616,
- "nom": "Primes d'assurance",
- "parent": 61,
- "position": 8
- },
- "618":
- {
- "code": 618,
- "nom": "Divers",
- "parent": 61,
- "position": 8
- },
- "62":
- {
- "code": 62,
- "nom": "AUTRES SERVICES EXTÉRIEURS",
- "parent": 6,
- "position": 8
- },
- "621":
- {
- "code": 621,
- "nom": "Personnel extérieur à l'association",
- "parent": 62,
- "position": 8
- },
- "622":
- {
- "code": 622,
- "nom": "Rémunérations d'intermédiaires et honoraires",
- "parent": 62,
- "position": 8
- },
- "6226":
- {
- "code": 6226,
- "nom": "Honoraires",
- "parent": 622,
- "position": 8
- },
- "6227":
- {
- "code": 6227,
- "nom": "Frais d'actes et de contentieux",
- "parent": 622,
- "position": 8
- },
- "6228":
- {
- "code": 6228,
- "nom": "Divers",
- "parent": 622,
- "position": 8
- },
- "623":
- {
- "code": 623,
- "nom": "Publicité, publications, relations publiques",
- "parent": 62,
- "position": 8
- },
- "624":
- {
- "code": 624,
- "nom": "Transports de biens et transports collectifs du personnel",
- "parent": 62,
- "position": 8
- },
- "625":
- {
- "code": 625,
- "nom": "Déplacements, missions et réceptions",
- "parent": 62,
- "position": 8
- },
- "626":
- {
- "code": 626,
- "nom": "Frais postaux et de télécommunications",
- "parent": 62,
- "position": 8
- },
- "627":
- {
- "code": 627,
- "nom": "Services bancaires et assimilés",
- "parent": 62,
- "position": 8
- },
- "628":
- {
- "code": 628,
- "nom": "Divers",
- "parent": 62,
- "position": 8
- },
- "63":
- {
- "code": 63,
- "nom": "IMPÔTS, TAXES ET VERSEMENTS ASSIMILÉS",
- "parent": 6,
- "position": 8
- },
- "631":
- {
- "code": 631,
- "nom": "Impôts, taxes et versements assimilés sur rémunérations (Administration des impôts)",
- "parent": 63,
- "position": 8
- },
- "6311":
- {
- "code": 6311,
- "nom": "Taxes sur les salaires",
- "parent": 631,
- "position": 8
- },
- "6313":
- {
- "code": 6313,
- "nom": "Participations des employeurs à la formation professionnelle continue",
- "parent": 631,
- "position": 8
- },
- "635":
- {
- "code": 635,
- "nom": "Autres impôts, taxes et versements assimilés (Administration des impôts)",
- "parent": 63,
- "position": 8
- },
- "6351":
- {
- "code": 6351,
- "nom": "Impôts directs (sauf impôts sur les bénéfices)",
- "parent": 635,
- "position": 8
- },
- "6353":
- {
- "code": 6353,
- "nom": "Impôts indirects",
- "parent": 635,
- "position": 8
- },
- "637":
- {
- "code": 637,
- "nom": "Autres impôts, taxes et versements assimilés (Autres organismes)",
- "parent": 63,
- "position": 8
- },
- "64":
- {
- "code": 64,
- "nom": "CHARGES DE PERSONNEL",
- "parent": 6,
- "position": 8
- },
- "641":
- {
- "code": 641,
- "nom": "Rémunérations du personnel",
- "parent": 64,
- "position": 8
- },
- "643":
- {
- "code": 643,
- "nom": "Rémunérations du personnel artistique et assimilés",
- "parent": 64,
- "position": 8
- },
- "645":
- {
- "code": 645,
- "nom": "Charges de sécurité sociale et de prévoyance",
- "parent": 64,
- "position": 8
- },
- "647":
- {
- "code": 647,
- "nom": "Autres charges sociales",
- "parent": 64,
- "position": 8
- },
- "648":
- {
- "code": 648,
- "nom": "Autres charges de personnel",
- "parent": 64,
- "position": 8
- },
- "65":
- {
- "code": 65,
- "nom": "AUTRES CHARGES DE GESTION COURANTE",
- "parent": 6,
- "position": 8
- },
- "658":
- {
- "code": 658,
- "nom": "Charges diverses de gestion courante",
- "parent": 65,
- "position": 8
- },
- "66":
- {
- "code": 66,
- "nom": "CHARGES FINANCIÈRES",
- "parent": 6,
- "position": 8
- },
- "661":
- {
- "code": 661,
- "nom": "Charges d'intérêts",
- "parent": 66,
- "position": 8
- },
- "67":
- {
- "code": 67,
- "nom": "CHARGES EXCEPTIONNELLES",
- "parent": 6,
- "position": 8
- },
- "671":
- {
- "code": 671,
- "nom": "Charges exceptionnelles sur opérations de gestion",
- "parent": 67,
- "position": 8
- },
- "6713":
- {
- "code": 6713,
- "nom": "Dons, libéralités",
- "parent": 671,
- "position": 8
- },
- "678":
- {
- "code": 678,
- "nom": "Autres charges exceptionnelles",
- "parent": 67,
- "position": 8
- },
- "6788":
- {
- "code": 6788,
- "nom": "Charges exceptionnelles diverses",
- "parent": 678,
- "position": 8
- },
- "68":
- {
- "code": 68,
- "nom": "DOTATIONS AUX AMORTISSEMENTS, DÉPRÉCIATIONS, PROVISIONS ET ENGAGEMENTS",
- "parent": 6,
- "position": 8
- },
- "681":
- {
- "code": 681,
- "nom": "Dotations aux amortissements, dépréciations et provisions - Charges d'exploitation",
- "parent": 68,
- "position": 8
- },
- "6811":
- {
- "code": 6811,
- "nom": "Dotations aux amortissements des immobilisations incorporelles et corporelles",
- "parent": 681,
- "position": 8
- },
- "68111":
- {
- "code": 68111,
- "nom": "Immobilisations incorporelles",
- "parent": 6811,
- "position": 8
- },
- "68112":
- {
- "code": 68112,
- "nom": "Immobilisations corporelles",
- "parent": 6811,
- "position": 8
- },
- "686":
- {
- "code": 686,
- "nom": "Dotations aux amortissements, dépréciations et provisions - Charges financières",
- "parent": 68,
- "position": 8
- },
- "69":
- {
- "code": 69,
- "nom": "PARTICIPATION DES SALARIÉS - IMPÔTS SUR LES BÉNÉFICES ET ASSIMILÉS",
- "parent": 6,
- "position": 8
- },
- "695":
- {
- "code": 695,
- "nom": "Impôts sur les sociétés (y compris impôts sur les sociétés des personnes morales non lucratives)",
- "parent": 69,
- "position": 8
- },
- "7":
- {
- "code": 7,
- "nom": "Classe 7 — Comptes de produits",
- "parent": 0,
- "position": 4
- },
- "70":
- {
- "code": 70,
- "nom": "VENTES DE PRODUITS FINIS, PRESTATIONS DE SERVICES, MARCHANDISES",
- "parent": 7,
- "position": 4
- },
- "701":
- {
- "code": 701,
- "nom": "Ventes de produits finis",
- "parent": 70,
- "position": 4
- },
- "706":
- {
- "code": 706,
- "nom": "Prestations de services",
- "parent": 70,
- "position": 4
- },
- "707":
- {
- "code": 707,
- "nom": "Ventes de marchandises",
- "parent": 70,
- "position": 4
- },
- "708":
- {
- "code": 708,
- "nom": "Produits des activités annexes",
- "parent": 70,
- "position": 4
- },
- "74":
- {
- "code": 74,
- "nom": "SUBVENTIONS D'EXPLOITATION",
- "parent": 7,
- "position": 4
- },
- "740":
- {
- "code": 740,
- "nom": "Subventions reçues",
- "parent": 74,
- "position": 4
- },
- "75":
- {
- "code": 75,
- "nom": "AUTRES PRODUITS DE GESTION COURANTE",
- "parent": 7,
- "position": 4
- },
- "754":
- {
- "code": 754,
- "nom": "Collectes",
- "parent": 75,
- "position": 4
- },
- "756":
- {
- "code": 756,
- "nom": "Cotisations",
- "parent": 75,
- "position": 4
- },
- "758":
- {
- "code": 758,
- "nom": "Produits divers de gestion courante",
- "parent": 75,
- "position": 4
- },
- "7587":
- {
- "code": 7587,
- "nom": "Ventes de dons en nature",
- "parent": 758,
- "position": 4
- },
- "7588":
- {
- "code": 7588,
- "nom": "Autres produits de la générosité du public",
- "parent": 758,
- "position": 4
- },
- "76":
- {
- "code": 76,
- "nom": "PRODUITS FINANCIERS",
- "parent": 7,
- "position": 4
- },
- "760":
- {
- "code": 760,
- "nom": "Produits financiers",
- "parent": 76,
- "position": 4
- },
- "77":
- {
- "code": 77,
- "nom": "PRODUITS EXCEPTIONNELS",
- "parent": 7,
- "position": 4
- },
- "771":
- {
- "code": 771,
- "nom": "Produits exceptionnels sur opérations de gestion",
- "parent": 77,
- "position": 4
- },
- "7713":
- {
- "code": 7713,
- "nom": "Libéralités reçues",
- "parent": 771,
- "position": 4
- },
- "7715":
- {
- "code": 7715,
- "nom": "Subventions d'équilibre",
- "parent": 771,
- "position": 4
- },
- "775":
- {
- "code": 775,
- "nom": "Produits des cessions d'éléments d'actifs",
- "parent": 77,
- "position": 4
- },
- "778":
- {
- "code": 778,
- "nom": "Autres produits exceptionnels",
- "parent": 77,
- "position": 4
- },
- "7780":
- {
- "code": 7780,
- "nom": "Manifestations diverses",
- "parent": 778,
- "position": 4
- },
- "7788":
- {
- "code": 7788,
- "nom": "Produits exceptionnels divers",
- "parent": 778,
- "position": 4
- },
- "79":
- {
- "code": 79,
- "nom": "TRANSFERT DE CHARGES",
- "parent": 7,
- "position": 4
- },
- "791":
- {
- "code": 791,
- "nom": "Transferts de charges d'exploitation",
- "parent": 79,
- "position": 4
- },
- "796":
- {
- "code": 796,
- "nom": "Transferts de charges financières",
- "parent": 79,
- "position": 4
- },
- "797":
- {
- "code": 797,
- "nom": "Transferts de charges exceptionnels",
- "parent": 79,
- "position": 4
- },
- "8":
- {
- "code": 8,
- "nom": "Classe 8 — Contributions bénévoles en nature",
- "parent": 0,
- "position": 4
- },
- "86":
- {
- "code": 86,
- "nom": "RÉPARTITION PAR NATURE DE CHARGES",
- "parent": 8,
- "position": 8
- },
- "861":
- {
- "code": 861,
- "nom": "Mise à dispositions gratuites de biens",
- "parent": 86,
- "position": 8
- },
- "862":
- {
- "code": 862,
- "nom": "Prestations",
- "parent": 86,
- "position": 8
- },
- "864":
- {
- "code": 864,
- "nom": "Personnel bénévole",
- "parent": 86,
- "position": 8
- },
- "87":
- {
- "code": 87,
- "nom": "RÉPARTITION PAR NATURE DE RESSOURCES",
- "parent": 8,
- "position": 4
- },
- "870":
- {
- "code": 870,
- "nom": "Bénévolat",
- "parent": 87,
- "position": 4
- },
- "871":
- {
- "code": 871,
- "nom": "Prestations en nature",
- "parent": 87,
- "position": 4
- },
- "875":
- {
- "code": 875,
- "nom": "Dons en nature",
- "parent": 87,
- "position": 4
- },
- "9":
- {
- "code": 9,
- "nom": "Classe 9 — Comptes analytiques",
- "parent": 0,
- "position": 12
- }
-}
DELETED include/data/schema.sql
Index: include/data/schema.sql
==================================================================
--- include/data/schema.sql
+++ include/data/schema.sql
@@ -1,325 +0,0 @@
-CREATE TABLE config (
--- Configuration de Garradin
- cle TEXT PRIMARY KEY,
- valeur TEXT
-);
-
--- On stocke ici les ID de catégorie de compta correspondant aux types spéciaux
--- compta_categorie_cotisations => id_categorie
--- compta_categorie_dons => id_categorie
-
-CREATE TABLE membres_categories
--- Catégories de membres
-(
- id INTEGER PRIMARY KEY,
- nom TEXT,
- description TEXT,
-
- droit_wiki INT DEFAULT 1,
- droit_membres INT DEFAULT 1,
- droit_compta INT DEFAULT 1,
- droit_inscription INT DEFAULT 0,
- droit_connexion INT DEFAULT 1,
- droit_config INT DEFAULT 0,
- cacher INT DEFAULT 0,
-
- id_transaction_obligatoire INTEGER NULL,
-
- FOREIGN KEY (id_transaction_obligatoire) REFERENCES transactions (id)
-);
-
--- Membres de l'asso
--- Table dynamique générée par l'application
--- voir class.champs_membres.php
-
-CREATE TABLE transactions
--- Paiements possibles
-(
- id INTEGER PRIMARY KEY,
- id_categorie_compta INTEGER NULL, -- NULL si le type n'est pas associé automatiquement à la compta
-
- intitule TEXT NOT NULL,
- description TEXT NOT NULL,
- montant REAL NOT NULL,
-
- duree INTEGER NULL, -- En jours
- debut TEXT NULL, -- timestamp
- fin TEXT NULL,
-
- FOREIGN KEY (id_categorie_compta) REFERENCES compta_categories (id)
-);
-
-CREATE TABLE rappels
--- Rappels de devoir renouveller une transaction
-(
- id INTEGER PRIMARY KEY,
- id_transaction INTEGER NULL,
-
- delai INTEGER NOT NULL, -- Délai en jours pour envoyer le rappel
-
- sujet TEXT NOT NULL,
- texte TEXT NOT NULL,
-
- FOREIGN KEY (id_transaction) REFERENCES transactions (id)
-);
-
-CREATE TABLE rappels_envoyes
--- Enregistrement des rappels envoyés à qui et quand
-(
- id_membre INTEGER NOT NULL,
- id_rappel INTEGER NOT NULL,
- date TEXT NOT NULL DEFAUT CURRENT_TIMESTAMP,
- media INTEGER NOT NULL, -- Média utilisé pour le rappel : 1 = email, 2 = courrier, 3 = autre
-
- FOREIGN KEY (id_membre) REFERENCES membres (id),
- FOREIGN KEY (id_rappel) REFERENCES rappels (id),
-
- PRIMARY KEY(id_membre, id_rappel, date)
-);
-
-CREATE TABLE membres_transactions
--- Paiements enregistrés
-(
- id_membre INTEGER NOT NULL,
- id_transaction INTEGER NULL, -- NULL si n'est pas relié à une transaction prévue
-
- libelle TEXT NULL,
-
- date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
- montant REAL NOT NULL,
-
- FOREIGN KEY (id_membre) REFERENCES membres (id),
- FOREIGN KEY (id_transaction) REFERENCES transactions (id)
-);
-
-CREATE TABLE membres_transactions_operations
--- Liaison paiements enregistrés avec écritures comptables
-(
- id_operation INTEGER NOT NULL,
- id_membre_transaction INTEGER NOT NULL,
-
- FOREIGN KEY (id_operation) REFERENCES compta_journal (id),
- FOREIGN KEY (id_membre_transaction) REFERENCES membres_transactions (id)
-);
-
---
--- WIKI
---
-
-CREATE TABLE wiki_pages
--- Pages du wiki
-(
- id INTEGER PRIMARY KEY,
- uri TEXT, -- URI unique (équivalent NomPageWiki)
- titre TEXT,
- date_creation TEXT DEFAULT CURRENT_TIMESTAMP,
- date_modification TEXT DEFAULT CURRENT_TIMESTAMP,
- parent INTEGER DEFAULT 0, -- ID de la page parent
- revision INTEGER DEFAULT 0, -- Numéro de révision (commence à 0 si pas de texte, +1 à chaque changement du texte)
- droit_lecture INTEGER DEFAULT 0, -- Accès en lecture (-1 = public [site web], 0 = tous ceux qui ont accès en lecture au wiki, 1+ = ID de groupe)
- droit_ecriture INTEGER DEFAULT 0 -- Accès en écriture (0 = tous ceux qui ont droit d'écriture sur le wiki, 1+ = ID de groupe)
-);
-
-CREATE UNIQUE INDEX wiki_uri ON wiki_pages (uri);
-
-CREATE VIRTUAL TABLE wiki_recherche USING fts4
--- Table dupliquée pour chercher une page
-(
- id INT PRIMARY KEY NOT NULL, -- Clé externe obligatoire
- titre TEXT,
- contenu TEXT, -- Contenu de la dernière révision
- FOREIGN KEY (id) REFERENCES wiki_pages(id)
-);
-
-CREATE TABLE wiki_revisions
--- Révisions du contenu des pages
-(
- id_page INTEGER NOT NULL,
- revision INTEGER,
-
- id_auteur INTEGER,
-
- contenu TEXT,
- modification TEXT, -- Description des modifications effectuées
- chiffrement INTEGER DEFAULT 0, -- 1 si le contenu est chiffré, 0 sinon
- date TEXT DEFAULT CURRENT_TIMESTAMP,
-
- PRIMARY KEY(id_page, revision),
- FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
- FOREIGN KEY (id_auteur) REFERENCES membres (id) -- Clé externe non-obligatoire (peut être supprimée après en cas de suppression de membre)
-);
-
-CREATE INDEX wiki_revisions_id_page ON wiki_revisions (id_page);
-CREATE INDEX wiki_revisions_id_auteur ON wiki_revisions (id_auteur);
-
--- Triggers pour synchro avec table wiki_pages
-CREATE TRIGGER wiki_recherche_delete AFTER DELETE ON wiki_pages
- BEGIN
- DELETE FROM wiki_recherche WHERE id = old.id;
- END;
-
-CREATE TRIGGER wiki_recherche_update AFTER UPDATE OF id, titre ON wiki_pages
- BEGIN
- UPDATE wiki_recherche SET id = new.id, titre = new.titre WHERE id = old.id;
- END;
-
--- Trigger pour mettre à jour le contenu de la table de recherche lors d'une nouvelle révision
-CREATE TRIGGER wiki_recherche_contenu_insert AFTER INSERT ON wiki_revisions WHEN new.chiffrement != 1
- BEGIN
- UPDATE wiki_recherche SET contenu = new.contenu WHERE id = new.id_page;
- END;
-
--- Si le contenu est chiffré, la recherche n'affiche pas de contenu
-CREATE TRIGGER wiki_recherche_contenu_chiffre AFTER INSERT ON wiki_revisions WHEN new.chiffrement = 1
- BEGIN
- UPDATE wiki_recherche SET contenu = '' WHERE id = new.id_page;
- END;
-
-/*
-CREATE TABLE wiki_fichiers (
- id INTEGER PRIMARY KEY,
- id_page INTEGER NOT NULL,
- nom TEXT,
- hash TEXT,
-
- FOREIGN KEY (id_page) REFERENCES wiki_pages (id) -- Clé externe obligatoire
-);
-
-CREATE INDEX wiki_fichiers_id_page ON wiki_fichiers (id_page);
-
-CREATE TABLE wiki_suivi
--- Suivi des pages
-(
- id_membre INTEGER NOT NULL,
- id_page INTEGER NOT NULL,
-
- PRIMARY KEY (id_membre, id_page),
-
- FOREIGN KEY (id_page) REFERENCES wiki_pages (id), -- Clé externe obligatoire
- FOREIGN KEY (id_membre) REFERENCES membres (id) -- Clé externe obligatoire
-);
-*/
-
---
--- COMPTA
---
-
-CREATE TABLE compta_exercices
--- Exercices
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
-
- debut TEXT NOT NULL DEFAULT CURRENT_DATE,
- fin TEXT NULL DEFAULT NULL,
-
- cloture INTEGER NOT NULL DEFAULT 0
-);
-
-
-CREATE TABLE compta_comptes
--- Plan comptable
-(
- id TEXT PRIMARY KEY,
- parent TEXT NOT NULL DEFAULT 0,
-
- libelle TEXT NOT NULL,
-
- position INTEGER NOT NULL, -- position actif/passif/charge/produit
- plan_comptable INTEGER NOT NULL DEFAULT 1 -- 1 = fait partie du plan comptable, 0 = a été ajouté par l'utilisateur
-);
-
-CREATE INDEX compta_comptes_parent ON compta_comptes (parent);
-
-CREATE TABLE compta_comptes_bancaires
--- Comptes bancaires
-(
- id TEXT PRIMARY KEY,
-
- banque TEXT NOT NULL,
-
- iban TEXT,
- bic TEXT,
-
- FOREIGN KEY(id) REFERENCES compta_comptes(id)
-);
-
-CREATE TABLE compta_journal
--- Journal des opérations comptables
-(
- id INTEGER PRIMARY KEY,
-
- libelle TEXT NOT NULL,
- remarques TEXT,
- numero_piece TEXT, -- N° de pièce comptable
-
- montant REAL,
-
- date TEXT DEFAULT CURRENT_DATE,
- moyen_paiement TEXT DEFAULT NULL,
- numero_cheque TEXT DEFAULT NULL,
-
- compte_debit INTEGER, -- N° du compte dans le plan
- compte_credit INTEGER, -- N° du compte dans le plan
-
- id_exercice INTEGER NULL DEFAULT NULL, -- En cas de compta simple, l'exercice est permanent (NULL)
- id_auteur INTEGER NULL,
- id_categorie INTEGER NULL, -- Numéro de catégorie (en mode simple)
- id_transaction INTEGER NULL, -- Numéro de transaction
-
- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code),
- FOREIGN KEY(compte_debit) REFERENCES compta_comptes(id),
- FOREIGN KEY(compte_credit) REFERENCES compta_comptes(id),
- FOREIGN KEY(id_exercice) REFERENCES compta_exercices(id),
- FOREIGN KEY(id_auteur) REFERENCES membres(id),
- FOREIGN KEY(id_categorie) REFERENCES compta_categories(id),
- FOREIGN KEY(id_transaction) REFERENCES membres_transactions(id)
-);
-
-CREATE INDEX compta_operations_exercice ON compta_journal (id_exercice);
-CREATE INDEX compta_operations_date ON compta_journal (date);
-CREATE INDEX compta_operations_comptes ON compta_journal (compte_debit, compte_credit);
-CREATE INDEX compta_operations_auteur ON compta_journal (id_auteur);
-
-CREATE TABLE compta_moyens_paiement
--- Moyens de paiement
-(
- code TEXT PRIMARY KEY,
- nom TEXT
-);
-
---INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('CB', 'Carte bleue');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('CH', 'Chèque');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('ES', 'Espèces');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('PR', 'Prélèvement');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('TI', 'TIP');
-INSERT INTO compta_moyens_paiement (code, nom) VALUES ('VI', 'Virement');
-
-CREATE TABLE compta_categories
--- Catégories pour simplifier le plan comptable
-(
- id INTEGER PRIMARY KEY,
- type INTEGER DEFAULT 1, -- 1 = recette, -1 = dépense, 0 = autre (utilisé uniquement pour l'interface)
-
- intitule TEXT NOT NULL,
- description TEXT,
-
- compte TEXT NOT NULL, -- Compte affecté par cette catégorie
-
- FOREIGN KEY(compte) REFERENCES compta_comptes(id)
-);
-
-/*
---
--- générateur de paperasses
---
-
-CREATE TABLE papiers (
- id INTEGER PRIMARY KEY,
- modele INTEGER,
-
- donnees TEXT
-);
-*/
DELETED include/init.php
Index: include/init.php
==================================================================
--- include/init.php
+++ include/init.php
@@ -1,252 +0,0 @@
-assign('error', $e->getMessage());
- $tpl->display('error.tpl');
- exit;
- }
- catch (Exception $e)
- {
- }
- }
-
- $error = "Exception of type ".get_class($e)." happened !\n\n".
- $e->getCode()." - ".$e->getMessage()."\n\nIn: ".
- $e->getFile() . ":" . $e->getLine()."\n\n";
-
- if (!empty($_SERVER['HTTP_HOST']))
- $error .= 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n\n";
-
- $error .= $e->getTraceAsString();
- //$error .= print_r($_SERVER, true);
-
- echo '';
- echo $error;
- exit;
-}
-
-set_error_handler('Garradin\exception_error_handler');
-set_exception_handler('Garradin\exception_handler');
-
-// Nettoyage des variables GPC pour ceux qui n'auraient
-// toujours pas désactivé les magic quotes
-if (get_magic_quotes_gpc())
-{
- function strip_slashes_from_user_data(&$array)
- {
- foreach($array as $k => $v)
- {
- if (is_array($v))
- {
- strip_slashes_from_user_data($array[$k]);
- continue;
- }
- $array[$k] = stripslashes($v);
- }
- }
-
- strip_slashes_from_user_data($_GET);
- strip_slashes_from_user_data($_POST);
- strip_slashes_from_user_data($_COOKIE);
-}
-
-/**
- * Auto-load classes and libs
- */
-class Loader
-{
- /**
- * Already loaded filenames
- * @var array
- */
- static protected $loaded = array();
-
- static protected $libs = array(
- 'utils',
- 'squelette_filtres',
- 'static_cache',
- 'template'
- );
-
- /**
- * Loads a class from the $name
- * @param stringg $classname
- * @return bool true
- */
- static public function load($classname)
- {
- $classname = ltrim($classname, '\\');
- $filename = '';
- $namespace = '';
-
- if ($lastnspos = strripos($classname, '\\'))
- {
- $namespace = substr($classname, 0, $lastnspos);
- $classname = substr($classname, $lastnspos + 1);
-
- if ($namespace != 'Garradin')
- {
- $filename = str_replace('\\', '/', $namespace) . '/';
- }
- }
-
- $classname = strtolower($classname);
-
- if (in_array($classname, self::$libs)) {
- $filename = 'lib.' . $classname . '.php';
- } else {
- $filename .= 'class.' . $classname . '.php';
- }
-
- $filename = GARRADIN_ROOT . '/include/' . $filename;
-
- if (array_key_exists($filename, self::$loaded))
- {
- return true;
- }
-
- if (!file_exists($filename)) {
- throw new \Exception('File '.$filename.' doesn\'t exists');
- }
-
- self::$loaded[$filename] = true;
-
- require $filename;
- }
-}
-
-\spl_autoload_register(array('Garradin\Loader', 'load'), true);
-
-$n = new Membres;
-
-/*
- * Inclusion des fichiers de base
- */
-
-if (!defined('GARRADIN_INSTALL_PROCESS') && !defined('GARRADIN_UPGRADE_PROCESS'))
-{
- if (!file_exists(GARRADIN_DB_FILE))
- {
- utils::redirect('/admin/install.php');
- }
-
- $config = Config::getInstance();
-
- if (version_compare($config->getVersion(), garradin_version(), '<'))
- {
- utils::redirect('/admin/upgrade.php');
- }
-}
-
-?>
DELETED include/lib.squelette_filtres.php
Index: include/lib.squelette_filtres.php
==================================================================
--- include/lib.squelette_filtres.php
+++ include/lib.squelette_filtres.php
@@ -1,350 +0,0 @@
- 'supprimer_tags',
- 'var_dump',
- );
-
- static public $filtres_alias = array(
- '!=' => 'different_de',
- '==' => 'egal_a',
- '?' => 'choixsivide',
- '>' => 'superieur_a',
- '>=' => 'superieur_ou_egal_a',
- '<' => 'inferieur_a',
- '<=' => 'inferieur_ou_egal_a',
- 'yes' => 'oui',
- 'no' => 'non',
- 'and' => 'et',
- 'or' => 'ou',
- 'xor' => 'xou',
- );
-
- static public $desactiver_defaut = array(
- 'formatter_texte',
- 'entites_html',
- 'proteger_contact',
- 'echapper_xml',
- );
-
- static public function date_en_francais($date)
- {
- return ucfirst(strtolower(utils::strftime_fr('%A %e %B %Y', $date)));
- }
-
- static public function heure_en_francais($date)
- {
- return utils::strftime_fr('%Hh%I', $date);
- }
-
- static public function mois_en_francais($date)
- {
- return utils::strftime_fr('%B %Y', $date);
- }
-
- static public function date_perso($date, $format)
- {
- return utils::strftime_fr($format, $date);
- }
-
- static public function date_intelligente($date)
- {
- if (date('Ymd', $date) == date('Ymd'))
- return 'Aujourd\'hui, '.date('H\hi', $date);
- elseif (date('Ymd', $date) == date('Ymd', strtotime('yesterday')))
- return 'Hier, '.date('H\hi', $date);
- elseif (date('Y', $date) == date('Y'))
- return strtolower(utils::strftime_fr('%e %B, %Hh%M', $date));
- else
- return strtolower(utils::strftime_fr('%e %B %Y', $date));
- }
-
- static public function date_atom($date)
- {
- return date(DATE_ATOM, $date);
- }
-
- static public function alterner($v, $name, $valeur1, $valeur2)
- {
- if (!array_key_exists($name, self::$alt))
- {
- self::$alt[$name] = 0;
- }
-
- if (self::$alt[$name]++ % 2 == 0)
- return $valeur1;
- else
- return $valeur2;
- }
-
- static public function proteger_contact($contact)
- {
- if (!trim($contact))
- return '';
-
- if (strpos($contact, '@'))
- return ''.htmlspecialchars(strrev($contact), ENT_QUOTES, 'UTF-8').'';
- else
- return ''.htmlspecialchars($contact, ENT_QUOTES, 'UTF-8').'';
- }
-
- static public function entites_html($texte)
- {
- return htmlspecialchars($texte, ENT_QUOTES, 'UTF-8');
- }
-
- static public function echapper_xml($texte)
- {
- return str_replace(''', ''', htmlspecialchars($texte, ENT_QUOTES, 'UTF-8'));
- }
-
- static public function formatter_texte($texte)
- {
- $texte = utils::htmlLinksOnUrls($texte);
- $texte = utils::htmlSpip($texte);
- $texte = utils::htmlGarbage2xhtml($texte);
-
- $texte = self::typo_fr($texte);
-
- return $texte;
- }
-
- static public function typo_fr($str, $html = true)
- {
- $space = $html ? ' ' : ' ';
- $str = preg_replace('/(?:[\h]| )*([?!:»])(\s+|$)/u', $space.'\\1\\2', $str);
- $str = preg_replace('/(^|\s+)([«])(?:[\h]| )*/u', '\\1\\2'.$space, $str);
- return $str;
- }
-
- static public function pagination($total, $debut, $par_page)
- {
- $max_page = ceil($total / $par_page);
- $current = ($debut > 0) ? ceil($debut / $par_page) + 1 : 1;
- $out = '';
-
- if ($current > 1)
- {
- $out .= '« Page précédente - ';
- }
-
- for ($i = 1; $i <= $max_page; $i++)
- {
- $link = ($i == 1) ? './' : './+' . (($i - 1) * $par_page);
-
- if ($i == $current)
- $out .= ''.$i.' - ';
- else
- $out .= ''.$i.' - ';
- }
-
- if ($current < $max_page)
- {
- $out .= 'Page suivante »';
- }
- else
- {
- $out = substr($out, 0, -3);
- }
-
- return $out;
- }
-
- // Compatibilité SPIP
-
- static public function egal_a($value, $test)
- {
- if ($value == $test)
- return true;
- else
- return false;
- }
-
- static public function different_de($value, $test)
- {
- if ($value != $test)
- return true;
- else
- return false;
- }
-
- // disponible aussi avec : | ?{sioui, sinon}
- static public function choixsivide($value, $un, $deux = '')
- {
- if (empty($value) || !trim($value))
- return $deux;
- else
- return $un;
- }
-
- static public function sinon($value, $sinon = '')
- {
- if ($value)
- return $value;
- else
- return $sinon;
- }
-
- static public function choixsiegal($value, $test, $un, $deux)
- {
- return ($value == $test) ? $un : $deux;
- }
-
- static public function supprimer_tags($value, $replace = '')
- {
- return preg_replace('!<[^>]*>!', $replace, $value);
- }
-
- static public function supprimer_spip($value)
- {
- $value = preg_replace('!\[([^\]]+)(?:->[^\]]*)?\]!U', '$1', $value);
- $value = preg_replace('!\{+([^\}]*)\}+!', '$1', $value);
- return $value;
- }
-
- static public function couper($texte, $taille, $etc = ' (...)')
- {
- if (strlen($texte) > $taille)
- {
- $texte = substr($texte, 0, $taille);
- $taille -= ($taille * 0.1);
-
- $texte = preg_replace('!([\s.,;:\!?])[^\s.,;:\!?]*?$!', '\\1', $texte);
- $texte.= $etc;
- }
-
- return $texte;
- }
-
- static public function replace($texte, $expression, $replace, $modif='UsimsS')
- {
- return preg_replace('/'.$expression.'/'.$modif, $replace, $texte);
- }
-
- static public function plus($a, $b)
- {
- return $a + $b;
- }
-
- static public function moins($a, $b)
- {
- return $a - $b;
- }
-
- static public function mult($a, $b)
- {
- return $a * $b;
- }
-
- static public function div($a, $b)
- {
- return $b ? $a / $b : 0;
- }
-
- static public function modulo($a, $mod, $add)
- {
- return ($mod ? $nb % $mod : 0) + $add;
- }
-
- static public function vide($value)
- {
- return '';
- }
-
- static public function concat()
- {
- return implode('', func_get_args());
- }
-
- static public function singulier_ou_pluriel($nb, $singulier, $pluriel, $var = null)
- {
- if (!$nb)
- return '';
-
- if ($nb == 1)
- return str_replace('@'.$var.'@', $nb, $singulier);
- else
- return str_replace('@'.$var.'@', $nb, $pluriel);
- }
-
- static public function date_w3c($date)
- {
- return date(DATE_W3C, $date);
- }
-
- static public function et($value, $test)
- {
- return ($value && $test);
- }
-
- static public function ou($value, $test)
- {
- return ($value || $test);
- }
-
- static public function xou($value, $test)
- {
- return ($value XOR $test);
- }
-
- static public function oui($value)
- {
- return $value ? true : false;
- }
-
- static public function non($value)
- {
- return !$value ? true : false;
- }
-
- static public function superieur_a($value, $test)
- {
- return ($value > $test) ? true : false;
- }
-
- static public function superieur_ou_egal_a($value, $test)
- {
- return ($value >= $test) ? true : false;
- }
-
- static public function inferieur_a($value, $test)
- {
- return ($value < $test) ? true : false;
- }
-
- static public function inferieur_ou_egal_a($value, $test)
- {
- return ($value <= $test) ? true : false;
- }
-}
-
-?>
DELETED include/lib.static_cache.php
Index: include/lib.static_cache.php
==================================================================
--- include/lib.static_cache.php
+++ include/lib.static_cache.php
@@ -1,106 +0,0 @@
- (time() - (int)$expire)) ? false : true;
- }
-
- static public function get($id)
- {
- $path = self::_getCachePath($id);
- return file_get_contents($path);
- }
-
- static public function display($id)
- {
- $path = self::_getCachePath($id);
- return readfile($path);
- }
-
- static public function remove($id)
- {
- $path = self::_getCachePath($id);
- return unlink($path);
- }
-
- static public function clean($expire = self::CLEAN_EXPIRE)
- {
- $dir = self::_getCacheDir();
- $d = dir($dir);
-
- $expire = time() - $expire;
-
- while ($file = $d->read())
- {
- if ($file[0] == '.')
- {
- continue;
- }
-
- if (filemtime($dir . '/' . $file) > $expire)
- {
- unlink($dir . '/' . $file);
- }
- }
-
- $d->close();
-
- return true;
- }
-}
-
-?>
DELETED include/lib.template.php
Index: include/lib.template.php
==================================================================
--- include/lib.template.php
+++ include/lib.template.php
@@ -1,559 +0,0 @@
-cache = false;
-
- $this->compile_dir = GARRADIN_DATA_ROOT . '/cache/compiled';
- $this->template_dir = GARRADIN_ROOT . '/templates';
-
- $this->compile_check = true;
-
- $this->reserved_template_varname = 'tpl';
-
- $this->assign('www_url', WWW_URL);
- $this->assign('self_url', utils::getSelfUrl());
-
- $this->assign('is_logged', false);
- }
-}
-
-$tpl = Template::getInstance();
-
-function tpl_csrf_field($params)
-{
- $name = utils::CSRF_field_name($params['key']);
- $value = utils::CSRF_create($params['key']);
-
- return '';
-}
-
-function tpl_form_field($params)
-{
- if (!isset($params['name']))
- throw new \BadFunctionCallException('name argument is mandatory');
-
- $name = $params['name'];
-
- if (isset($_POST[$name]))
- $value = $_POST[$name];
- elseif (isset($params['data']) && isset($params['data'][$name]))
- $value = $params['data'][$name];
- elseif (isset($params['default']))
- $value = $params['default'];
- else
- $value = '';
-
- if (isset($params['checked']))
- {
- if ($value == $params['checked'])
- return ' checked="checked" ';
-
- return '';
- }
- elseif (isset($params['selected']))
- {
- if ($value == $params['selected'])
- return ' selected="selected" ';
-
- return '';
- }
-
- return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
-}
-
-function tpl_format_tel($n)
-{
- $n = preg_replace('![^\d\+]!', '', $n);
- $n = preg_replace('!(\+?\d{2})!', '\\1 ', $n);
- return $n;
-}
-
-function tpl_strftime_fr($ts, $format)
-{
- return utils::strftime_fr($format, $ts);
-}
-
-function tpl_date_fr($ts, $format)
-{
- return utils::date_fr($format, $ts);
-}
-
-function tpl_format_droits($params)
-{
- $droits = $params['droits'];
-
- $out = array('connexion' => '', 'inscription' => '', 'membres' => '', 'compta' => '',
- 'wiki' => '', 'config' => '');
- $classes = array(
- Membres::DROIT_AUCUN => 'aucun',
- Membres::DROIT_ACCES => 'acces',
- Membres::DROIT_ECRITURE=> 'ecriture',
- Membres::DROIT_ADMIN => 'admin',
- );
-
- foreach ($droits as $cle=>$droit)
- {
- $cle = str_replace('droit_', '', $cle);
-
- if (array_key_exists($cle, $out))
- {
-
- $class = $classes[$droit];
- $desc = false;
- $s = false;
-
- if ($cle == 'connexion')
- {
- if ($droit == Membres::DROIT_AUCUN)
- $desc = 'N\'a pas le droit de se connecter';
- else
- $desc = 'A le droit de se connecter';
- }
- elseif ($cle == 'inscription')
- {
- if ($droit == Membres::DROIT_AUCUN)
- $desc = 'N\'a pas le droit de s\'inscrire seul';
- else
- $desc = 'A le droit de s\'inscrire seul';
- }
- elseif ($cle == 'config')
- {
- $s = '☑';
-
- if ($droit == Membres::DROIT_AUCUN)
- $desc = 'Ne peut modifier la configuration';
- else
- $desc = 'Peut modifier la configuration';
- }
- elseif ($cle == 'compta')
- {
- $s = '€';
- }
-
- if (!$s)
- $s = strtoupper($cle[0]);
-
- if (!$desc)
- {
- $desc = ucfirst($cle). ' : ';
-
- if ($droit == Membres::DROIT_AUCUN)
- $desc .= 'Pas accès';
- elseif ($droit == Membres::DROIT_ACCES)
- $desc .= 'Lecture uniquement';
- elseif ($droit == Membres::DROIT_ECRITURE)
- $desc .= 'Lecture & écriture';
- else
- $desc .= 'Administration';
- }
-
- $out[$cle] = ''.$s.'';
- }
- }
-
- return implode(' ', $out);
-}
-
-function tpl_format_wiki($str)
-{
- $str = utils::htmlLinksOnUrls($str);
- $str = utils::htmlSpip($str);
- $str = utils::htmlGarbage2xhtml($str);
- return $str;
-}
-
-function tpl_liens_wiki($str, $prefix)
-{
- return preg_replace_callback('!!i', function ($matches) use ($prefix) {
- return '';
- }, $str);
-}
-
-function tpl_pagination($params)
-{
- if (!isset($params['url']) || !isset($params['page']) || !isset($params['bypage']) || !isset($params['total']))
- throw new \BadFunctionCallException("Paramètre manquant pour pagination");
-
- if ($params['total'] == -1)
- return '';
-
- $pagination = utils::getGenericPagination($params['page'], $params['total'], $params['bypage']);
-
- if (empty($pagination))
- return '';
-
- $out = '';
-
- return $out;
-}
-
-function tpl_diff($params)
-{
- if (!isset($params['old']) || !isset($params['new']))
- {
- throw new Template_Exception('Paramètres old et new requis.');
- }
-
- $old = $params['old'];
- $new = $params['new'];
-
- require_once GARRADIN_ROOT . '/include/libs/diff/class.simplediff.php';
- $diff = simpleDiff::diff_to_array(false, $old, $new, 3);
-
- $out = '
';
- $prev = key($diff);
-
- foreach ($diff as $i=>$line)
- {
- if ($i > $prev + 1)
- {
- $out .= '
|
';
- }
-
- list($type, $old, $new) = $line;
-
- $class1 = $class2 = '';
- $t1 = $t2 = '';
-
- if ($type == simpleDiff::INS)
- {
- $class2 = 'ins';
- $t2 = '+';
- $old = htmlspecialchars($old, ENT_QUOTES, 'UTF-8');
- $new = htmlspecialchars($new, ENT_QUOTES, 'UTF-8');
- }
- elseif ($type == simpleDiff::DEL)
- {
- $class1 = 'del';
- $t1 = '-';
- $old = htmlspecialchars($old, ENT_QUOTES, 'UTF-8');
- $new = htmlspecialchars($new, ENT_QUOTES, 'UTF-8');
- }
- elseif ($type == simpleDiff::CHANGED)
- {
- $class1 = 'del';
- $class2 = 'ins';
- $t1 = '-';
- $t2 = '+';
-
- $lineDiff = simpleDiff::wdiff($old, $new);
- $lineDiff = htmlspecialchars($lineDiff, ENT_QUOTES, 'UTF-8');
-
- // Don't show new things in deleted line
- $old = preg_replace('!\{\+(?:.*)\+\}!U', '', $lineDiff);
- $old = str_replace(' ', ' ', $old);
- $old = str_replace('-] [-', ' ', $old);
- $old = preg_replace('!\[-(.*)-\]!U', '\\1', $old);
-
- // Don't show old things in added line
- $new = preg_replace('!\[-(?:.*)-\]!U', '', $lineDiff);
- $new = str_replace(' ', ' ', $new);
- $new = str_replace('+} {+', ' ', $new);
- $new = preg_replace('!\{\+(.*)\+\}!U', '\\1', $new);
- }
- else
- {
- $old = htmlspecialchars($old, ENT_QUOTES, 'UTF-8');
- $new = htmlspecialchars($new, ENT_QUOTES, 'UTF-8');
- }
-
- $out .= '';
- $out .= ''.($i+1).' | ';
- $out .= ''.$t1.' | ';
- $out .= ''.$old.' | ';
- $out .= ''.$t2.' | ';
- $out .= ''.$new.' | ';
- $out .= '
';
-
- $prev = $i;
- }
-
- $out .= '
';
- return $out;
-}
-
-function tpl_select_compte($params)
-{
- $name = $params['name'];
- $comptes = $params['comptes'];
- $selected = isset($params['data'][$params['name']]) ? $params['data'][$params['name']] : utils::post($name);
-
- $out = '