Browse Source

v1.8.2

- Met à jour SimplePie : 1.4.3-2-geb6dd2d
- Désactive le référent
- Permet de purger le cache de RainTPL
- Utilise la langue du navigateur si pas connecté
- Échecs de connexion dans le log du serveur web
Christophe HENRY 4 years ago
parent
commit
eaa60f4ff7
50 changed files with 13526 additions and 14355 deletions
  1. 1 0
      .gitignore
  2. 67 3
      Configuration.class.php
  3. 0 1
      Event.class.php
  4. 9 8
      Feed.class.php
  5. 0 1
      Folder.class.php
  6. 24 2
      Functions.class.php
  7. 202 0
      Install.class.php
  8. 6 1
      Logger.class.php
  9. 33 52
      MysqlEntity.class.php
  10. 17 13
      Plugin.class.php
  11. 27 9
      README.md
  12. 0 11308
      SimplePie.class.php
  13. 12832 0
      SimplePie.compiled-1.4.3-2-geb6dd2d.php
  14. 2 1
      Update.class.php
  15. 81 6
      User.class.php
  16. 1 3
      about.php
  17. 13 5
      action.php
  18. 30 38
      common.php
  19. 35 7
      i18n.php
  20. 41 211
      install.php
  21. 10 0
      locale/en.json
  22. 12 2
      locale/eo.json
  23. 10 0
      locale/es.json
  24. 10 0
      locale/fr.json
  25. 1 2
      settings.php
  26. 0 57
      templates/marigolds-old/about.html
  27. 0 88
      templates/marigolds-old/article.html
  28. 0 363
      templates/marigolds-old/css/style.css
  29. BIN
      templates/marigolds-old/favicon.png
  30. 0 24
      templates/marigolds-old/footer.html
  31. 0 61
      templates/marigolds-old/header.html
  32. 0 225
      templates/marigolds-old/index.html
  33. 0 1
      templates/marigolds-old/js/libs/jqueryAndModernizr.min.js
  34. 0 838
      templates/marigolds-old/js/script.js
  35. 0 151
      templates/marigolds-old/locale/en.json
  36. 0 151
      templates/marigolds-old/locale/eo.json
  37. 0 151
      templates/marigolds-old/locale/es.json
  38. 0 151
      templates/marigolds-old/locale/fr.json
  39. 0 365
      templates/marigolds-old/settings.html
  40. 13 8
      templates/marigolds/about.html
  41. 0 4
      templates/marigolds/css/style.css
  42. 2 2
      templates/marigolds/header.html
  43. BIN
      templates/marigolds/images/QRcode-PhpGdLibraryRequired.png
  44. 1 33
      templates/marigolds/js/script.js
  45. 3 1
      templates/marigolds/locale/en.json
  46. 6 4
      templates/marigolds/locale/eo.json
  47. 3 1
      templates/marigolds/locale/es.json
  48. 3 1
      templates/marigolds/locale/fr.json
  49. 7 2
      templates/marigolds/settings.html
  50. 24 0
      updates/00008-unique-20160124.sql

+ 1 - 0
.gitignore

@@ -2,5 +2,6 @@
 /constant.php
 /logs/
 /plugins/
+/templates/ !/templates/marigolds/
 update.json
 *.log

+ 67 - 3
Configuration.class.php

@@ -11,14 +11,43 @@ class Configuration extends MysqlEntity{
 
     protected $id,$key,$value,$confTab;
     protected $TABLE_NAME = 'configuration';
-    protected $CLASS_NAME = 'Configuration';
     protected $object_fields =
     array(
         'id'=>'key',
-        'key'=>'longstring',
+        'key'=>'string',
         'value'=>'longstring'
     );
 
+    protected $object_fields_uniques =
+    array(
+        'key'
+    );
+
+    protected $options = array(
+        'articleDisplayAnonymous' => '0',
+        'articleDisplayAuthor' => '1',
+        'articleDisplayDate' => '1',
+        'articleDisplayFolderSort' => '1',
+        'articleDisplayHomeSort' => '1',
+        'articleDisplayLink' => '1',
+        'articleDisplayMode' => 'summary',
+        'articlePerPages' => '5',
+        'displayOnlyUnreadFeedFolder' => 'false',
+        'feedMaxEvents' => '50',
+        'language' => 'en',
+        'optionFeedIsVerbose' => 1,
+        'paginationScale' => 5,
+        'syncGradCount' => '10',
+        'synchronisationCode' => '',
+        'synchronisationEnableCache' => '0',
+        'synchronisationForceFeed' => '0',
+        'synchronisationType' => 'auto',
+        'theme' => 'marigolds',
+        'root' => '',
+        'cryptographicSalt' => '',
+        'otpEnabled' => 0
+    );
+
     function __construct(){
         parent::__construct();
     }
@@ -58,6 +87,10 @@ class Configuration extends MysqlEntity{
         unset($_SESSION['configuration']);
     }
 
+    protected function createSynchronisationCode() {
+        return substr(sha1(rand(0,30).time().rand(0,30)),0,10);
+    }
+
     public function add($key,$value){
         $config = new Configuration();
         $config->setKey($key);
@@ -67,6 +100,37 @@ class Configuration extends MysqlEntity{
         unset($_SESSION['configuration']);
     }
 
+    public function setDefaults() {
+        foreach($this->options as $option => $defaultValue) {
+            switch($option) {
+                case 'language':
+                    $value = isset($_POST['install_changeLngLeed']) ? $_POST['install_changeLngLeed'] : $defaultValue;
+                    break;
+                case 'theme':
+                    $value = isset($_POST['template']) ? $_POST['template'] : $defaultValue;
+                    break;
+                case 'synchronisationCode':
+                    $value = $this->createSynchronisationCode();
+                    break;
+                case 'root':
+                    $root = $_POST['root'];
+                    $value = (substr($root, strlen($root)-1)=='/'?$root:$root.'/');
+                    break;
+                case 'cryptographicSalt':
+                    $value = $this->generateSalt();
+                    break;
+                default:
+                    $value = $defaultValue;
+                    break;
+            }
+            $this->add($option, $value);
+        }
+    }
+
+    protected function generateSalt() {
+        return ''.mt_rand().mt_rand();
+    }
+
     function getId(){
         return $this->id;
     }
@@ -92,4 +156,4 @@ class Configuration extends MysqlEntity{
 
 }
 
-?>
+?>

+ 0 - 1
Event.class.php

@@ -10,7 +10,6 @@ class Event extends MysqlEntity{
 
     protected $id,$title,$guid,$content,$description,$pudate,$link,$feed,$category,$creator,$unread,$favorite;
     protected $TABLE_NAME = 'event';
-    protected $CLASS_NAME = 'Event';
     protected $object_fields =
     array(
         'id'=>'key',

+ 9 - 8
Feed.class.php

@@ -10,7 +10,6 @@ class Feed extends MysqlEntity{
 
     protected $id,$name,$url,$events=array(),$description,$website,$folder,$lastupdate,$isverbose,$lastSyncInError;
     protected $TABLE_NAME = 'feed';
-    protected $CLASS_NAME = 'Feed';
     protected $object_fields =
     array(
         'id'=>'key',
@@ -78,7 +77,7 @@ class Feed extends MysqlEntity{
         $feed->enable_cache($enableCache);
         $feed->force_feed($forceFeed);
         $feed->set_feed_url($this->url);
-        $feed->set_useragent('Mozilla/4.0 Leed (LightFeed Aggregator) '.VERSION_NAME.' by idleman http://projet.idleman.fr/leed');
+        $feed->set_useragent('Mozilla/4.0 Leed (LightFeed Aggregator) '.LEED_VERSION_NAME.' by idleman http://projet.idleman.fr/leed');
         $this->lastSyncInError = 0;
         $this->lastupdate = $_SERVER['REQUEST_TIME'];
         if (!$feed->init()) {
@@ -180,9 +179,9 @@ class Feed extends MysqlEntity{
             if (strpos($enclosureType, 'image/') === 0) {
                 $html .= '<img src="' . $enclosure->link . '" />';
             } elseif (strpos($enclosureType, 'audio/') === 0) {
-                $html .= '<audio src="' . $enclosure->link . '" preload="none" controls>'.$i18n->get('BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED').'</audio>';
+                $html .= '<audio src="' . $enclosure->link . '" preload="none" controls>'._t('BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED').'</audio>';
             } elseif (strpos($enclosureType, 'video/') === 0) {
-                $html .= '<video src="' . $enclosure->link . '" preload="none" controls>'.$i18n->get('BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED').'</video>';
+                $html .= '<video src="' . $enclosure->link . '" preload="none" controls>'._t('BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED').'</video>';
             } else {
                 $html .= '<a href="'.$enclosure->link.'"> '.$enclosureName.'</a>';
             }
@@ -207,7 +206,7 @@ class Feed extends MysqlEntity{
             DELETE FROM {$tableEvent} WHERE feed={$this->id} AND favorite!=1 AND unread!=1 AND syncId!={$currentSyncId} ORDER BY pubdate ASC LIMIT {$limit}
         ";
         ///@TODO: escape the variables inside mysql
-         $this->customExecute($query);
+         $this->customQuery($query);
     }
 
     function setId($id){
@@ -365,9 +364,11 @@ class Feed extends MysqlEntity{
                 echo date('d/m/Y H:i:s')."\t".$parseTimeStr."\t";
                 echo "{$feedName}\t{$feedUrlTxt}\n";
             } else {
-
-                if (!$parseOk) echo '<div class="errorSync">';
-                echo "<dt><i>{$parseTimeStr}s</i> | <a href='{$feedUrl}'>{$feedName}</a></dt>\n";
+                if (!$parseOk)
+                    echo '<div class="errorSync">';
+                else
+                    echo '<div>';
+                echo "<dt><i>{$parseTimeStr}s</i> | <a target='_blank' rel='noopener noreferrer' href='{$feedUrl}'>{$feedName}</a></dt>\n";
 
             }
             foreach($errors as $error) {

+ 0 - 1
Folder.class.php

@@ -10,7 +10,6 @@ class Folder extends MysqlEntity{
 
     protected $id,$name,$parent,$isopen;
     protected $TABLE_NAME = 'folder';
-    protected $CLASS_NAME = 'Folder';
     protected $object_fields =
     array(
         'id'=>'key',

+ 24 - 2
Functions.class.php

@@ -150,7 +150,7 @@ class Functions
         }
         $fin='…' ;
         $nb=$limit-1;
-        return mb_substr($str, 0, $nb, 'UTF-8').$fin;
+        return htmlentities(mb_substr($str, 0, $nb, 'UTF-8').$fin);
     }
 
 
@@ -391,5 +391,27 @@ class Functions
         }
     }
 
-}
+    /**
+    * Vide le contenu du cache de RainTpl
+    *
+    */
+    public static function purgeRaintplCache() {
+        $directory = raintpl::$cache_dir;
+        if ($directory) {
+            $files = glob($directory.'*.rtpl.php');
+            if ($files) {
+                foreach($files as $file) {
+                    if (!unlink($file)) {
+                        error_log("Leed: cannot unlink '$file'");
+                    }
+                }
+            } else {
+                error_log('Leed: Raintpl, no file cached: '.$directory.'   '.getcwd());
+            }
+        } else {
+            error_log('Leed: Raintpl cache directory not set!');
+        }
+    }
+
+    }
 ?>

+ 202 - 0
Install.class.php

@@ -0,0 +1,202 @@
+<?php
+
+class Install {
+
+    const DEFAULT_TABLES_PREFIX = 'leed__';
+    const CONSTANT_FILE = 'constant.php';
+    public $finished = false;
+    public $logs = array(
+        'errors' => array(),
+        'notices' => array()
+    );
+    public $options = array(
+        'user' => array(
+            'login' => "",
+            'password' => ""
+        ),
+        'db' => array(
+            'mysqlBase' => "",
+            'mysqlHost' => "",
+            'mysqlLogin' => "",
+            'mysqlMdp' => "",
+            'mysqlPrefix' => self::DEFAULT_TABLES_PREFIX
+        )
+    );
+    protected $salt;
+
+
+    public function __construct() {
+        require_once('Logger.class.php');
+        $this->logger = new Logger('install');
+    }
+
+    protected function overrideDefaultValues($_) {
+        foreach ($this->options as $type => $options) {
+            foreach ($options as $var => $defaultValue) {
+                if (!empty($_[$var])) {
+                    $val = $type === 'db' ? str_replace("'", "\'", $_[$var]) : Functions::secure($_[$var]);
+                    $this->options[$type][$var] = $val;
+                }
+            }
+        }
+    }
+
+    public function launch($_, $installActionName) {
+        $this->checkFunctionsExists();
+        if(!isset($_[$installActionName])) {
+            return false;
+        }
+        $this->overrideDefaultValues($_);
+        $this->checkLoginPassword();
+        $this->checkdb();
+        if(!$this->hasErrors()) {
+            $this->createConstantFile();
+
+            require_once('constant.php');
+            require_once('MysqlEntity.class.php');
+            class_exists('Update') or require_once('Update.class.php');
+            Update::ExecutePatch(true);
+            require_once('Feed.class.php');
+            require_once('Event.class.php');
+            require_once('User.class.php');
+            require_once('Folder.class.php');
+            require_once('Configuration.class.php');
+
+            $this->createConfig();
+            $this->createUser();
+            $this->setFinished(true);
+            $this->logger->destroy();
+        }
+    }
+
+    public function getDefaultRoot() {
+        $urlParts = explode('/', $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
+        array_pop($urlParts);
+        return implode('/', $urlParts);
+    }
+
+    protected function createConstantFile() {
+        $constant = "<?php
+//Host de Mysql, le plus souvent localhost ou 127.0.0.1
+define('MYSQL_HOST','{$this->options['db']['mysqlHost']}');
+//Identifiant MySQL
+define('MYSQL_LOGIN','{$this->options['db']['mysqlLogin']}');
+//mot de passe MySQL
+define('MYSQL_MDP','{$this->options['db']['mysqlMdp']}');
+//Nom de la base MySQL ou se trouvera leed
+define('MYSQL_BDD','{$this->options['db']['mysqlBase']}');
+//Prefix des noms des tables leed pour les bases de données uniques
+define('MYSQL_PREFIX','{$this->options['db']['mysqlPrefix']}');
+?>";
+
+        file_put_contents(self::CONSTANT_FILE, $constant);
+        if (!is_readable(self::CONSTANT_FILE))
+            die('"'.self::CONSTANT_FILE.'" not found!');
+    }
+
+    protected function createConfig() {
+        $configurationManager = new Configuration();
+        if ($configurationManager->tableExists()) {
+            $configurationManager->truncate();
+        }
+        $configurationManager->create();
+        $configurationManager->setDefaults();
+        $this->salt = $configurationManager->get('cryptographicSalt');
+    }
+
+    protected function createUser() {
+        $userManager = new User();
+        if ($userManager->tableExists()) {
+            $userManager->truncate();
+        }
+        $userManager->create();
+        $userManager->add($this->options['user']['login'], $this->options['user']['password'], $this->salt, $this->logger);
+        $_SESSION['currentUser'] = serialize($userManager->get($this->options['user']['login']));
+    }
+
+    protected function checkLoginPassword() {
+        if(
+            empty($this->options['user']['password'])
+            || empty($this->options['user']['login'])
+        ) {
+            $this->logs['errors'][] = _t('INSTALL_ERROR_USERPWD');
+            return false;
+        }
+        return true;
+    }
+
+    protected function checkDb() {
+        if(
+            empty($this->options['db']['mysqlHost'])
+            || empty($this->options['db']['mysqlLogin'])
+            || empty($this->options['db']['mysqlBase'])
+        ) {
+            $this->logs['errors'][] = _t('INSTALL_ERROR_DB_INFOS');
+            return false;
+        }
+        if (!Functions::testDb(
+            $this->options['db']['mysqlHost'], $this->options['db']['mysqlLogin'], $this->options['db']['mysqlMdp'], $this->options['db']['mysqlBase']
+        )) {
+            $this->logs['errors'][] = _t('INSTALL_ERROR_CONNEXION');
+        } else {
+            $this->logs['notices'][] = _t('INSTALL_INFO_CONNEXION');
+        }
+        return true;
+    }
+
+    public function hasErrors() {
+        return count($this->logs['errors']) > 0;
+    }
+
+    public function checkFunctionsExists() {
+        if(!is_writable('./')){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_RIGHT', array(str_replace(basename(__FILE__),'',__FILE__)));
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_RIGHT');
+        }
+        if (!@function_exists('mysqli_connect')){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_MYSQLICONNECT');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_MYSQLICONNECT');
+        }
+        if (!@function_exists('file_get_contents')){
+            $this->logs['errors'][] =  _t('INSTALL_ERROR_FILEGET');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_FILEGET');
+        }
+        if (!@function_exists('file_put_contents')){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_FILEPUT');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_FILEPUT');
+        }
+        if (!@function_exists('curl_exec')){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_CURL');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_CURL');
+        }
+        if (!@function_exists('gd_info')){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_GD');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_GD');
+        }
+        if (@version_compare(PHP_VERSION, '5.1.0') <= 0){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_PHPV', array(PHP_VERSION));
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_PHPV', array(PHP_VERSION));
+        }
+        if(ini_get('safe_mode') && ini_get('max_execution_time')!=0){
+            $this->logs['errors'][] = _t('INSTALL_ERROR_SAFEMODE');
+        }else{
+            $this->logs['notices'][] = _t('INSTALL_INFO_SAFEMODE');
+        }
+    }
+
+    public function setFinished($finished) {
+        $this->finished = $finished;
+
+    }
+
+    public function getFinished() {
+        return $this->finished;
+    }
+}

+ 6 - 1
Logger.class.php

@@ -25,7 +25,7 @@ class Logger {
         return $logs;
     }
 
-    protected function destroy(){
+    public function destroy(){
         unset($_SESSION[self::LOGGER_IDENTIFIER][$this->getName()]);
     }
 
@@ -37,6 +37,11 @@ class Logger {
         }
     }
 
+    public function hasLogs()
+    {
+        return count($this->logs) > 0;
+    }
+
     public function setName($name)
     {
         $this->name = $name;

+ 33 - 52
MysqlEntity.class.php

@@ -91,13 +91,12 @@ class MysqlEntity
     * Methode de suppression de l'entité
     * @author Valentin CARRUESCO
     * @category manipulation SQL
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return Aucun retour
     */
-    public function destroy($debug=false)
+    public function destroy()
     {
         $query = 'DROP TABLE IF EXISTS `'.MYSQL_PREFIX.$this->TABLE_NAME.'`;';
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $myQuery = $this->customQuery($query);
     }
 
@@ -105,13 +104,12 @@ class MysqlEntity
     * Methode de nettoyage de l'entité
     * @author Valentin CARRUESCO
     * @category manipulation SQL
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return Aucun retour
     */
-    public function truncate($debug=false)
+    public function truncate()
     {
         $query = 'TRUNCATE TABLE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`;';
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $myQuery = $this->customQuery($query);
     }
 
@@ -119,10 +117,9 @@ class MysqlEntity
     * Methode de creation de l'entité
     * @author Valentin CARRUESCO
     * @category manipulation SQL
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return Aucun retour
     */
-    public function create($debug=false){
+    public function create(){
         $query = 'CREATE TABLE IF NOT EXISTS `'.MYSQL_PREFIX.$this->TABLE_NAME.'` (';
 
         $i=false;
@@ -135,11 +132,16 @@ class MysqlEntity
                 $query .= ',KEY `index'.$field.'` (`'.$field.'`)';
             }
         }
+        if (isset($this->object_fields_uniques)){
+            foreach($this->object_fields_uniques as $field){
+                $query .= ',UNIQUE `unique'.$field.'` (`'.$field.'`)';
+            }
+        }
         $query .= ')
         ENGINE InnoDB,
         DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
         ;';
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $myQuery = $this->customQuery($query);
     }
 
@@ -172,7 +174,7 @@ class MysqlEntity
             }
 
             $query .=';';
-            if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+            if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
 
         $this->customQuery($query);
     }
@@ -213,7 +215,7 @@ class MysqlEntity
 
             $query .=');';
         }
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $this->customQuery($query);
         $this->$id_field =  (!isset($this->$id_field)?$this->dbconnector->connection->insert_id:$this->$id_field);
     }
@@ -225,10 +227,9 @@ class MysqlEntity
     * @param <Array> $colonnes=>$valeurs
     * @param <Array> $colonnes (WHERE) =>$valeurs (WHERE)
     * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return Aucun retour
     */
-    public function change($columns,$columns2,$operation='=',$debug=false){
+    public function change($columns,$columns2,$operation='='){
         $query = 'UPDATE `'.MYSQL_PREFIX.$this->TABLE_NAME.'` SET ';
         $i=false;
         foreach ($columns as $column=>$value){
@@ -237,7 +238,7 @@ class MysqlEntity
         }
         $query .= $this->getWhereClause($columns2, $operation);
 
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $this->customQuery($query);
     }
 
@@ -247,11 +248,10 @@ class MysqlEntity
     * @category manipulation SQL
     * @param <String> $ordre=null
     * @param <String> $limite=null
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return <Array<Entity>> $Entity
     */
-    public function populate($order=null,$limit=null,$debug=false){
-        $results = $this->loadAll(array(),$order,$limit,'=',$debug);
+    public function populate($order=null,$limit=null){
+        $results = $this->loadAll(array(),$order,$limit,'=');
         return $results;
     }
 
@@ -264,10 +264,9 @@ class MysqlEntity
     * @param <String> $ordre=null
     * @param <String> $limite=null
     * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return <Array<Entity>> $Entity
     */
-    public function loadAll($columns,$order=null,$limit=null,$operation="=",$debug=false,$selColumn='*'){
+    public function loadAll($columns,$order=null,$limit=null,$operation="=",$selColumn='*'){
         $objects = array();
         $whereClause = $this->getWhereClause($columns,$operation);
 
@@ -276,11 +275,12 @@ class MysqlEntity
             if($limit!=null) $query .='LIMIT '.$limit.' ';
             $query .=';';
 
-            if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+            if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
             $result = $this->customQuery($query);
             while($queryReturn = $result->fetch_assoc()){
 
-                $object = new $this->CLASS_NAME();
+                $thisClass = get_class($this);
+                $object = new $thisClass();
                 foreach($this->object_fields as $field=>$type){
                     if(isset($queryReturn[$field])) $object->$field = $queryReturn[$field];
                 }
@@ -290,8 +290,8 @@ class MysqlEntity
             return $objects;
     }
 
-    public function loadAllOnlyColumn($selColumn,$columns,$order=null,$limit=null,$operation="=",$debug=false){
-        $objects = $this->loadAll($columns,$order,$limit,$operation,$debug,$selColumn);
+    public function loadAllOnlyColumn($selColumn,$columns,$order=null,$limit=null,$operation="="){
+        $objects = $this->loadAll($columns,$order,$limit,$operation,$selColumn);
         if(count($objects)==0)$objects = array();
         return $objects;
     }
@@ -304,11 +304,10 @@ class MysqlEntity
     * @param <Array> $colonnes (WHERE)
     * @param <Array> $valeurs (WHERE)
     * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
     */
-    public function load($columns,$operation='=',$debug=false){
-        $objects = $this->loadAll($columns,null,1,$operation,$debug);
+    public function load($columns,$operation='='){
+        $objects = $this->loadAll($columns,null,1,$operation);
         if(!isset($objects[0]))$objects[0] = false;
         return $objects[0];
     }
@@ -320,18 +319,16 @@ class MysqlEntity
     * @param <Array> $colonnes (WHERE)
     * @param <Array> $valeurs (WHERE)
     * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
     */
-    public function getById($id,$operation='=',$debug=false){
-        return $this->load(array('id'=>$id),$operation,$debug);
+    public function getById($id,$operation='='){
+        return $this->load(array('id'=>$id),$operation);
     }
 
     /**
     * Methode de comptage des éléments de l'entité
     * @author Valentin CARRUESCO
     * @category manipulation SQL
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return<Integer> nombre de ligne dans l'entité'
     */
     public function rowCount($columns=null)
@@ -346,7 +343,7 @@ class MysqlEntity
             }
         }
         $query = 'SELECT COUNT(1) FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'`'.$whereClause;
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $myQuery = $this->customQuery($query);
         $number = $myQuery->fetch_array();
         return $number[0];
@@ -359,10 +356,9 @@ class MysqlEntity
     * @param <Array> $colonnes (WHERE)
     * @param <Array> $valeurs (WHERE)
     * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @param <String> $debug=false active le debug mode (0 ou 1)
     * @return Aucun retour
     */
-    public function delete($columns,$operation='=',$debug=false){
+    public function delete($columns,$operation='='){
         $whereClause = '';
 
         $i=false;
@@ -371,28 +367,13 @@ class MysqlEntity
             $whereClause .= '`'.$column.'`'.$operation.'"'.$this->secure($value, $column).'"';
         }
         $query = 'DELETE FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` WHERE '.$whereClause.' ;';
-        if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
+        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
         $this->customQuery($query);
 
     }
 
-    ///@TODO: pourquoi deux méthodes différentes qui font la même chose ?
-    public function customExecute($request){
-        if($this->debugAllQuery)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$request.'<br>'.$this->dbconnector->connection->error;
-        $result = $this->dbconnector->connection->query($request);
-        $error = $this->error();
-        if ($error) {
-            error_log('Leed error: '.$this->error());
-            error_log('Leed query: '.$query);
-        }
-        if (false===$result) {
-            throw new Exception($this->dbconnector->connection->error);
-        }
-        return $result;
-    }
-
     public function customQuery($request){
-        if($this->debugAllQuery)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$request.'<br>'.$this->dbconnector->connection->error;
+        if($this->debugAllQuery)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$request.'<br>'.$this->dbconnector->connection->error;
         $result = $this->dbconnector->connection->query($request);
         $error = $this->error();
         if ($error) {
@@ -436,10 +417,10 @@ class MysqlEntity
     */
 
     public function tableExists() {
-        $table = '`'.MYSQL_PREFIX.$this->TABLE_NAME.'';
+        $table = MYSQL_PREFIX.$this->TABLE_NAME;
         $result = $this->customQuery("SHOW TABLES LIKE '$table'");
         $assoc = $result->fetch_assoc();
-        return false===$assoc ? false : true;
+        return !is_null($assoc);
     }
 
     /**

+ 17 - 13
Plugin.class.php

@@ -15,12 +15,12 @@ class Plugin{
     }
 
     public static function includeAll(){
-        global $i18n, $i18n_js, $language, $theme;
+        global $i18n, $i18n_js, $theme;
         $pluginFiles = Plugin::getFiles(true);
         if(is_array($pluginFiles)) {
             foreach($pluginFiles as $pluginFile) {
                 // Chargement du fichier de Langue du plugin
-                $i18n->append(new Translation(dirname($pluginFile),$language));
+                $i18n->append(new Translation(dirname($pluginFile),$i18n->languages));
                 // Inclusion du coeur de plugin
                 include $pluginFile;
                 // Gestion des css du plugin en fonction du thème actif
@@ -132,7 +132,7 @@ class Plugin{
             $logger->appendLogs('Téléchargement du plugin...');
             $pluginBaseFolder = str_replace('/', '', self::FOLDER).'/';
             $tempZipName = $pluginBaseFolder.md5(microtime());
-            file_put_contents($tempZipName,file_get_contents(urldecode($url)), false, self::getContext());
+            file_put_contents($tempZipName,self::getUrlContent(urldecode($url)));
             if(file_exists($tempZipName)){
                 $logger->appendLogs('Plugin téléchargé <span class="button notice">OK</span>');
                 $logger->appendLogs('Extraction du plugin...');
@@ -193,7 +193,7 @@ class Plugin{
     }
 
     protected function getGithubMarketReposList() {
-        return json_decode(file_get_contents('https://api.github.com/orgs/Leed-market/repos', false, $this->getContext()));
+        return json_decode(self::getUrlContent("https://api.github.com/orgs/Leed-market/repos"));
     }
 
     protected function getGithubMarketReposInfos($repos) {
@@ -224,15 +224,19 @@ class Plugin{
         return $names;
     }
 
-    protected static function getContext() {
-        return stream_context_create(
-                array (
-                    'http' => array (
-                        'follow_location' => true,
-                        'user_agent' => $_SERVER['HTTP_USER_AGENT']
-                    )
-                )
-            );
+    protected static function getUrlContent($url) {
+        $timeout = 20;
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_REFERER, $url);
+        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
+        $datas = curl_exec($ch);
+        curl_close($ch);
+        return $datas;
     }
 
     public static function addHook($hookName, $functionName) {

+ 27 - 9
README.md

@@ -7,8 +7,11 @@ Leed (contraction de Light Feed) est un agrégateur [RSS](https://fr.wikipedia.o
 Cet agrégateur peut s'installer sur votre propre serveur et fonctionne avec un système de tâches [cron](https://fr.wikipedia.org/wiki/Cron) afin de traiter les informations de manière transparente et de les afficher le plus rapidement possible lorsque vous vous y connectez.
 
 - Application : Leed (Light Feed)
-- Version : Branche Stable
-- Auteur : Valentin CARRUESCO aka Idleman (idleman@idleman.fr)
+- Auteur : Valentin CARRUESCO aka **Idleman** (idleman@idleman.fr)
+- Contributeurs principaux : (par ordre alphabétique des pseudos)
+  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
+  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
+  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
 - Page du projet : http://projet.idleman.fr/leed
 - Licence : [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
 
@@ -21,7 +24,7 @@ Leed est également compatible avec le format d'import/export [OPML](https://fr.
 ### Pré-requis
 
 - Serveur Apache conseillé (non testé sur les autres serveurs type Nginx…)
-- PHP 5.3 minimum
+- PHP 5.5 minimum
 - MySQL
 - Un peu de bon sens :-)
 
@@ -64,6 +67,9 @@ Le dépot [Leed market](https://github.com/Leed-market) contient tous les plugin
 - Javascript : JQuery (http://www.jquery.com)
 - Moteur template : RainTPL (https://github.com/feulf/raintpl)
 - Parseur RSS : SimplePie (http://simplepie.org)
+- QR Code : PhpQrCode (https://sourceforge.net/projects/phpqrcode)
+- OTP : OtPhp (https://github.com/lelag/otphp)
+- Php GD : LibGD (https://libgd.github.io/)
 
 
 ---------
@@ -76,8 +82,11 @@ Leed (short for Light Feed) is a minimalist [RSS](https://fr.wikipedia.org/wiki/
 This reader can be installed on your own server and works with a system of [cron](https://fr.wikipedia.org/wiki/Cron)  tasks to process information in a transparent manner and display the updates as quick as possible when you connect to it.
 
 - Application: Leed (Light Feed)
-- Version : Branch Stable
-- Author : Valentin Carruesco aka Idleman ( idleman@idleman.fr )
+- Author: Valentin CARRUESCO aka **Idleman** (idleman@idleman.fr)
+- Main contributors: (alphabetical order of pseudos)
+  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
+  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
+  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
 - Project page: http://projet.idleman.fr/leed
 - License: [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
 
@@ -90,7 +99,7 @@ Leed is also compatible with [OPML](https://fr.wikipedia.org/wiki/OPML) import /
 ### Prerequisites
 
 - Recommended Apache server (not tested on other webservers such as Nginx…)
-- PHP 5.3 minimum
+- PHP 5.5 minimum
 - MySQL
 - A little common sense :-)
 
@@ -133,6 +142,9 @@ The [Leed-market](https://github.com/Leed-market) repository contains all the pl
 - Javascript: JQuery ( http://www.jquery.com )
 - Template Engine: RainTPL ( https://github.com/feulf/raintpl )
 - RSS Parser: SimplePie ( http://simplepie.org )
+- QR Code: PhpQrCode (https://sourceforge.net/projects/phpqrcode)
+- OTP: OtPhp (https://github.com/lelag/otphp)
+- Php GD : LibGD (https://libgd.github.io/)
  
 
 ---------
@@ -145,8 +157,11 @@ Leed (contracción de Light Feed) es un agregator [RSS](https://fr.wikipedia.org
 Se puede instalar este agregador sobre su servidor. Leed funciona con un sistema de tareas [cron](https://fr.wikipedia.org/wiki/Cron) para procesar los RSS de manera transparente y mostrarse tan pronto como sea posible cuando se conecta.
 
 - Script : Leed (Light Feed)
-- Versión : Branche Stable
-- Autor : Valentin CARRUESCO aka Idleman (idleman@idleman.fr)
+- Autor : Valentin CARRUESCO aka **Idleman** (idleman@idleman.fr)
+- Principales contribuyentes (por orden alfabético del pseudos):
+  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
+  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
+  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
 - Página del proyecto : http://projet.idleman.fr/leed
 - Licencia : [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
 
@@ -159,7 +174,7 @@ El script también está compatible con los archivos de exportación/importació
 ### Prerrequisito
 
 - Se recomienda Apache (non testé sur les autres serveurs type Nginx…)
-- PHP versión 5.3 mínima
+- PHP versión 5.5 mínima
 - MySQL
 - Un poco de sentido común ;-)
 
@@ -202,3 +217,6 @@ El repositorio [Leed market](https://github.com/Leed-market) contiene todos los
 - Javascript : JQuery (http://www.jquery.com)
 - PHP Template : RainTPL (https://github.com/feulf/raintpl)
 - RSS parser : SimplePie (http://simplepie.org)
+- QR Code : PhpQrCode (https://sourceforge.net/projects/phpqrcode)
+- OTP : OtPhp (https://github.com/lelag/otphp)
+- Php GD : LibGD (https://libgd.github.io/)

File diff suppressed because it is too large
+ 0 - 11308
SimplePie.class.php


File diff suppressed because it is too large
+ 12832 - 0
SimplePie.compiled-1.4.3-2-geb6dd2d.php


+ 2 - 1
Update.class.php

@@ -73,6 +73,7 @@ class Update{
         //si aucun nouveau fichier de mise à jour à traiter @return : false
         if(count($newFilesForUpdate)==0) return false;
         if (!$simulation) {
+            Functions::purgeRaintplCache();
             foreach($newFilesForUpdate as $file){
                 // récupération du contenu du sql
                 $sql = file_get_contents(dirname(__FILE__).Update::FOLDER.'/'.$file);
@@ -110,4 +111,4 @@ class Update{
 
 }
 
-?>
+?>

+ 81 - 6
User.class.php

@@ -11,11 +11,9 @@ class User extends MysqlEntity{
     const OTP_INTERVAL = 30;
     const OTP_DIGITS   = 8;
     const OTP_DIGEST   = 'sha1';
-    private $otpControler;
 
     protected $id,$login,$password,$otpSecret;
     protected $TABLE_NAME = 'user';
-    protected $CLASS_NAME = 'User';
     protected $object_fields =
     array(
         'id'=>'key',
@@ -24,6 +22,11 @@ class User extends MysqlEntity{
         'otpSecret'=>'string',
     );
 
+    protected $object_fields_uniques =
+    array(
+        'login'
+    );
+
     function __construct(){
         parent::__construct();
     }
@@ -81,6 +84,82 @@ class User extends MysqlEntity{
         return sha1($this->password.$this->login);
     }
 
+    public function add($login = false, $password = false, $salt = false, $logger = false) {
+        if(!$logger) {
+            require_once('Logger.class.php');
+            $logger = new Logger('settings');
+        }
+        if(empty($login)) {
+            $logger->appendLogs(_t("USER_ADD_MISSING_LOGIN"));
+        }
+        $existingUser = $this->load(array('login' => $login));
+        if($existingUser instanceof User) {
+            $logger->appendLogs(_t("USER_ADD_DUPLICATE"));
+            $logger->save();
+            return false;
+        }
+        if(empty($password)) {
+            $logger->appendLogs(_t("USER_ADD_MISSING_PASSWORD"));
+        }
+        if($logger->hasLogs()) {
+            $logger->save();
+            return false;
+        }
+        $this->setLogin($login);
+        $this->setPassword($password, $salt);
+        $this->save();
+        $this->createSideTables($login);
+        $logger->appendLogs(_t("USER_ADD_OK"). ' '.$login);
+        $logger->save();
+        return true;
+    }
+
+    public function remove($userId) {
+        require_once('Logger.class.php');
+        $logger = new Logger('settings');
+        if(empty($userId)) {
+            $logger->appendLogs(_t("USER_DEL_MISSING_ID"));
+            $logger->save();
+            return false;
+        }
+        $user = $this->load(array('id' => $userId));
+        if(!$user) {
+            $logger->appendLogs(_t("USER_DEL_UNKNOWN_ID").' '.$userId);
+            $logger->save();
+            return false;
+        }
+        $this->setLogin($user->getLogin());
+        $this->deleteSideTables();
+        $this->delete(array('id' => $userId));
+        $logger->appendLogs(_t("USER_DEL_OK").$user->getLogin());
+        $logger->save();
+        return true;
+    }
+
+    protected function createSideTables() {
+        $this->manageSideTables();
+    }
+
+    protected function deleteSideTables() {
+        $this->manageSideTables('remove');
+    }
+
+    protected function manageSideTables($action = 'add') {
+        $actionMethod = $action === 'add' ? 'create' : 'destroy';
+        $feedManager = new Feed();
+        $feedManager->$actionMethod();
+        $eventManager = new Event();
+        $eventManager->$actionMethod();
+        $folderManager = new Folder();
+        $folderManager->$actionMethod();
+        if($action === 'add' && $folderManager->rowCount() === '0') {
+            $folderManager->setName(_t('GENERAL_FOLDER'));
+            $folderManager->setParent(-1);
+            $folderManager->setIsopen(1);
+            $folderManager->save();
+        }
+    }
+
     static function existAuthToken($auth=null){
         $result = false;
         $userManager = new User();
@@ -143,10 +222,6 @@ class User extends MysqlEntity{
         return sha1($password.$salt);
     }
 
-    static function generateSalt() {
-        return ''.mt_rand().mt_rand();
-    }
-
 }
 
 ?>

+ 1 - 3
about.php

@@ -7,10 +7,8 @@
  */
 
 require_once('header.php');
-require_once('constant.php');
 
-$tpl->assign('VERSION_NUMBER',VERSION_NUMBER);
-$tpl->assign('VERSION_NAME',VERSION_NAME);
+$tpl->assign('otpEnabled', $configurationManager->get('otpEnabled'));
 $view = 'about';
 require_once('footer.php');
 

+ 13 - 5
action.php

@@ -24,7 +24,7 @@ Plugin::callHook("action_pre_case", array(&$_,$myUser));
 switch ($action){
     case 'commandLine':
     case 'synchronize':
-        require_once("SimplePie.class.php");
+        require_once("SimplePie.compiled-1.4.3-2-geb6dd2d.php");
         $syncCode = $configurationManager->get('synchronisationCode');
         $syncGradCount = $configurationManager->get('syncGradCount');
         if (   false==$myUser
@@ -152,13 +152,20 @@ switch ($action){
     break;
 
 
-    case 'purge':
+    case 'purgeEvents':
         if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
         $eventManager->truncate();
         header('location: ./settings.php');
     break;
 
 
+    case 'purgeCache':
+        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
+        Functions::purgeRaintplCache();
+        header('location: ./settings.php');
+    break;
+
+
     case 'exportFeed':
         if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
             /*********************/
@@ -289,7 +296,7 @@ switch ($action){
 
     case 'addFeed':
         if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        require_once("SimplePie.class.php");
+        require_once("SimplePie.compiled-1.4.3-2-geb6dd2d.php");
         if(!isset($_['newUrl'])) break;
         $newFeed = new Feed();
         $newFeed->setUrl(Functions::clean_url($_['newUrl']));
@@ -361,7 +368,7 @@ switch ($action){
     case 'removeFolder':
         if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
         if(isset($_['id']) && is_numeric($_['id']) && $_['id']>0){
-            $eventManager->customExecute('DELETE FROM `'.MYSQL_PREFIX.'event` WHERE `'.MYSQL_PREFIX.'event`.`feed` in (SELECT `'.MYSQL_PREFIX.'feed`.`id` FROM `'.MYSQL_PREFIX.'feed` WHERE `'.MYSQL_PREFIX.'feed`.`folder` =\''.intval($_['id']).'\') ;');
+            $eventManager->customQuery('DELETE FROM `'.MYSQL_PREFIX.'event` WHERE `'.MYSQL_PREFIX.'event`.`feed` in (SELECT `'.MYSQL_PREFIX.'feed`.`id` FROM `'.MYSQL_PREFIX.'feed` WHERE `'.MYSQL_PREFIX.'feed`.`folder` =\''.intval($_['id']).'\') ;');
             $feedManager->delete(array('folder'=>$_['id']));
             $folderManager->delete(array('id'=>$_['id']));
         }
@@ -458,6 +465,7 @@ switch ($action){
             if (empty($salt)) $salt = '';
             $user = $userManager->exist($_['login'],$_['password'],$salt,@$_['otp']);
             if($user==false){
+                error_log("Leed: wrong login for '".$_['login']."'");
                 header('location: ./index.php?action=wrongLogin');
             }else{
                 $_SESSION['currentUser'] = serialize($user);
@@ -557,7 +565,7 @@ switch ($action){
         break;
 
     default:
-        require_once("SimplePie.class.php");
+        require_once("SimplePie.compiled-1.4.3-2-geb6dd2d.php");
         Plugin::callHook("action_post_case", array(&$_,$myUser));
         //exit('0');
     break;

+ 30 - 38
common.php

@@ -6,21 +6,15 @@
  @description: Page incluse dans tous (ou presque) les fichiers du projet, inclus les entitées SQL et récupère/traite les variables de requetes
  */
 
-define('VERSION_NUMBER_CODE','1.8.1');
-define('VERSION_NAME_CODE','Stable');
-
-/* ----------MAJ de la version du constant.php--------------------- */
-if (is_writable('constant.php')) {
-    $content = file_get_contents('constant.php');
-    preg_match('#define\(\'VERSION_NUMBER\',\'([A-Za-z0-9.]+)\'\);?#',$content,$matches_version);
-    preg_match('#define\(\'VERSION_NAME\',\'([A-Za-z0-9.]+)\'\);?#',$content,$matches_name);
-    if ($matches_version[1]!=VERSION_NUMBER_CODE or $matches_name[1]!=VERSION_NAME_CODE)
-    {
-        $content = preg_replace('#define\(\'VERSION_NUMBER\',\'([A-Za-z0-9.]+)\'\);?#','define(\'VERSION_NUMBER\',\''.VERSION_NUMBER_CODE.'\');', $content);
-        $content = preg_replace('#define\(\'VERSION_NAME\',\'([A-Za-z0-9.]+)\'\);?#','define(\'VERSION_NAME\',\''.VERSION_NAME_CODE.'\');', $content);
-        file_put_contents('constant.php', $content);
-    }
-};
+define('LEED_VERSION_NUMBER','1.8.2');
+define('LEED_VERSION_NAME','stable');
+
+/* Assure la compatibilité des greffons utilisant ces anciennes constantes.
+ * Cela doit rester en place jusque Leed v2.0.
+ */
+if (!defined('VERSION_NUMBER')) define('VERSION_NUMBER', LEED_VERSION_NUMBER);
+if (!defined('VERSION_NAME')) define('VERSION_NAME', LEED_VERSION_NAME);
+
 /* ---------------------------------------------------------------- */
 // Mise en place d'un timezone par default pour utiliser les fonction de date en php
 $timezone_default = 'Europe/Paris'; // valeur par défaut :)
@@ -40,13 +34,12 @@ require_once('constant.php');
 require_once('RainTPL.php');
 require_once('i18n.php');
 require_once('otphp/lib/otphp.php');
+class_exists('Functions') or require_once('Functions.class.php');
 class_exists('Plugin') or require_once('Plugin.class.php');
 class_exists('MysqlEntity') or require_once('MysqlEntity.class.php');
 class_exists('Update') or require_once('Update.class.php');
-$resultUpdate = Update::ExecutePatch();
 class_exists('Feed') or require_once('Feed.class.php');
 class_exists('Event') or require_once('Event.class.php');
-class_exists('Functions') or require_once('Functions.class.php');
 class_exists('User') or require_once('User.class.php');
 class_exists('Folder') or require_once('Folder.class.php');
 class_exists('Configuration') or require_once('Configuration.class.php');
@@ -59,6 +52,20 @@ class_exists('Logger') or require_once('Logger.class.php');
 //Calage de la date
 date_default_timezone_set('Europe/Paris');
 
+$configurationManager = new Configuration();
+$conf = $configurationManager->getAll();
+
+$theme = $configurationManager->get('theme');
+
+//Instanciation du template
+$tpl = new RainTPL();
+//Definition des dossiers de template
+raintpl::configure("base_url", null );
+raintpl::configure("tpl_dir", './templates/'.$theme.'/' );
+raintpl::configure("cache_dir", "./cache/tmp/" );
+
+$resultUpdate = Update::ExecutePatch();
+
 $userManager = new User();
 $myUser = (isset($_SESSION['currentUser'])?unserialize($_SESSION['currentUser']):false);
 if (empty($myUser)) {
@@ -71,30 +78,15 @@ if (empty($myUser)) {
 $feedManager = new Feed();
 $eventManager = new Event();
 $folderManager = new Folder();
-$configurationManager = new Configuration();
-$conf = $configurationManager->getAll();
 
-$language = $configurationManager->get('language');
-//@todo requis pour la MAJ mais pourra être supprimé.
-if (empty($language)) {
-    // On tente de récupérer la valeur issue de 'constant.php'
-    if (defined('LANGUAGE')) $language = LANGUAGE;
-    elseif (defined('LANGAGE')) $language = LANGAGE; // ancien bug de nommage
-    else $language = Translation::DEFAULT_LANGUAGE;
-    $configurationManager->put('language', $language);
+// Sélection de la langue de l'interface utilisateur
+if (!$myUser) {
+    $languages = Translation::getHttpAcceptLanguages();
+} else {
+    $languages = array($configurationManager->get('language'));
 }
-// Faut-il supprimer la variable /langu?age/ de 'constant.php'?
-
-$theme = $configurationManager->get('theme');
-
-//Instanciation du template
-$tpl = new RainTPL();
-//Definition des dossiers de template
-raintpl::configure("base_url", null );
-raintpl::configure("tpl_dir", './templates/'.$theme.'/' );
-raintpl::configure("cache_dir", "./cache/tmp/" );
 
-i18n_init($language, dirname(__FILE__).'/templates/'.$theme.'/');
+i18n_init($languages, dirname(__FILE__).'/templates/'.$theme.'/');
 if ($resultUpdate) die (_t('LEED_UPDATE_MESSAGE'));
 
 $view = '';

+ 35 - 7
i18n.php

@@ -18,33 +18,37 @@ class Translation {
     // tableau associatif des traductions
     var $trans = array();
     var $language = ''; // langue courante
-    var $languages = array(); // langues disponibles
+    var $translatedLanguages = array(); // langues traduites
 
     /** @param location L'endroit où se trouve le dossier 'locale'
      *  @param languages Les langues demandées */
     function __construct($location, $languages=array()) {
         $this->location = $location;
         if (!is_array($languages)) $languages = array($languages);
-        $this->listLanguages();
+        $this->translatedLanguages = $this->listLanguages();
         $languages[]=self::DEFAULT_LANGUAGE;
-        foreach ($languages as $language)
+        $this->languages = $languages;
+        foreach ($languages as $language) {
+            if (empty($language)) continue;
             if ($this->load($language)) {
                 $this->language = $language;
                 break;
             }
+        }
     }
 
-    /* Peuple la liste des langues avec une traduction */
+    /* @return la liste des langues avec une traduction */
     protected function listLanguages() {
-        $this->languages = array();
+        $translatedLanguages = array();
         $files = glob($this->location.'/'.self::LOCALE_DIR.'/*.json');
         if (is_array($files)) {
             foreach($files as $file){
                 preg_match('/([a-z]{2})\.json$/', $file, $matches);
                 assert('!empty($matches)');
-                $this->languages [] = $matches[1];
+                $translatedLanguages [] = $matches[1];
             }
         }
+        return $translatedLanguages;
     }
 
     /* Charge la traduction
@@ -57,7 +61,7 @@ class Translation {
         }
         $trans = $this->loadFile($language);
         if (empty($trans)) return false;
-        assert('in_array($language, $this->languages)');
+        assert('in_array($language, $this->translatedLanguages)');
         if ($language!=self::DEFAULT_LANGUAGE) {
             $defaultTrans = $this->loadFile(self::DEFAULT_LANGUAGE);
             assert('!empty($defaultTrans)');
@@ -77,6 +81,14 @@ class Translation {
             $translations = array();
         } else {
             $translations = json_decode($content, true);
+            foreach ($translations as $id => $translation) {
+                if (empty($translation)) {
+                    # Retire les traductions vides afin qu'elles soient
+                    # traduites dans une autre langue si possible.
+                    unset($translations[$id]);
+                }
+            }
+
             if (!empty($content) && empty($translations))
                 error_log("Error while loading '$fileName'");
         }
@@ -109,6 +121,22 @@ class Translation {
         return json_encode($this->trans);
     }
 
+    /* @return un tableau des langues préférées */
+    static function getHttpAcceptLanguages($httpAcceptLanguage=Null) {
+        /** Exemple de directive :
+         * eo,fr;q=0.8,fr-FR;q=0.6,en-US;q=0.4,en;q=0.2
+         * Les langues sont séparées entre elles par des virgules.
+         * Chaque langue est séparée du coefficient, si présent, par un point-virgule.
+         */
+        // Suppose que les langues préférées sont en premier.
+        if (is_null($httpAcceptLanguage)) $httpAcceptLanguage = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
+        $languageList = array();
+        foreach (explode(',', $httpAcceptLanguage) as $language) {
+            $languageList[] = substr($language, 0, 2); // fr-FR;q=0.6 --> fr
+        }
+        return array_unique($languageList); // en-US,en-UK --> en, en --> en
+    }
+
 }
 
 // Initialise le singleton, avec les langues possibles

+ 41 - 211
install.php

@@ -7,9 +7,10 @@
  */
 
 require_once('Functions.class.php');
+require_once('Install.class.php');
 require_once('i18n.php');
 global $i18n;
-$install_terminee=false;
+$install = new Install();
 
 /* Prend le choix de langue de l'utilisateur, soit :
  * - lorsqu'il vient de changer la langue du sélecteur ($lang)
@@ -20,22 +21,25 @@ if (isset($_GET['lang'])) $lang = $_GET['lang'];
 elseif (isset($_POST['install_changeLngLeed'])) $lang = $_POST['install_changeLngLeed'];
 
 $installDirectory = dirname(__FILE__).'/install';
-if (empty($lang))
-    $currentLanguage = i18n_init(Functions::getBrowserLanguages(),$installDirectory);
-else
-    $currentLanguage = i18n_init($lang,$installDirectory);
 
-$languageList = $i18n->languages;
+// N'affiche que les langues du navigateur
+// @TODO: il faut afficher toutes les langues disponibles
+//        avec le choix par défaut de la langue préférée
+$languageList = Functions::getBrowserLanguages();
+if (!empty($lang)) {
+    // L'utilisateur a choisi une langue, qu'on incorpore dans la liste
+    array_unshift($languageList, $lang);
+    $liste = array_unique($languageList);
+}
+unset($i18n); //@TODO: gérer un singleton et le choix de langue / liste de langue
+$currentLanguage = i18n_init($languageList, $installDirectory);
+
+$languageList = array_unique($i18n->languages);
 
 if (file_exists('constant.php')) {
     die(_t('ALREADY_INSTALLED'));
 }
 
-/* Nombres de thèmes disponibles
- * 0 - Pas possible, car il y aura au moins Marigolds
- * 1 - Indique le thème (Marigolds), mais ne permet pas la modification
- * 2 - Indique un thème et permet la sélection. Marigolds est mis en premier. 
- */
 define('DEFAULT_TEMPLATE', 'marigolds');
 $templates = scandir('templates');
 if (!in_array(DEFAULT_TEMPLATE, $templates)) die('Missing default template : '.DEFAULT_TEMPLATE);
@@ -51,194 +55,15 @@ session_start();
 
 // Protection des variables
 $_ = array_merge($_GET, $_POST);
-$whiteList = array(
-    /* La liste blanche recense les variables ne devant pas être passées via
-       la sécurisation, mais simplement échappées pour Php. */
-    'mysqlHost', 'mysqlLogin', 'mysqlMdp', 'mysqlBase', 'mysqlPrefix',
-);
-foreach($_ as $key=>&$val){
- $val = in_array($key, $whiteList)
-    ? str_replace("'", "\'", $val)
-    : Functions::secure($val);
-}
-
-// Valeurs par défaut, remplacées si une autre valeur est saisie.
-foreach (array('login','mysqlBase','mysqlHost','mysqlLogin','mysqlMdp','mysqlPrefix','password','root') as $var) {
-    /* Initalise les variables avec le contenu des champs
-     * pour rappeler les valeurs déjà saisies. */
-    if (!empty($_[$var]))
-        $$var = $_[$var];
-    else
-        $$var = '';
-}
-if (empty($root)) {
-    // Ne peut être vide, alors on met la valeur par défaut
-    $root = str_replace(
-        basename(__FILE__),
-        '',
-        $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']
-    );
-}
-if (!isset($_['mysqlPrefix'])) {
-    // Le formulaire n'étant pas soumis, on met cette valeur par défaut.
-    $mysqlPrefix = 'leed__'; // séparation en groupe de tables PhpMyAdmin
-}
-
-$lib_errors = _t('ERROR');
-$lib_success = _t('SUCCESS');
+$installActionName = 'installButton';
+$install->launch($_, $installActionName);
 
-if(isset($_['installButton'])){
-    if (empty($_['password']) || empty($_['login'])) {
-        $test[$lib_errors][] = _t('INSTALL_ERROR_USERPWD');
-    }
-    if (!Functions::testDb(
-        $_['mysqlHost'], $_['mysqlLogin'], $_['mysqlMdp'], $_['mysqlBase']
-    )) {
-        $test[$lib_errors][] = _t('INSTALL_ERROR_CONNEXION');
-    } else {
-        $test[$lib_success][] = _t('INSTALL_INFO_CONNEXION');
-    }
-}
-if(!is_writable('./')){
-    $test[$lib_errors][]=_t('INSTALL_ERROR_RIGHT', array(str_replace(basename(__FILE__),'',__FILE__)));
-}else{
-    $test[$lib_success][]=_t('INSTALL_INFO_RIGHT');
-}
-if (!@function_exists('mysqli_connect')){
-    $test[$lib_errors][] = _t('INSTALL_ERROR_MYSQLICONNECT');
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_MYSQLICONNECT');
-}
-if (!@function_exists('file_get_contents')){
-    $test[$lib_errors][] =  _t('INSTALL_ERROR_FILEGET');
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_FILEGET');
-}
-if (!@function_exists('file_put_contents')){
-    $test[$lib_errors][] = _t('INSTALL_ERROR_FILEPUT');
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_FILEPUT');
-}
-if (!@function_exists('curl_exec')){
-    $test[$lib_errors][] = _t('INSTALL_ERROR_CURL');
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_CURL');
-}
-if (@version_compare(PHP_VERSION, '5.1.0') <= 0){
-    $test[$lib_errors][] = _t('INSTALL_ERROR_PHPV', array(PHP_VERSION));
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_PHPV', array(PHP_VERSION));
-}
-if(ini_get('safe_mode') && ini_get('max_execution_time')!=0){
-    $test[$lib_errors][] = _t('INSTALL_ERROR_SAFEMODE');
-}else{
-    $test[$lib_success][] = _t('INSTALL_INFO_SAFEMODE');
-}
-
-if (isset($_['installButton']) && empty($test[$lib_errors])) { // Pas d'erreur, l'installation peut se faire.
-    $constant = "<?php
-    define('VERSION_NUMBER','1.6');
-    define('VERSION_NAME','Dev');
-
-    //Host de Mysql, le plus souvent localhost ou 127.0.0.1
-    define('MYSQL_HOST','{$mysqlHost}');
-    //Identifiant MySQL
-    define('MYSQL_LOGIN','{$mysqlLogin}');
-    //mot de passe MySQL
-    define('MYSQL_MDP','{$mysqlMdp}');
-    //Nom de la base MySQL ou se trouvera leed
-    define('MYSQL_BDD','{$mysqlBase}');
-    //Prefix des noms des tables leed pour les bases de données uniques
-    define('MYSQL_PREFIX','{$mysqlPrefix}');
-?>";
-
-    file_put_contents('constant.php', $constant);
-    if (!is_readable('constant.php'))
-        die('"constant.php" not found!');
-
-    require_once('constant.php');
-    require_once('MysqlEntity.class.php');
-    class_exists('Update') or require_once('Update.class.php');
-    Update::ExecutePatch(true);
-    require_once('Feed.class.php');
-    require_once('Event.class.php');
-
-    require_once('User.class.php');
-    require_once('Folder.class.php');
-    require_once('Configuration.class.php');
-
-    $cryptographicSalt = User::generateSalt();
-    $synchronisationCode = substr(sha1(rand(0,30).time().rand(0,30)),0,10);
-    $root = (substr($_['root'], strlen($_['root'])-1)=='/'?$_['root']:$_['root'].'/');
-
-    // DOSSIERS À CONSERVER TELS QUELS, SI DÉJÀ EXISTANTS
-    $feedManager = new Feed(); $feedManager->create();
-    $eventManager = new Event(); $eventManager->create();
-
-    // COMPTE ADMINISTRATEUR, RÀZ SI NÉCESSAIRE
-    $userManager = new User();
-    if ($userManager->tableExists()) {
-        // Suppose qu'il n'y a qu'un seul utilisateur
-        $userManager->truncate();
-    }
-    $userManager->create();
-    $admin = new User();
-    $admin->setLogin($_['login']);
-    $admin->setPassword($_['password'],$cryptographicSalt);
-    $admin->save();
-    $_SESSION['currentUser'] = serialize($admin);
-
-    // DOSSIERS DE FLUX, RECRÉE LE DOSSIER GÉNÉRAL SI NÉCESSAIRE
-    $folderManager = new Folder();
-    $folderManager->create();
-    if ($folderManager->rowCount()==0) {
-        //Création du dossier général
-        $folder = new Folder();
-        $folder->setName(_t('GENERAL_FOLDER'));
-        $folder->setParent(-1);
-        $folder->setIsopen(1);
-        $folder->save();
-    }
-
-    // REMET À ZÉRO LA CONFIGURATION
-    $configurationManager = new Configuration();
-    if ($configurationManager->tableExists()) {
-        $configurationManager->truncate();
-    }
-    $configurationManager->create();
-    $configurationManager->add('articleDisplayAnonymous','0');
-    $configurationManager->add('articleDisplayAuthor','1');
-    $configurationManager->add('articleDisplayDate','1');
-    $configurationManager->add('articleDisplayFolderSort','1');
-    $configurationManager->add('articleDisplayHomeSort','1');
-    $configurationManager->add('articleDisplayLink','1');
-    $configurationManager->add('articleDisplayMode','summary');
-    $configurationManager->add('articlePerPages','5');
-    $configurationManager->add('cryptographicSalt', $cryptographicSalt);
-    $configurationManager->add('displayOnlyUnreadFeedFolder','false');
-    $configurationManager->add('feedMaxEvents','50');
-    $configurationManager->add('language', $_POST['install_changeLngLeed']);
-    $configurationManager->add('optionFeedIsVerbose',1);
-    $configurationManager->add('paginationScale',5);
-    $configurationManager->add('syncGradCount','10');
-    $configurationManager->add('synchronisationCode',$synchronisationCode);
-    $configurationManager->add('synchronisationEnableCache','0');
-    $configurationManager->add('synchronisationForceFeed','0');
-    $configurationManager->add('synchronisationType','auto');
-    $configurationManager->add('theme', $_POST['template']);
-    $configurationManager->add('root',$root);
-
-    $install_terminee=true;
-} /* Ci-dessous, on y va si :
-- la page est simplement affichée, sans avoir été validée
-- le formulaire est soumis, mais l'installation ne peut se faire
-*/
 ?>
 <!doctype html>
-<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
-<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
-<!--[if IE 8]>    <html class="no-js lt-ie9" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="<?php echo $currentLanguage;?>"> <![endif]-->
+<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="<?php echo $currentLanguage;?>"> <![endif]-->
+<!--[if IE 8]>    <html class="no-js lt-ie9" lang="<?php echo $currentLanguage;?>"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="<?php echo $currentLanguage;?>"> <!--<![endif]-->
 <head>
     <meta charset="utf-8">
     <meta name="referrer" content="no-referrer" />
@@ -299,14 +124,14 @@ if (isset($_['installButton']) && empty($test[$lib_errors])) { // Pas d'erreur,
         </header>
     </div>
     <?php
-    if ($install_terminee){
+    if ($install->getFinished()){
         echo '<div id="main-container">
                 <div id="main" class="wrapper clearfix">
                     <div id="menuBar"></div>
                         <h1>'._t('INSTALL_TITLE_END').'</h1>
                         <span>'._t('INSTALL_END').'</span>
                         <hr>
-                        <button id="installButton" name="installButton" onclick="document.location.href=\'settings.php#preferenceBloc\'">'._t('INSTALL_BTN_END').'</button>
+                        <button id="installButton" name="<?php echo $installActionName; ?>" onclick="document.location.href=\'settings.php#preferenceBloc\'">'._t('INSTALL_BTN_END').'</button>
               ';
         // écriture des balises de fin et ne pas faire la suite
         echo '</div>
@@ -329,12 +154,17 @@ if (isset($_['installButton']) && empty($test[$lib_errors])) { // Pas d'erreur,
             <h3 class="left"><?php echo _t('INSTALL_PRE_REQUIS') ?></h3>
             <ul class="clear" style="margin:0">
             <?php
-                foreach($test as $type=>$messages){
+                foreach($install->logs as $type => $messages){
+                    if(empty($messages)) {
+                        continue;
+                    }
                     $class = 'message ';
-                    $class .= $lib_errors==$type ? 'messageError':'messageSuccess';
-                    echo "<li class='$class'>$type&nbsp;:\n<ul>";
+                    $class .= $type === 'errors' ? 'messageError':'messageSuccess';
+                    $label = $type === 'errors' ? _t('ERROR') : _t('SUCCESS');
+                    echo "<li class='$class'>$label&nbsp;:<ul>";
+
                     foreach ($messages as $message){
-                        echo "<li>$message</li>\n";
+                        echo "<li>$message</li>";
                     }
                     echo "</ul></li>";
                 }
@@ -370,44 +200,44 @@ if (isset($_['installButton']) && empty($test[$lib_errors])) { // Pas d'erreur,
             </li>
             <li>
                 <span><?php echo _t('PROJECT_ROOT') ?></span>
-                <input type="text" name="root" value="<?php echo $root; ?>">
+                <input type="text" name="root" value="<?php echo $install->getDefaultRoot(); ?>">
             </li>
         </ul>
         <h2><?php echo _t('INSTALL_TAB_BDD') ?></h2>
         <ul>
             <li>
                 <span><?php echo _t('INSTALL_HOST') ?></span>
-                <input type="text" name="mysqlHost" value="<?php echo $mysqlHost; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_HOST') ?>">
+                <input type="text" name="mysqlHost" value="<?php echo $install->options['db']['mysqlHost']; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_HOST') ?>">
             </li>
             <li>
                 <span><?php echo _t('LOGIN') ?></span>
-                <input type="text" name="mysqlLogin" value="<?php echo $mysqlLogin; ?>">
+                <input type="text" name="mysqlLogin" value="<?php echo $install->options['db']['mysqlLogin']; ?>">
             </li>
             <li>
                 <span><?php echo _t('PASSWORD') ?></span>
-                <input type="text" autocomplete="off" name="mysqlMdp" value="<?php echo $mysqlMdp; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
+                <input type="text" autocomplete="off" name="mysqlMdp" value="<?php echo $install->options['db']['mysqlMdp']; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
             </li>
             <li>
                 <span><?php echo _t('INSTALL_BDD') ?></span>
-                <input type="text" name="mysqlBase" value="<?php echo $mysqlBase; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_BDD') ?>">
+                <input type="text" name="mysqlBase" value="<?php echo $install->options['db']['mysqlBase']; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_BDD') ?>">
             </li>
             <li>
                 <span><?php echo _t('INSTALL_PREFIX_TABLE') ?></span>
-                <input type="text" name="mysqlPrefix" value="<?php echo $mysqlPrefix; ?>">
+                <input type="text" name="mysqlPrefix" value="<?php echo $install->options['db']['mysqlPrefix']; ?>">
             </li>
         </ul>
         <h2><?php echo _t('INSTALL_TAB_ADMIN') ?></h2>
         <ul>
             <li>
                 <span><?php echo _t('LOGIN') ?></span>
-                <input type="text" name="login" value="<?php echo $login; ?>" placeholder="<?php echo _t('LOGIN') ?>">
+                <input type="text" name="login" value="<?php echo $install->options['user']['login']; ?>" placeholder="<?php echo _t('LOGIN') ?>">
             </li>
             <li>
                 <span><?php echo _t('PASSWORD') ?></span>
-                <input type="text" autocomplete="off" name="password" value="<?php echo $password; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
+                <input type="text" autocomplete="off" name="password" value="<?php echo $install->options['user']['password']; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
             </li>
         </ul>
-        <button id="installButton" name="installButton"><?php echo _t('INSTALL_BTN') ?></button>
+        <button id="installButton" name="<?php echo $installActionName; ?>"><?php echo _t('INSTALL_BTN') ?></button>
     </form>
 </div>
 <div id="footer-container">

+ 10 - 0
locale/en.json

@@ -26,8 +26,10 @@
  "INSTALL_END":"You can customize your installation through many plugins available <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
  "INSTALL_ERROR_CONNEXION":"Unable to connect to database",
  "INSTALL_ERROR_CURL":"The required function 'curl_exec' is inaccessible on your server, please install the Curl module for PHP.",
+ "INSTALL_ERROR_DB_INFOS":"The 'host', 'username' and 'base' fields about your database are required.",
  "INSTALL_ERROR_FILEGET":"The required function 'file_get_contents' is inaccessible on your server, check your version of PHP.",
  "INSTALL_ERROR_FILEPUT":"The required 'file_put_contents' is inaccessible on your server, check your version of PHP.",
+ "INSTALL_ERROR_GD":"The required 'gd_info' is inaccessible on your server, check your version of PHP.",
  "INSTALL_ERROR_MYSQLICONNECT":"The required function 'mysqli_connect' is inaccessible on your server, check your MySql installation.",
  "INSTALL_ERROR_PHPV":"Your PHP version ($1) is too old, it is possible that some features script include malfunctions.",
  "INSTALL_ERROR_RIGHT":"Can't write in Leed directory, please add write permissions on the entire folder (sudo chmod 777 -R $1, think about shielding permissions later)",
@@ -38,6 +40,7 @@
  "INSTALL_INFO_CURL":"Requested function 'curl_exec' : OK",
  "INSTALL_INFO_FILEGET":"Requested function 'file_get_contents' : OK",
  "INSTALL_INFO_FILEPUT":"Requested function 'file_put_contents' : OK",
+ "INSTALL_INFO_GD":"Requested function 'gd_info' : OK",
  "INSTALL_INFO_MYSQLICONNECT":"Requested function 'mysqli_connect' : OK",
  "INSTALL_INFO_PHPV":"Php version compatibility ($1) : OK",
  "INSTALL_INFO_RIGHT":"Permissions on the current folder: OK ",
@@ -67,5 +70,12 @@
  "SYNCHRONISATION_TYPE":"Synchronization type",
  "SYNCHRONIZE_COFFEE_TIME":"NB : The synchronization can take time, leave your browser do the job and go grab a coffee :).",
  "SYNCHRONIZE_NOW":"Synchronize now",
+ "USER_ADD_DUPLICATE":"A user with this login already exists. Please use another one.",
+ "USER_ADD_MISSING_LOGIN":"The login field can't be empty.",
+ "USER_ADD_MISSING_PASSWORD":"The password field can't be empty.",
+ "USER_ADD_OK":"User added.",
+ "USER_DEL_MISSING_ID":"Something went wrong: the user id is missing.",
+ "USER_DEL_OK":"User removed.",
+ "USER_DEL_UNKNOWN_ID":"Something went wrong: the user id is unknown",
  "YOU_MUST_BE_CONNECTED_ACTION":"You must be logged in for this action."
 }

+ 12 - 2
locale/eo.json

@@ -1,8 +1,8 @@
 {
  "ALREADY_INSTALLED":"Leed estas jam agordita. Forviŝu aû alinomu la dosieron agordan.",
  "AT_TOTAL":"Sume",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "Via retumilo ne apogas la sonan elementon.",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "Via retumilo ne apogas la videan elementon.",
+ "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED":"Via retumilo ne apogas la sonan elementon.",
+ "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED":"Via retumilo ne apogas la videan elementon.",
  "CLIC_HERE_SYNC_IMPORT":"klaku tie por sinkroni viajn fluojn enportitajn.",
  "ERROR":"Eraro",
  "ERRORS":"eraro(j)",
@@ -26,8 +26,10 @@
  "INSTALL_END":"Vi povas adapti vian instalon danke al multaj kromaĵoj haveblaj ĉe <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
  "INSTALL_ERROR_CONNEXION":"Konekto neebla al datumbazo.",
  "INSTALL_ERROR_CURL":"La funkcio nepra 'curl_exec' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
+ "INSTALL_ERROR_DB_INFOS":"La kampoj 'Gastiganto', 'salutnomo' kaj 'datumbazo' pri via datumbazo nepras.",
  "INSTALL_ERROR_FILEGET":"La funkcio nepra 'file_get_contents' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
  "INSTALL_ERROR_FILEPUT":"La funkcio nepra 'file_put_contents' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
+ "INSTALL_ERROR_GD":"La funkcio nepra 'gd_info' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
  "INSTALL_ERROR_MYSQLICONNECT":"La funkcio nepra 'mysqli_connect' ne akceseblas ĉe via servilo, kontrolu vian version de MySql.",
  "INSTALL_ERROR_PHPV":"Via versio de PHP ($1) estas tro malnova, eblas ke funkcioj misfunkcias.",
  "INSTALL_ERROR_RIGHT":"Ne eblas skribi en la dosierujon Leed, bonvolu aldoni permesojn por skribi sur la tuta dosierujo (sudo chmod 777 -R $1, pripensu finagordi la permesoj poste)",
@@ -38,6 +40,7 @@
  "INSTALL_INFO_CURL":"Funkcio nepra 'curl_exec': bone",
  "INSTALL_INFO_FILEGET":"Funkcio nepra 'file_get_contents': bone",
  "INSTALL_INFO_FILEPUT":"Funkcio nepra 'file_put_contents': bone",
+ "INSTALL_INFO_GD":"Funkcio nepra 'gd_info': bone",
  "INSTALL_INFO_MYSQLICONNECT":"Funkcio nepra 'mysqli_connect': bone",
  "INSTALL_INFO_PHPV":"Kongrueco versio PHP ($1): bone",
  "INSTALL_INFO_RIGHT":"Permesoj sur aktuala dosierujo: bone",
@@ -67,5 +70,12 @@
  "SYNCHRONISATION_TYPE":"tipo de sinkrono",
  "SYNCHRONIZE_COFFEE_TIME":"NB: La sinkronado povas daûri iom, lasu vian retumilon funkcii kaj iru trinki kafon.&nbsp;:)",
  "SYNCHRONIZE_NOW":"Sinkroni nun",
+ "USER_ADD_DUPLICATE":"Uzanto kun tiu salutnomo jam ekzistas. Bonvolu uzi alian.",
+ "USER_ADD_MISSING_LOGIN":"La salutnoma kampo ne estu malplena.",
+ "USER_ADD_MISSING_PASSWORD":"La pasvorta kampo ne estu malplena.",
+ "USER_ADD_OK":"Uzanto aldonita.",
+ "USER_DEL_MISSING_ID":"Io malbone okazis: la uzanta id forestas.",
+ "USER_DEL_OK":"Uzanto forviŝita.",
+ "USER_DEL_UNKNOWN_ID":"Io malbone okazis: la uzanta id nekonatas.",
  "YOU_MUST_BE_CONNECTED_ACTION":"Vi devas esti ensalutita por fari tiun agon."
 }

+ 10 - 0
locale/es.json

@@ -26,8 +26,10 @@
  "INSTALL_END":"Puede personalizar su instancia gracias a numerosos complementos que son disponibles sobre el <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
  "INSTALL_ERROR_CONNEXION":"No se puede conectar a la base de datos.",
  "INSTALL_ERROR_CURL":"Se necesita la función 'curl_exec' pero no es disponible sobre el servidor. Por favor, instale el módulo Curl por PHP.",
+ "INSTALL_ERROR_DB_INFOS":"Se necesitan los campos 'huésped', 'login' y 'base' en cuanto a vuestra base de datos.",
  "INSTALL_ERROR_FILEGET":"Se necesita la función 'file_get_contents' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
  "INSTALL_ERROR_FILEPUT":"Se necesita la función 'file_put_contents' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
+ "INSTALL_ERROR_GD":"Se necesita la función 'gd_info' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
  "INSTALL_ERROR_MYSQLICONNECT":"Se necesita la función 'mysqli_connect' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
  "INSTALL_ERROR_PHPV":"Su versión de PHP ($1) es demasiada antigua, se puede que algunas funcionalidades del script no funcionan.",
  "INSTALL_ERROR_RIGHT":"No se puede escribir en el directorio de Leed. Añadir los permisos para escribir sobre todo el directorio (sudo chmod 777 -R $1, pensar a modificarlo de nuevo por medida se seguridad después de la instalación)",
@@ -38,6 +40,7 @@
  "INSTALL_INFO_CURL":"Función necesaria 'curl_exec' : OK",
  "INSTALL_INFO_FILEGET":"Función necesaria 'file_get_contents' : OK",
  "INSTALL_INFO_FILEPUT":"Función necesaria 'file_put_contents' : OK",
+ "INSTALL_INFO_GD":"Función necesaria 'gd_info' : OK",
  "INSTALL_INFO_MYSQLICONNECT":"Función necesaria 'mysqli_connect' : OK",
  "INSTALL_INFO_PHPV":"Version de PHP ($1) compatible : OK",
  "INSTALL_INFO_RIGHT":"Permisos sobre el directorio corriente : OK",
@@ -67,5 +70,12 @@
  "SYNCHRONISATION_TYPE":"Tipo de syncronisación",
  "SYNCHRONIZE_COFFEE_TIME":"NB : La syncronisación puede tomar cierto tiempo, deje su navegador y vaya tomarse un cafe.&nbsp;:)",
  "SYNCHRONIZE_NOW":"Syncronisar ahora",
+ "USER_ADD_DUPLICATE":"Ya existe un usuario con ese nombre.",
+ "USER_ADD_MISSING_LOGIN":"El campo usuario no puede estar vacío.",
+ "USER_ADD_MISSING_PASSWORD":"El campo contraseña no puede estar vacío. ",
+ "USER_ADD_OK":"Usuario añadido.",
+ "USER_DEL_MISSING_ID":"Algo salió mal : id del usuario está vacío.",
+ "USER_DEL_OK":"Usuario suprimido.",
+ "USER_DEL_UNKNOWN_ID":"Algo salió mal : nombre de usuario desconocido.",
  "YOU_MUST_BE_CONNECTED_ACTION":"Usted debe haber iniciado una sesión para continuar."
 }

+ 10 - 0
locale/fr.json

@@ -26,8 +26,10 @@
  "INSTALL_END":"Vous pouvez personnaliser votre installation grâce à de nombreux plugins disponibles sur <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
  "INSTALL_ERROR_CONNEXION":"Connexion impossible à la base de données.",
  "INSTALL_ERROR_CURL":"La fonction requise 'curl_exec' est inaccessible sur votre serveur, veuillez installer le module Curl de PHP.",
+ "INSTALL_ERROR_DB_INFOS":"Les champs 'hôte', 'identifiant' et 'base' concernant votre base de données sont requis.",
  "INSTALL_ERROR_FILEGET":"La fonction requise 'file_get_contents' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
  "INSTALL_ERROR_FILEPUT":"La fonction requise 'file_put_contents' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
+ "INSTALL_ERROR_GD":"La fonction requise 'gd_info' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
  "INSTALL_ERROR_MYSQLICONNECT":"La fonction requise 'mysqli_connect' est inaccessible sur votre serveur, vérifiez votre installation de MySql.",
  "INSTALL_ERROR_PHPV":"Votre version de PHP ($1) est trop ancienne, il est possible que certaines fonctionnalités du script comportent des dysfonctionnements.",
  "INSTALL_ERROR_RIGHT":"Écriture impossible dans le répertoire Leed, veuillez ajouter les permissions en écriture sur tout le dossier (sudo chmod 777 -R $1, pensez à blinder les permissions par la suite)",
@@ -38,6 +40,7 @@
  "INSTALL_INFO_CURL":"Fonction requise 'curl_exec' : OK",
  "INSTALL_INFO_FILEGET":"Fonction requise 'file_get_contents' : OK",
  "INSTALL_INFO_FILEPUT":"Fonction requise 'file_put_contents' : OK",
+ "INSTALL_INFO_GD":"Fonction requise 'gd_info' : OK",
  "INSTALL_INFO_MYSQLICONNECT":"Fonction requise 'mysqli_connect' : OK",
  "INSTALL_INFO_PHPV":"Compatibilité version PHP ($1) : OK",
  "INSTALL_INFO_RIGHT":"Permissions sur le dossier courant : OK",
@@ -67,5 +70,12 @@
  "SYNCHRONISATION_TYPE":"Type de synchronisation",
  "SYNCHRONIZE_COFFEE_TIME":"NB : La synchronisation peut prendre un certain temps, laissez votre navigateur tourner et allez vous prendre un café.&nbsp;:)",
  "SYNCHRONIZE_NOW":"Synchroniser maintenant",
+ "USER_ADD_DUPLICATE":"Un utilisateur possédant cet identifiant existe déjà. Merci d'en utiliser un autre.",
+ "USER_ADD_MISSING_LOGIN":"Le champ de l'identifiant ne peut pas être vide.",
+ "USER_ADD_MISSING_PASSWORD":"Le champ du mot de passe ne peut pas être vide.",
+ "USER_ADD_OK":"Utilisateur ajouté.",
+ "USER_DEL_MISSING_ID":"Quelque chose s'est mal passé : l'id de l'utilisateur est absent.",
+ "USER_DEL_OK":"Utilisateur supprimé.",
+ "USER_DEL_UNKNOWN_ID":"Quelque chose s'est mal passé : l'id de l'utilisateur est inconnu.",
  "YOU_MUST_BE_CONNECTED_ACTION":"Vous devez être connecté pour effectuer cette action."
 }

+ 1 - 2
settings.php

@@ -14,8 +14,7 @@ $logger = new Logger('settings');
 $tpl->assign('logs',$logger->flushLogs());
 
 // gestion de la langue
-$languageList = $i18n->languages;
-$tpl->assign('languageList',$languageList);
+$tpl->assign('languageList',$i18n->translatedLanguages);
 $tpl->assign('currentLanguage',$configurationManager->get('language'));
 
 $wrongLogin = !empty($wrongLogin);

+ 0 - 57
templates/marigolds-old/about.html

@@ -1,57 +0,0 @@
-{include="header"}
-
-        <div id="main" class="wrapper clearfix about">
-
-            <div id="menuBar">
-                <aside>
-                    <h3>{function="_t('AUTHOR')"}</h3>
-                    <ul>
-                            <li>{function="_t('NAME')"} : Valentin CARRUESCO aka Idleman</li>
-                            <li>{function="_t('MAIL')"} : <a href="mailto: idleman@idleman.fr">idleman@idleman.fr</a></li>
-                            <li>{function="_t('BLOG')"} : <a href="http://blog.idleman.fr">blog.idleman.fr</a></li>
-                            <li>{function="_t('CONTRIBUTORS')"} : <a href="mailto:cobalt74@gmail.com">Maël ILLOUZ aka Cobalt74</a>, <a href="mailto:christophe.henry@sbgodin.fr">Christophe HENRY aka Sbgodin</a>, <a href="mailto:contact@simounet.net">Simon ALBERNY aka Simounet</a></li>
-                    </ul>
-                </aside>
-            </div>
-
-            <article>
-                <header>
-                    <h1>{function="_t('ABOUT')"}</h1>
-                    <p>{function="_t('ABOUT_LEED')"}</p>
-                </header>
-
-
-                <section>
-                    <h2>{function="_t('GENERALITY')"} :</h2>
-                    <ul>
-                        <li><b>{function="_t('APPLICATION')"} :</b> Leed (Light Feed)</li>
-                        <li><b>{function="_t('VERSION')"} :</b> {$VERSION_NUMBER} {$VERSION_NAME}</li>
-                        <li><b>{function="_t('AUTHOR')"} :</b> Valentin CARRUESCO aka <a href="mailto:idleman@idleman.fr">Idleman</a></li>
-                        <li><b>{function="_t('PROJECT_PAGE')"}:</b> <a href="http://projet.idleman.fr/leed">http://projet.idleman.fr/leed</a></li>
-                        <li><b>{function="_t('GIT_REPOSITORY')"} :</b> <a href="https://github.com/ldleman/Leed.git">https://github.com/ldleman/Leed.git</a></li>
-                        <li><b>Licence :</b> <a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a></li>
-                    </ul>
-
-                    <h2>{function="_t('PRESENTATION')"}</h2>
-                    <p>{function="_t('PRESENTATION_PARAGRAPH')"}</p>
-
-                    <h2>{function="_t('INSTALLATION')"}</h2>
-                    {function="_t('INSTALLATION_PARAGRAPH')"}
-
-                    <h2>{function="_t('QUESTIONS_SUGGESTIONS')"}</h2>
-                    {function="_t('QUESTIONS_SUGGESTIONS_PARAGRAPH')"}
-
-                    <h2>{function="_t('LIBRARIES')"}</h2>
-                    {function="_t('LIBRARIES_PARAGRAPHE')"}
-
-                </section>
-
-
-
-            </article>
-
-
-        </div> <!-- #main -->
-
-
-{include="footer"}

+ 0 - 88
templates/marigolds-old/article.html

@@ -1,88 +0,0 @@
-{loop="$events"}
-    {$plainDescription=strip_tags($value->getDescription())}
-
-    <!-- CORPS ARTICLE -->
-
-    {function="Plugin::callHook("event_pre_section", array(&$value))"}
-    <section id="{$value->getId()}" data-feed="{$value->getFeed()}" class="{if="!$value->getUnread()"}eventRead{/if} {$hightlighted%2==0?'eventHightLighted':''}{$scroll?' scroll':''}" {$scroll?'style="display: none;"':''}>
-        <a title="{function="_t('RETURN_TO_TOP')"}" class="goTopButton" href="#pageTopAnvil">ˆ</a>
-        <!-- TITRE -->
-        <h2 class="articleTitle">
-            {function="Plugin::callHook("event_pre_title", array(&$value))"}
-            <a onclick="readThis(this,{$value->getId()},'title');" target="_blank" rel="noopener noreferrer" href="{$value->getLink()}" title="{$plainDescription}">{$value->getTitle()}</a>
-            {function="Plugin::callHook("event_post_title", array(&$value))"}
-        </h2>
-        <!-- DETAILS + OPTIONS -->
-        <h3 class="articleDetails">
-            {function="Plugin::callHook("event_pre_top_options", array(&$value))"}
-            {if="$articleDisplayLink"}
-                <a href="{$value->getLink()}" target="_blank" rel="noopener noreferrer">{$allFeeds['idMap'][$value->getFeed()]['name']}</a>
-            {/if}
-            {if="$articleDisplayAuthor"}
-                {if="$value->getCreator()"}
-                    {function="_t('BY')"} {$value->getCreator()}
-                {/if}
-            {/if}
-
-            {if="$articleDisplayDate"}
-                {$value->getPubdateWithInstant($time)}
-            {/if}
-            {if="$value->getFavorite()!=1"} -  <a class="pointer favorite" onclick="addFavorite(this,{$value->getId()});" >{function="_t('FAVORIZE')"}</a>
-            {else}
-            <a class="pointer favorite" onclick="removeFavorite(this,{$value->getId()});" >{function="_t('UNFAVORIZE')"}</a>
-            {/if}
-            {if="$articleDisplayMode=='title'"}
-            <a class="pointer" id="btnDisplayMode_{$value->getId()}" onclick="toggleArticleDisplayMode(this,{$value->getId()})" title="{function="_t('EVENT_DISPLAY_TITLE')"}">|&nbsp;&nbsp;</a>
-            {/if}
-            {if="$articleDisplayMode=='summary'"}
-            <a class="pointer" id="btnDisplayMode_{$value->getId()}" onclick="toggleArticleDisplayMode(this,{$value->getId()})" title="{function="_t('EVENT_DISPLAY_SUMMARY')"}">||&nbsp;</a>
-            {/if}
-            {if="$articleDisplayMode=='content'"}
-            <a class="pointer" id="btnDisplayMode_{$value->getId()}" onclick="toggleArticleDisplayMode(this,{$value->getId()})" title="{function="_t('EVENT_DISPLAY_CONTENT')"}">|||</a>
-            {/if}
-            <a class="pointer right readUnreadButton">({function="_t('READ')"}/{function="_t('UNREAD')"})</a>
-            {function="Plugin::callHook("event_post_top_options", array(&$value))"}
-        </h3>
-
-        <!-- CONTENU/DESCRIPTION -->
-        {if="$articleDisplayMode=='summary'"}
-            <div class="articleContent summary">
-            {function="Plugin::callHook("event_pre_description", array(&$value))"}
-            {$value->getDescription()}
-            {function="Plugin::callHook("event_post_description", array(&$value))"}
-            </div>
-        {else}
-            <div class="articleContent summary" style="display: none;"></div>
-        {/if}
-
-        {if="$articleDisplayMode=='content'"}
-            <div class="articleContent content">
-            {function="Plugin::callHook("event_pre_content", array(&$value))"}
-            {$value->getContent()}
-            {function="Plugin::callHook("event_post_content", array(&$value))"}
-            </div>
-        {else}
-            <div class="articleContent content" style="display: none;"></div>
-        {/if}
-
-        {if="$articleDisplayMode=='content'"}
-        <!-- RAPPEL DETAILS + OPTIONS POUR LES ARTICLES AFFICHES EN ENTIER -->
-        <h3 class="articleDetails">
-        {else}
-        <h3 class="articleDetails" style="display: none;">
-        {/if}
-            {function="Plugin::callHook("event_pre_bottom_options", array(&$value))"}
-
-            <a class="pointer right readUnreadButton">({function="_t('READ')"}/{function="_t('UNREAD')"})</a>
-            {if="$value->getFavorite()!=1"}<a class="right pointer favorite"  onclick="addFavorite(this,{$value->getId()});">{function="_t('FAVORIZE')"}</a>
-            {else}
-            <a class="right pointer favorite" onclick="removeFavorite(this,{$value->getId()});">{function="_t('UNFAVORIZE')"}</a>
-            {/if}
-            <div class="clear"></div>
-            {function="Plugin::callHook("event_post_bottom_options", array(&$value))"}
-        </h3>
-    </section>
-    {function="Plugin::callHook("event_post_section", array(&$value))"}
-    {$hightlighted=$hightlighted+1}
-{/loop}
-{if="$scroll && $events"}<div class='scriptaddbutton'><script>addEventsButtonLuNonLus();</script></div>{/if}

File diff suppressed because it is too large
+ 0 - 363
templates/marigolds-old/css/style.css


BIN
templates/marigolds-old/favicon.png


+ 0 - 24
templates/marigolds-old/footer.html

@@ -1,24 +0,0 @@
-<!--
- @nom: footer
- @auteur: Idleman (idleman@idleman.fr)
- @description: Page de bas de page commun a toutes les vues
--->
-
-    </div> <!-- #main-container -->
-
-    <div id="footer-container">
-        <footer class="wrapper">
-            <p>Leed "Light Feed" {function="_t('FABULOUS_AGGREGATOR_LAUNCHED_IN',array($executionTime,'<a target="_blank" rel="noopener noreferrer" href="http://blog.idleman.fr">Idleman</a>'))"} | <a href="about.php">{function="_t('ABOUT',array())"}</a></p>
-            {function="Plugin::callHook("footer_post_copyright", array(&$myUser))"}
-        </footer>
-    </div>
-</div>
-
-<script>
-var  i18n = {$i18n_js};
-</script>
-<script src="js/libs/jqueryAndModernizr.min.js"></script>
-<script src="js/script.js"></script>
-{function="Plugin::callJs()"}
-</body>
-</html>

+ 0 - 61
templates/marigolds-old/header.html

@@ -1,61 +0,0 @@
-<!doctype html>
-<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
-<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
-<!--[if IE 8]>    <html class="no-js lt-ie9" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--><html class="no-js" lang="en"><!--<![endif]-->
-<head>
-    <title>Leed</title>
-    <meta charset="utf-8">
-    <meta name="referrer" content="no-referrer" />
-    <meta http-equiv="X-UA-Compatible" content="IE=100,chrome=1">
-    <meta name="description" content="Agrégateur de flux RSS Leed">
-    <meta name="author" content="IdleMan">
-    <link rel="shortcut icon" type="image/png" href="favicon.png">
-    <meta name="viewport" content="width=device-width">
-    <link rel="stylesheet" href="css/style.css">
-    {function="Plugin::callLink()"}
-    {function="Plugin::callCss()"}
-</head>
-<body>
-    <div class="global-wrapper">
-        <!-- <!> Balise ayant double utilité : sert de base a javascript pour connaitre l'action courante permet le retour en haut de page -->
-        <a id="pageTopAnvil"></a>
-        <a id="pageTop" class="hidden">{$action}</a>
-        <div id="header-container">
-            <header class="wrapper clearfix">
-                <h1 class="logo" id="title"><a href="./index.php">L<i>eed</i></a></h1>
-                <div class="loginBloc">
-                    {if="!$myUser"}
-                    {if="$wrongLogin"}
-                        {$wrongLoginClass=' wrongLogin'}
-                    {else}
-                        {$wrongLoginClass=''}
-                    {/if}
-                    <form action="action.php?action=login" method="POST" class="{$wrongLoginClass}">
-                        <input id="inputlogin" type="text" class="miniInput left" name="login" placeholder="{function="_t('LOGIN')"}"/>
-                        <input type="password" class="miniInput left" name="password" placeholder="{function="_t('PASSWORD')"}"/>
-                        <button class="left">GO!!</button>
-                        <span id="rememberMe">
-                            <input type="checkbox" name="rememberMe">
-                            <span>{function="_t('REMEMBER_ME')"}</span>
-                        </span>
-                        <div class="clear"></div>
-                    </form>
-                    {else}
-                        <span>{function="_t('IDENTIFIED_WITH',array('<span>'.$myUser->getLogin().'</span>'))"} </span><button onclick="window.location='action.php?action=logout'">{function="_t('DISCONNECT')"}</button>
-                    {/if}
-                    <div class="clear"></div>
-                </div>
-
-                <nav>
-                    <ul>
-                        <li><a href="index.php">{function="_t('HOME')"}</a></li>
-                        <li><a href="index.php?action=favorites">{function="_t('FAVORITES')"}</a></li>
-                        <li><a href="settings.php">{function="_t('MANAGE')"}</a></li>
-                        <li><a class="synchronyzeButton" title="{function="_t('LAUNCH_SYNCHRONISATION')"}" onclick="synchronize('{if="$myUser"}{$synchronisationCode}{/if}');">↺</a></li>
-                        {function="Plugin::callHook("navigate_post_link", array(&$myUser))"}
-                    </ul>
-                </nav>
-            </header>
-        </div>
-    <div id="main-container">

+ 0 - 225
templates/marigolds-old/index.html

@@ -1,225 +0,0 @@
-{include="header"}
-
-<!--
- @nom: index
- @auteur: Idleman (idleman@idleman.fr)
- @description: Page d'accueil et de lecture des flux
--->
-
-
-{if="($configurationManager->get('articleDisplayAnonymous')=='1') || ($myUser!=false)"}
-
-
-        <div id="helpPanel">
-            <h3>Raccourcis clavier</h3>
-            <ul>
-                <li>{function="_t('HELP_M')"}</li>
-                <li>{function="_t('HELP_L')"}</li>
-                <li>{function="_t('HELP_S')"}</li>
-                <li>{function="_t('HELP_N')"}</li>
-                <li>{function="_t('HELP_V')"}</li>
-                <li>{function="_t('HELP_P')"}</li>
-                <li>{function="_t('HELP_SPC')"}</li>
-                <li>{function="_t('HELP_K')"}</li>
-                <li>{function="_t('HELP_O_ENTER')"}</li>
-                <li>{function="_t('HELP_J')"}</li>
-                <li>{function="_t('HELP_H')"}</li>
-            </ul>
-        </div>
-
-        <div id="main" class="wrapper clearfix index">
-            <!--      -->
-            <!-- MENU -->
-            <!--      -->
-
-
-            <div id="menuBar">
-                {function="Plugin::callHook("menu_pre_folder_menu", array(&$myUser))"}
-            <aside>
-                <!-- TITRE MENU + OPTION TOUT MARQUER COMME LU -->
-                <h3 class="left">{function="_t('FEED')"}</h3> <button style="margin: 25px 0px 0px 10px;" onclick="if(confirm('{function="_t('CONFIRM_MARK_ALL_AS_READ')"}'))window.location='action.php?action=readAll'">{function="_t('MARK_ALL_AS_READ')"}</button>
-                <button class="right" onclick="toggleUnreadFeedFolder(this,{$displayOnlyUnreadFeedFolder_reverse});" title="{function="_t('DISPLAY_ONLY_UNREAD_FEEDFOLDER')"}" style="margin: 25px 4px 0px 10px;">&#8597;</button>
-                {function="Plugin::callHook("menu_post_header_options", array(&$myUser))"}
-                <ul class="clear">
-
-
-
-                        <!--Pour chaques dossier-->
-                        {loop="folders"}
-                            {$feeds=""}
-                            <!--on récupere tous les flux lié au dossier-->
-                              {if="isset($allFeedsPerFolder[$value->getId()])"}
-                                  {$feeds=$allFeedsPerFolder[$value->getId()]}
-                              {/if}
-                              {if="isset($allEvents[$value->getId()])"}
-                                  {$unreadEventsForFolder=$allEvents[$value->getId()]}
-                              {/if}
-
-                    <!-- DOSSIER -->
-                    <li>
-
-                        {if="$displayOnlyUnreadFeedFolder=='true'"}
-                        <!-- affichage uniquement des dossiers comportant des articles non lus -->
-                            {if="$unreadEventsForFolder>0"}
-                            <!-- cas de dossier avec des non lus -->
-                            <h1 class="folder">
-                                {function="Plugin::callHook("menu_pre_folder_link", array(&$value))"}
-                                <a  title="{function="_t('READ_FOLDER_ITEMS')"}" href="index.php?action=selectedFolder&amp;folder={$value->getId()}">{$value->getName()}</a> <a class="readFolder" title="{function="_t('FOLD_UNFOLD_FOLDER')"}" onclick="toggleFolder(this,{$value->getId()});" >{if="!$value->getIsopen()"}{function="_t('UNFOLD')"}{else}{function="_t('FOLD')"}{/if}</a> {if="$unreadEventsForFolder!=0"}<a class="unreadForFolder"  title="{function="_t('MARK_AS_READ_FOLDER_ITEMS',array($unreadEventsForFolder))"}" onclick="if(confirm('{function="_t('READ_ALL_FOLDER_CONFIRM')"}'))window.location='action.php?action=readFolder&amp;folder={$value->getId()}';">{$unreadEventsForFolder} {function="_t('UNREAD')"}</a>{/if}
-                                {function="Plugin::callHook("menu_post_folder_link", array(&$value))"}
-                            </h1>
-                            {else}
-                            <!-- cas de dossier sans non lus -->
-                                <h1 class="folder hidefeed"  style="display:none;">
-                                {function="Plugin::callHook("menu_pre_folder_link", array(&$value))"}
-                                <a  title="{function="_t('READ_FOLDER_ITEMS')"}" href="index.php?action=selectedFolder&amp;folder={$value->getId()}">{$value->getName()}</a> <a class="readFolder" title="{function="_t('FOLD_UNFOLD_FOLDER')"}" onclick="toggleFolder(this,{$value->getId()});" >{if="!$value->getIsopen()"}{function="_t('UNFOLD')"}{else}{function="_t('FOLD')"}{/if}</a> {if="$unreadEventsForFolder!=0"}<a class="unreadForFolder"  title="{function="_t('MARK_AS_READ_FOLDER_ITEMS',array($unreadEventsForFolder))"}" onclick="if(confirm('{function="_t('READ_ALL_FOLDER_CONFIRM')"}'))window.location='action.php?action=readFolder&amp;folder={$value->getId()}';">{$unreadEventsForFolder} {function="_t('UNREAD')"}</a>{/if}
-                                {function="Plugin::callHook("menu_post_folder_link", array(&$value))"}
-                            </h1>
-                            {/if}
-                        {else}
-                         <!-- affichage de tous les dossiers -->
-                            {if="$unreadEventsForFolder>0"}
-                            <!-- cas de dossier avec des non lus -->
-                            <h1 class="folder">
-                                {function="Plugin::callHook("menu_pre_folder_link", array(&$value))"}
-                                <a  title="{function="_t('READ_FOLDER_ITEMS')"}" href="index.php?action=selectedFolder&amp;folder={$value->getId()}">{$value->getName()}</a> <a class="readFolder" title="{function="_t('FOLD_UNFOLD_FOLDER')"}" onclick="toggleFolder(this,{$value->getId()});" >{if="!$value->getIsopen()"}{function="_t('UNFOLD')"}{else}{function="_t('FOLD')"}{/if}</a> {if="$unreadEventsForFolder!=0"}<a class="unreadForFolder"  title="{function="_t('MARK_AS_READ_FOLDER_ITEMS',array($unreadEventsForFolder))"}" onclick="if(confirm('{function="_t('READ_ALL_FOLDER_CONFIRM')"}'))window.location='action.php?action=readFolder&amp;folder={$value->getId()}';">{$unreadEventsForFolder} {function="_t('UNREAD')"}</a>{/if}
-                                {function="Plugin::callHook("menu_post_folder_link", array(&$value))"}
-                            </h1>
-                            {else}
-                            <!-- cas de dossier sans non lus donc à cacher si on passe dans l'autre mode -->
-                            <h1 class="folder hidefeed">
-                                {function="Plugin::callHook("menu_pre_folder_link", array(&$value))"}
-                                <a  title="{function="_t('READ_FOLDER_ITEMS')"}" href="index.php?action=selectedFolder&amp;folder={$value->getId()}">{$value->getName()}</a> <a class="readFolder" title="{function="_t('FOLD_UNFOLD_FOLDER')"}" onclick="toggleFolder(this,{$value->getId()});" >{if="!$value->getIsopen()"}{function="_t('UNFOLD')"}{else}{function="_t('FOLD')"}{/if}</a> {if="$unreadEventsForFolder!=0"}<a class="unreadForFolder"  title="{function="_t('MARK_AS_READ_FOLDER_ITEMS',array($unreadEventsForFolder))"}" onclick="if(confirm('{function="_t('READ_ALL_FOLDER_CONFIRM')"}'))window.location='action.php?action=readFolder&amp;folder={$value->getId()}';">{$unreadEventsForFolder} {function="_t('UNREAD')"}</a>{/if}
-                                {function="Plugin::callHook("menu_post_folder_link", array(&$value))"}
-                            </h1>
-                            {/if}
-                        {/if}
-                        <!-- FLUX DU DOSSIER -->
-                        <ul {if="!$value->getIsopen()"}style="display:none;"{/if}>
-
-                                {if="count($feeds)!=0"}
-                                    {loop="feeds"}
-                                        {if="$displayOnlyUnreadFeedFolder=='true'"}
-                                        <!-- Affichage des feeds ayant des articles non lus -->
-                                            {if="isset($unread[$value2['id']])"}
-                                                {if="$feedState->getById($value2['id'])->getLastSyncInError()==0"}
-                                                <li>
-                                                {else}
-                                                <li class="errorSync" title="{function="_t('SYNCHRONISATION_ERROR')"}">
-                                                {/if}
-                                                    {function="Plugin::callHook("menu_pre_feed_link", array(&$value))"}                                             <a href="index.php?action=selectedFeed&amp;feed={$value2['id']}" title="{$value2['url']}">{function="Functions::truncate($value2['name'],37)"} </a>
-                                                    <button class="right" style="margin:5px 0 0 10px;" onclick="if(confirm('{function="_t('CONFIRM_MARK_FEED_AS_READ')"}'))window.location='action.php?action=readAll&amp;feed={$value2['id']}';">
-                                                        <span title="{function="_t('MARK_AS_READ')"}">{$unread[$value2['id']]}</span>
-                                                    </button>
-                                                    {function="Plugin::callHook("menu_post_feed_link", array(&$value))"}
-                                                </li>
-                                            {else}
-                                                <!-- On cache les feeds n'ayant pas d'article non lus -->
-                                                    {if="$feedState->getById($value2['id'])->getLastSyncInError()==0"}
-                                                    <li class="hidefeed" style="display:none;">
-                                                    {else}
-                                                    <li class="hidefeed errorSync" style="display:none;" title="{function="_t('SYNCHRONISATION_ERROR')"}">
-                                                    {/if}
-                                                    {function="Plugin::callHook("menu_pre_feed_link", array(&$value))"}                                             <a href="index.php?action=selectedFeed&amp;feed={$value2['id']}" title="{$value2['url']}">{function="Functions::truncate($value2['name'],37)"} </a>
-                                                    {if="isset($unread[$value2['id']])"}
-                                                    <button class="right" style="margin:5px 0 0 10px;" onclick="if(confirm('{function="_t('CONFIRM_MARK_FEED_AS_READ')"}'))window.location='action.php?action=readAll&amp;feed={$value2['id']}';">
-                                                    <span title="{function="_t('MARK_AS_READ')"}">{$unread[$value2['id']]}</span>
-                                                    </button>
-                                                    {/if}
-                                                    {function="Plugin::callHook("menu_post_feed_link", array(&$value))"}
-                                                </li>
-                                            {/if}
-									    {else}
-                                        <!-- Affichage de tous les feeds -->
-                                            {if="isset($unread[$value2['id']])"}
-                                                {if="$feedState->getById($value2['id'])->getLastSyncInError()==0"}
-                                                <li>
-                                                {else}
-                                                <li class="errorSync" title="{function="_t('SYNCHRONISATION_ERROR')"}">
-                                                {/if}
-                                            {else} <!-- On affiche même ceux qui non pas d'article non lus -->
-                                                {if="$feedState->getById($value2['id'])->getLastSyncInError()==0"}
-                                                <li class="hidefeed">
-                                                {else}
-                                                <li class="hidefeed errorSync" title="{function="_t('SYNCHRONISATION_ERROR')"}">
-                                                {/if}
-                                            {/if}
-                                                {function="Plugin::callHook("menu_pre_feed_link", array(&$value))"}                                             <a href="index.php?action=selectedFeed&amp;feed={$value2['id']}" title="{$value2['url']}">{function="Functions::truncate($value2['name'],37)"} </a>
-                                                {if="isset($unread[$value2['id']])"}
-                                                    <button class="right" style="margin:5px 0 0 10px;" onclick="if(confirm('{function="_t('CONFIRM_MARK_FEED_AS_READ')"}'))window.location='action.php?action=readAll&amp;feed={$value2['id']}';">
-                                                        <span title="{function="_t('MARK_AS_READ')"}">{$unread[$value2['id']]}</span>
-                                                    </button>
-                                                {/if}
-                                                {function="Plugin::callHook("menu_post_feed_link", array(&$value))"}
-                                            </li>
-                                        {/if}
-                                    {/loop}
-                                {/if}
-                        </ul>
-                        <!-- FIN FLUX DU DOSSIER -->
-                    </li>
-                    <!-- FIN DOSSIER -->
-                    {$unreadEventsForFolder=0}
-                    {/loop}
-
-
-
-                </ul>
-            </aside>
-
-            {function="Plugin::callHook("menu_post_folder_menu", array(&$myUser))"}
-            </div>
-            <!--          -->
-            <!-- ARTICLES -->
-            <!--          -->
-
-            <article>
-                <!-- ENTETE ARTICLE -->
-                <header class="articleHead">
-
-                {if="$action=='selectedFeed'"}
-                <!-- AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER -->
-
-
-                    <h1 class="articleSection"><a target="_blank" rel="noopener noreferrer" href="{$currentFeed->getWebSite()}">{$currentFeed->getName()}</a></h1>
-                    <div class="clear"></div>
-                        {$currentFeed->getDescription()}
-                            {function="_t('SEE_THE')"}
-                    <a href="index.php?action=selectedFeed&amp;feed={$_['feed']}&amp;page={$page}&amp;order=unread">{function="ucfirst(_t('UNREAD'))"}</a> |
-                    <a href="index.php?action=selectedFeed&amp;feed={$_['feed']}&amp;page={$page}&amp;order=older">{function="_t('OLDER')"}</a> {function="_t('IN_FIRST')"}
-                {/if}
-
-                {if="$action=='selectedFolder'"}
-                <!-- AFFICHAGE DES EVENEMENTS D'UN DOSSIER EN PARTICULIER -->
-                    <h1 class="articleSection">{function="_t('FOLDER')"} : {$currentFolder->getName()}</h1>
-                    <p>{function="_t('SEE_EVENTS_FOR_FOLDER',array($currentFolder->getName()))"}</p>
-                {/if}
-
-                {if="$action=='favorites'"}
-                <!-- AFFICHAGE DES EVENEMENTS FAVORIS -->
-                    <h1 class="articleSection">{function="_t('FAVORITES_EVENTS',array('<span id="nbarticle">'.$numberOfItem.'</span>'))"}</h1>
-                {/if}
-
-
-                {if="($action=='unreadEvents') || ($action=='')"}
-                <!-- AFFICHAGE DES EVENEMENTS NON LU (COMPORTEMENT PAR DEFAUT) -->
-                    <h1 class="articleSection">{function="_t('UNREAD')"} (<span id="nbarticle">{$numberOfItem}</span>)</h1><div class="pointer right readUnreadButton" onmouseout="document.getElementById( 'helpPanel' ).style.display = 'none'" onmouseover="document.getElementById( 'helpPanel' ).style.display = 'block'" title="{function="_t('HELP_H_?')"}">?</div>
-                {/if}
-
-                 <div class="clear"></div>
-                </header>
-                {include="article"}
-            </article>
-
-
-        </div> <!-- #main -->
-
-{else}
-    <div id="main" class="wrapper clearfix">
-        <article>
-                <h3>{function="_t('YOU_MUST_BE_LOGGED')"}</h3>
-                <p>{function="_t('IF_ADMIN_THEN_CONFIG')"}</p>
-        </article>
-    </div>
-{/if}
-
-{include="footer"}

File diff suppressed because it is too large
+ 0 - 1
templates/marigolds-old/js/libs/jqueryAndModernizr.min.js


+ 0 - 838
templates/marigolds-old/js/script.js

@@ -1,838 +0,0 @@
-var keyCode = new Array();
-
-keyCode['shift'] = 16;
-keyCode['ctrl'] = 17;
-keyCode['enter'] = 13;
-keyCode['l'] = 76;
-keyCode['m'] = 77;
-keyCode['s'] = 83;
-keyCode['n'] = 78;
-keyCode['v'] = 86;
-keyCode['p'] = 80;
-keyCode['k'] = 75;
-keyCode['o'] = 79;
-keyCode['h'] = 72;
-keyCode['j'] = 74;
-keyCode['space'] = 32;
-
-$(document).ready(function(){
-
-    // Page settings
-    if($('.settings').length){
-
-        // Si nom du bloc en hash dans url
-        var hash=window.location.hash;
-        if(hash.length){
-            toggleBlocks(hash);
-        }
-
-        // Affichage des differents blocs apres clic sur le menu
-        $('.toggle').click(function(){
-                toggleBlocks($(this).attr("href"));
-            }
-        );
-
-    }else{
-
-        targetThisEvent($('article section:first'),true);
-        addEventsButtonLuNonLus();
-
-        // on initialise ajaxready à true au premier chargement de la fonction
-        $(window).data('ajaxready', true);
-        $('article').append('<div id="loader">'+_t('LOADING')+'</div>');
-        $(window).data('page', 1);
-        $(window).data('nblus', 0);
-
-        if ($(window).scrollTop()==0) scrollInfini();
-    }
-    //alert(_t('IDENTIFIED_WITH',['idleman']));
-
-    // focus sur l'input du login
-    if (document.getElementById('inputlogin')) document.getElementById('inputlogin').focus();
-});
-
-function _t(key,args){
-    value = i18n[key];
-    if(args!=null){
-        for(i=0;i<args.length;i++){
-            value = value.replace('$'+(i+1),args[i]);
-        }
-    }
-    return value;
-}
-
-$(document).keydown(function (e) {
-    switch(true) {
-        case e.altKey||e.ctrlKey||e.shiftKey||e.metaKey:
-        case $('.index').length==0:
-        case $("input:focus").length!=0:
-            return true;
-    }
-    switch(e.which){
-
-        case keyCode['m']:
-            //marque l'élément sélectionné comme lu / non lu
-            readTargetEvent();
-            return false;
-        break;
-
-        case keyCode['l']:
-            //marque l'élément precédent comme non lu et réafficher
-            targetPreviousEventRead();
-            return false;
-        break;
-
-        case keyCode['s']:
-            //marque l'élément sélectionné comme favori / non favori
-            switchFavoriteTargetEvent();
-            return false;
-        break;
-        case keyCode['n']:
-            //élément suivant (sans l'ouvrir)
-            targetNextEvent();
-            return false;
-        break;
-        case keyCode['v']:
-            //ouvre l'url de l'élément sélectionné
-            openTargetEvent();
-            return false;
-        break;
-        case keyCode['p']:
-            //élément précédent (sans l'ouvrir)
-            targetPreviousEvent();
-            return false;
-        break;
-        case keyCode['space']:
-            //élément suivant (et l'ouvrir)
-            targetNextEvent();
-            openTargetEvent();
-            return false;
-        break;
-        case keyCode['k']:
-            //élément précédent (et l'ouvrir)
-            targetPreviousEvent();
-            openTargetEvent();
-            return false;
-        break;
-        case keyCode['o']:
-        case keyCode['enter']:
-            //ouvrir l'élément sélectionné
-            openTargetEvent();
-            return false;
-        break;
-        case keyCode['h']:
-            //ouvrir/fermer le panneau d'aide
-            document.getElementById( 'helpPanel' ).style.display == 'block' ? document.getElementById( 'helpPanel' ).style.display = 'none' : document.getElementById( 'helpPanel' ).style.display = 'block';
-            return false;
-        break;
-        case keyCode['j']:
-            // Affiche / cache les blocs résumé / content
-            toggleArticleDisplayMode(document.getElementById('btnDisplayMode_'+$('.eventSelected').attr('id')),$('.eventSelected').attr('id'));
-            return false;
-        break;
-    }
-});
-
-$(window).scroll(function(){
-    scrollInfini();
-});
-
-
-/** SECTION MARKET & PLUGINS **/
-
-function togglePluginMenu(element,page){
-    $(element).parent().find('li').removeClass('selected');
-    $(element).addClass('selected');
-    if(page=='market'){
-        $('.marketZone').fadeIn(300);
-        $('.installedZone').hide();
-        $('#btnSearchPlugin').trigger("click");
-
-    }else{
-        $('.marketZone').hide();
-        $('.installedZone').fadeIn(300);
-    }
-}
-
-function searchPlugin(keyword){
-    $('#resultsPlugin').html('Chargement en cours...');
-    var baseUrl = (location.protocol == 'https:'?"https://market.idleman.fr:666":"http://market.idleman.fr")
-    $.getJSON(baseUrl+"/api.php?s=leed&m=search&k="+keyword+"&callback=?");
-}
-
-function jsonp(data){
-    
-    switch(data.method){
-        case 'search':
-            $('#resultsPlugin').html('');
-            if(data.results!=null && data.results.length>0){
-                for(var key in data.results){
-                    var plugin = data.results[key];
-                    tpl = 
-                    '<li>\
-                        <ul>\
-                            <li><h4>Nom: </h4>'+plugin.name+'</li>\
-                            <li><h4>Auteur: </h4><a href="mailto:'+plugin.mail+'">'+plugin.author+'</a></li>\
-                            <li><h4>Licence: </h4><a href="http://google.fr/#q='+plugin.licence+'">'+plugin.licence+'</a></li>\
-                            <li><h4>Version: </h4><code>'+plugin.version+'</code></li>\
-                            <li><h4>Site web: </h4><a href="'+plugin.link+'">'+plugin.link+'</a></li>\
-                            <li>'+plugin.description+'</li>\
-                            <li><button class="btn" onclick="installPlugin(\''+plugin.dll+'\');">Installer</button></li>\
-                        </ul>\
-                    </li>';
-                    $('#resultsPlugin').append(tpl);
-                }
-            }else{
-                $('#resultsPlugin').append('<li>Aucun résultats pour cette recherche.</li>');
-            }   
-        break;
-        case 'get':
-        
-        break;
-    }
-}
-
-function installPlugin(url){
-    $('#resultsPlugin').load('action.php?action=installPlugin&zip='+encodeURIComponent(url));
-}
-
-/** FIN MARKET & PLUGINS **/
-
-
-function scrollInfini() {
-    var deviceAgent = navigator.userAgent.toLowerCase();
-    var agentID = deviceAgent.match(/(iphone|ipod|ipad)/);
-
-    if($('.index').length) {
-        // On teste si ajaxready vaut false, auquel cas on stoppe la fonction
-        if ($(window).data('ajaxready') == false) return;
-
-        if(($(window).scrollTop() + $(window).height()) + 50 >= $(document).height()
-           || agentID && ($(window).scrollTop() + $(window).height()) + 150 > $(document).height()
-           || $('article').position().top + $('article').height() < $('aside').height()
-           )
-        {
-            // lorsqu'on commence un traitement, on met ajaxready à false
-            $(window).data('ajaxready', false);
-
-             //j'affiche mon loader pour indiquer le chargement
-            $('article #loader').show();
-
-            //utilisé pour l'alternance des couleurs d'un article à l'autre
-            if ($('article section:last').hasClass('eventHightLighted')) {
-                hightlighted = 1;
-            } else {
-                hightlighted = 2;
-            }
-
-            // récupération des variables passées en Get
-            var action = getUrlVars()['action'];
-            var folder = getUrlVars()['folder'];
-            var feed = getUrlVars()['feed'];
-            var order = getUrlVars()['order'];
-            if (order) {
-                order = '&order='+order
-            } else {
-                order = ''
-            }
-
-            $.ajax({
-                url: './article.php',
-                type: 'post',
-                data: 'scroll='+$(window).data('page')+'&nblus='+$(window).data('nblus')+'&hightlighted='+hightlighted+'&action='+action+'&folder='+folder+'&feed='+feed+order,
-
-                //Succès de la requête
-                success: function(data) {
-                    if (data.replace(/^\s+/g,'').replace(/\s+$/g,'') != '')
-                    {    // on les insère juste avant le loader
-                        $('article #loader').before(data);
-                        //on supprime de la page le script pour ne pas intéragir avec les next & prev
-                        $('article .scriptaddbutton').remove();
-                        //si l'élement courant est caché, selectionner le premier élément du scroll
-                        //ou si le div loader est sélectionné (quand 0 article restant suite au raccourcis M)
-                        if (($('article section.eventSelected').attr('style')=='display: none;')
-                            || ($('article div.eventSelected').attr('id')=='loader'))
-                        {
-                            targetThisEvent($('article section.scroll:first'), true);
-                        }
-                        // on les affiche avec un fadeIn
-                        $('article section.scroll').fadeIn(600);
-                        // on supprime le tag de classe pour le prochain scroll
-                        $('article section.scroll').removeClass('scroll');
-                        $(window).data('ajaxready', true);
-                        $(window).data('page', $(window).data('page')+1);
-                        $(window).data('enCoursScroll',0);
-                        // appel récursif tant qu'un scroll n'est pas detecté.
-                        if ($(window).scrollTop()==0) scrollInfini();
-                    } else {
-                        $('article #loader').addClass('finScroll');
-                    }
-                 },
-                complete: function(){
-                    // le chargement est terminé, on fait disparaitre notre loader
-                    $('article #loader').fadeOut(400);
-                }
-            });
-        }
-    }
-};
-
-/* Fonctions de séléctions */
-/* Cette fonction sera utilisé pour le scroll infinie, afin d'ajouter les évènements necessaires */
-function addEventsButtonLuNonLus(){
-    var handler = function(event){
-    var target = event.target;
-    var id = this.id;
-    if($(target).hasClass('readUnreadButton')){
-        buttonAction(target,id);
-    }else{
-        targetThisEvent(this);
-    }
-    }
-    // on vire tous les évènements afin de ne pas avoir des doublons d'évènements
-    $('article section').unbind('click');
-    // on bind proprement les click sur chaque section
-    $('article section').bind('click', handler);
-}
-
-function targetPreviousEvent(){
-    targetThisEvent($('.eventSelected').prevAll(':visible').first(),true);
-}
-function targetNextEvent(){
-
-    targetThisEvent($('.eventSelected').nextAll(':visible').first(),true);
-}
-
-function targetThisEvent(event,focusOn){
-    target = $(event);
-    if(target.prop("tagName")=='SECTION'){
-        $('.eventSelected').removeClass('eventSelected');
-        target.addClass('eventSelected');
-        var id = target.attr('id');
-        if(id && focusOn)window.location = '#'+id;
-    }
-    if(target.prop("tagName")=='DIV'){
-        $('.eventSelected').removeClass('eventSelected');
-        target.addClass('eventSelected');
-    }
-    // on débloque les touches le plus tard possible afin de passer derrière l'appel ajax
-}
-function openTargetEvent(){
-    window.open($('.eventSelected .articleTitle a').attr('href'), '_blank');
-}
-
-function readTargetEvent(){
-    var buttonElement = $('.eventSelected .readUnreadButton');
-    var id = $(target).attr('id');
-    readThis(buttonElement,id,null,function(){
-        // on fait un focus sur l'Event suivant
-        targetThisEvent($('.eventSelected').nextAll(':visible').first(),true);
-        $(window).scroll();
-    });
-}
-
-function targetPreviousEventRead(){
-    targetThisEvent($('.eventSelected').prev().css('display','block'),true);
-    var buttonElement = $('.eventSelected .readUnreadButton');
-    var id = $(target).attr('id');
-    unReadThis(buttonElement,id,null);
-}
-
-function readAllDisplayedEvents(){
-    $('article section').each(function(i,article){
-        var buttonElement = $('.readUnreadButton',article);
-        var id = $('.anchor',article).attr('id');
-        readThis(buttonElement,id);
-    });
-}
-
-function switchFavoriteTargetEvent(){
-    var id = $(target).attr('id');