mirror of
https://github.com/YunoHost-Apps/leed_ynh.git
synced 2024-09-03 19:26:32 +02:00
Add sources to repo
This commit is contained in:
commit
136b0f9ae5
43 changed files with 25977 additions and 0 deletions
95
sources/Configuration.class.php
Executable file
95
sources/Configuration.class.php
Executable file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
|
||||
/*
|
||||
@nom: Configuration
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de gestion des préférences, fonctionne sur un simple système clé=>valeur avec un cache session pour eviter les requête inutiles
|
||||
*/
|
||||
|
||||
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',
|
||||
'value'=>'longstring'
|
||||
);
|
||||
|
||||
function __construct(){
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function getAll(){
|
||||
|
||||
if(!isset($_SESSION['configuration'])){
|
||||
|
||||
$configurationManager = new Configuration();
|
||||
$configs = $configurationManager->populate();
|
||||
$confTab = array();
|
||||
|
||||
foreach($configs as $config){
|
||||
$this->confTab[$config->getKey()] = $config->getValue();
|
||||
}
|
||||
|
||||
$_SESSION['configuration'] = serialize($this->confTab);
|
||||
|
||||
}else{
|
||||
$this->confTab = unserialize($_SESSION['configuration']);
|
||||
}
|
||||
}
|
||||
|
||||
public function get($key){
|
||||
|
||||
return (isset($this->confTab[$key])?$this->confTab[$key]:'');
|
||||
}
|
||||
|
||||
public function put($key,$value){
|
||||
$configurationManager = new Configuration();
|
||||
if (isset($this->confTab[$key])){
|
||||
$configurationManager->change(array('value'=>$value),array('key'=>$key));
|
||||
} else {
|
||||
$configurationManager->add($key,$value);
|
||||
}
|
||||
$this->confTab[$key] = $value;
|
||||
unset($_SESSION['configuration']);
|
||||
}
|
||||
|
||||
public function add($key,$value){
|
||||
$config = new Configuration();
|
||||
$config->setKey($key);
|
||||
$config->setValue($value);
|
||||
$config->save();
|
||||
$this->confTab[$key] = $value;
|
||||
unset($_SESSION['configuration']);
|
||||
}
|
||||
|
||||
function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getKey(){
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
function setKey($key){
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
function getValue(){
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function setValue($value){
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
208
sources/Event.class.php
Executable file
208
sources/Event.class.php
Executable file
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: Event
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de gestion des évenements/news liés a chaques flux RSS/ATOM
|
||||
*/
|
||||
|
||||
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',
|
||||
'guid'=>'longstring',
|
||||
'title'=>'string',
|
||||
'creator'=>'string',
|
||||
'content'=>'longstring',
|
||||
'description'=>'longstring',
|
||||
'link'=>'longstring',
|
||||
'unread'=>'integer',
|
||||
'feed'=>'integer',
|
||||
'unread'=>'integer',
|
||||
'favorite'=>'integer',
|
||||
'pubdate'=>'integer',
|
||||
'syncId'=>'integer',
|
||||
);
|
||||
|
||||
protected $object_fields_index =
|
||||
array(
|
||||
'feed'=>'index',
|
||||
'unread'=>'index',
|
||||
'favorite'=>'index'
|
||||
);
|
||||
|
||||
function __construct($guid=null,$title=null,$description=null,$content=null,$pubdate=null,$link=null,$category=null,$creator=null){
|
||||
|
||||
$this->guid = $guid;
|
||||
$this->title = $title;
|
||||
$this->creator = $creator;
|
||||
$this->content = $content;
|
||||
$this->description = $description;
|
||||
$this->pubdate = $pubdate;
|
||||
$this->link = $link;
|
||||
$this->category = $category;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
function getEventCountPerFolder(){
|
||||
$events = array();
|
||||
$results = $this->customQuery('SELECT COUNT('.MYSQL_PREFIX.$this->TABLE_NAME.'.id),'.MYSQL_PREFIX.'feed.folder FROM '.MYSQL_PREFIX.$this->TABLE_NAME.' INNER JOIN '.MYSQL_PREFIX.'feed ON ('.MYSQL_PREFIX.'event.feed = '.MYSQL_PREFIX.'feed.id) WHERE '.MYSQL_PREFIX.$this->TABLE_NAME.'.unread=1 GROUP BY '.MYSQL_PREFIX.'feed.folder');
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$events[$item[1]] = $item[0];
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
function getEventCountNotVerboseFeed(){
|
||||
$results = $this->customQuery('SELECT COUNT(1) FROM '.MYSQL_PREFIX.$this->TABLE_NAME.' INNER JOIN '.MYSQL_PREFIX.'feed ON ('.MYSQL_PREFIX.'event.feed = '.MYSQL_PREFIX.'feed.id) WHERE '.MYSQL_PREFIX.$this->TABLE_NAME.'.unread=1 AND '.MYSQL_PREFIX.'feed.isverbose=0');
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$nbitem = $item[0];
|
||||
}
|
||||
|
||||
return $nbitem;
|
||||
}
|
||||
|
||||
function getEventsNotVerboseFeed($start=0,$limit=10000,$order,$columns='*'){
|
||||
$eventManager = new Event();
|
||||
$objects = array();
|
||||
$results = $this->customQuery('SELECT '.$columns.' FROM '.MYSQL_PREFIX.'event INNER JOIN '.MYSQL_PREFIX.'feed ON ('.MYSQL_PREFIX.'event.feed = '.MYSQL_PREFIX.'feed.id) WHERE '.MYSQL_PREFIX.'event.unread=1 AND '.MYSQL_PREFIX.'feed.isverbose = 0 ORDER BY '.$order.' LIMIT '.$start.','.$limit);
|
||||
if($results!=false){
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$object = new Event();
|
||||
foreach($object->getObject_fields() as $field=>$type){
|
||||
$setter = 'set'.ucFirst($field);
|
||||
if(isset($item[$field])) $object->$setter($item[$field]);
|
||||
}
|
||||
$objects[] = $object;
|
||||
unset($object);
|
||||
}
|
||||
}
|
||||
return $objects;
|
||||
}
|
||||
|
||||
function setId($id){
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function getCreator(){
|
||||
return $this->creator;
|
||||
}
|
||||
|
||||
function setCreator($creator){
|
||||
$this->creator = $creator;
|
||||
}
|
||||
|
||||
function getCategory(){
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
function setCategory($category){
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
function getDescription(){
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
function setDescription($description,$encoding = true){
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
function getPubdate($format=false){
|
||||
if($this->pubdate!=0){
|
||||
return ($format!=false?date($format,$this->pubdate):$this->pubdate);
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getPubdateWithInstant($instant){
|
||||
$alpha = $instant - $this->pubdate;
|
||||
if ($alpha < 86400 ){
|
||||
$hour = floor($alpha/3600);
|
||||
$alpha = ($hour!=0?$alpha-($hour*3600):$alpha);
|
||||
$minuts = floor($alpha/60);
|
||||
return 'il y a '.($hour!=0?$hour.'h et':'').' '.$minuts.'min';
|
||||
}else{
|
||||
return 'le '.$this->getPubdate('d/m/Y à H:i:s');
|
||||
}
|
||||
}
|
||||
|
||||
function setPubdate($pubdate){
|
||||
$this->pubdate = (is_numeric($pubdate)?$pubdate:strtotime($pubdate));
|
||||
}
|
||||
|
||||
function getLink(){
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
function setLink($link){
|
||||
$this->link = $link;
|
||||
}
|
||||
|
||||
function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getTitle(){
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
function setTitle($title){
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
function getContent(){
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
function setContent($content,$encoding=true){
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
|
||||
function getGuid(){
|
||||
return $this->guid;
|
||||
}
|
||||
|
||||
function setGuid($guid){
|
||||
$this->guid = $guid;
|
||||
}
|
||||
|
||||
function getSyncId(){
|
||||
return $this->syncId;
|
||||
}
|
||||
|
||||
function setSyncId($syncId){
|
||||
$this->syncId = $syncId;
|
||||
}
|
||||
|
||||
function getUnread(){
|
||||
return $this->unread;
|
||||
}
|
||||
|
||||
function setUnread($unread){
|
||||
$this->unread = $unread;
|
||||
}
|
||||
function setFeed($feed){
|
||||
$this->feed = $feed;
|
||||
}
|
||||
function getFeed(){
|
||||
return $this->feed;
|
||||
}
|
||||
function setFavorite($favorite){
|
||||
$this->favorite = $favorite;
|
||||
}
|
||||
function getFavorite(){
|
||||
return $this->favorite;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
304
sources/Feed.class.php
Executable file
304
sources/Feed.class.php
Executable file
|
@ -0,0 +1,304 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: Feed
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de gestion des flux RSS/ATOM
|
||||
*/
|
||||
|
||||
class Feed extends MysqlEntity{
|
||||
|
||||
protected $id,$name,$url,$events=array(),$description,$website,$folder,$lastupdate,$isverbose;
|
||||
protected $TABLE_NAME = 'feed';
|
||||
protected $CLASS_NAME = 'Feed';
|
||||
protected $object_fields =
|
||||
array(
|
||||
'id'=>'key',
|
||||
'name'=>'string',
|
||||
'description'=>'longstring',
|
||||
'website'=>'longstring',
|
||||
'url'=>'longstring',
|
||||
'lastupdate'=>'string',
|
||||
'folder'=>'integer',
|
||||
'isverbose'=>'boolean',
|
||||
);
|
||||
|
||||
protected $object_fields_index =
|
||||
array(
|
||||
'folder'=>'index'
|
||||
);
|
||||
|
||||
protected $error = '';
|
||||
|
||||
function __construct($name=null,$url=null){
|
||||
$this->name = $name;
|
||||
$this->url = $url;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/** @TODO: ne faire qu'un seul chargement avec SimplePie et récupérer les
|
||||
même informations. Mettre le chargement en cache au moins d'une méthode
|
||||
loadLeed() qui ne chargera qu'une seule fois. Voire même en déclenchement
|
||||
retardé, au dernier moment. */
|
||||
function getInfos(){
|
||||
$xml = @simplexml_load_file($this->url);
|
||||
if($xml!=false){
|
||||
$this->name = array_shift ($xml->xpath('channel/title'));
|
||||
$this->description = array_shift ($xml->xpath('channel/description'));
|
||||
$this->website = array_shift ($xml->xpath('channel/link'));
|
||||
}
|
||||
}
|
||||
|
||||
function getError() { return $this->error; }
|
||||
|
||||
/*@TODO: fournir un extrait quand il 'y a pas de description. De même pour les médias.
|
||||
@TODO: SimplePie remplace "é" par "é", il ne devrait pas le faire.
|
||||
J'ai testé set_stupidly_fast(true) sans succès.
|
||||
Il encadre les descriptions avec <div>, absents dans le source du flux.
|
||||
@TODO: la vérification de doublon est sous la responsabilité de l'appelant.
|
||||
Il serait peut-être utile de faire une méthode add() qui vérifie, plante si
|
||||
nécessaire, et appelle parse(). Impossible de vérifier dans parse() même
|
||||
car elle est appelée aussi pour autre chose que l'ajout.
|
||||
*/
|
||||
function parse($syncId,&$nbEvents =0, $enableCache=true, $forceFeed=false){
|
||||
$nbEvents = 0;
|
||||
assert('is_int($syncId) && $syncId>0');
|
||||
if (empty($this->id) || 0 == $this->id) {
|
||||
/* Le flux ne dispose pas pas d'id !. Ça arrive si on appelle
|
||||
parse() sans avoir appelé save() pour un nouveau flux.
|
||||
@TODO: un create() pour un nouveau flux ? */
|
||||
$msg = 'Empty or null id for a feed! '
|
||||
.'See '.__FILE__.' on line '.__LINE__;
|
||||
error_log($msg, E_USER_ERROR);
|
||||
die($msg); // Arrêt, sinon création événements sans flux associé.
|
||||
}
|
||||
$feed = new SimplePie();
|
||||
$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');
|
||||
if (!$feed->init()) {
|
||||
$this->error = $feed->error;
|
||||
$this->lastupdate = $_SERVER['REQUEST_TIME'];
|
||||
$this->save();
|
||||
return false;
|
||||
}
|
||||
|
||||
$feed->handle_content_type(); // UTF-8 par défaut pour SimplePie
|
||||
|
||||
if($this->name=='') $this->name = $feed->get_title();
|
||||
if($this->name=='') $this->name = $this->url;
|
||||
$this->website = $feed->get_link();
|
||||
$this->description = $feed->get_description();
|
||||
|
||||
$items = $feed->get_items();
|
||||
$eventManager = new Event();
|
||||
|
||||
$events = array();
|
||||
$iEvents = 0;
|
||||
foreach($items as $item){
|
||||
// Ne retient que les 100 premiers éléments de flux.
|
||||
if ($iEvents++>=100) break;
|
||||
|
||||
// Si le guid existe déjà, on évite de le reparcourir.
|
||||
$alreadyParsed = $eventManager->load(array('guid'=>$item->get_id(), 'feed'=>$this->id));
|
||||
if (isset($alreadyParsed)&&($alreadyParsed!=false)) {
|
||||
$events[]=$alreadyParsed->getId();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialisation des informations de l'événement (élt. de flux)
|
||||
$event = new Event();
|
||||
$event->setSyncId($syncId);
|
||||
$event->setGuid($item->get_id());
|
||||
$event->setTitle($item->get_title());
|
||||
$event->setPubdate($item->get_date());
|
||||
$event->setCreator(
|
||||
''==$item->get_author()
|
||||
? ''
|
||||
: $item->get_author()->name
|
||||
);
|
||||
$event->setLink($item->get_permalink());
|
||||
|
||||
$event->setFeed($this->id);
|
||||
$event->setUnread(1); // inexistant, donc non-lu
|
||||
|
||||
//Gestion de la balise enclosure pour les podcasts et autre cochonneries :)
|
||||
$enclosure = $item->get_enclosure();
|
||||
if($enclosure!=null && $enclosure->link!=''){
|
||||
$enclosureName = substr(
|
||||
$enclosure->link,
|
||||
strrpos($enclosure->link, '/')+1,
|
||||
strlen($enclosure->link)
|
||||
);
|
||||
$enclosureArgs = strpos($enclosureName, '?');
|
||||
if($enclosureArgs!==false)
|
||||
$enclosureName = substr($enclosureName,0,$enclosureArgs);
|
||||
$enclosureFormat = isset($enclosure->handler)
|
||||
? $enclosure->handler
|
||||
: substr($enclosureName, strrpos($enclosureName,'.')+1);
|
||||
|
||||
$enclosure ='<div class="enclosure"><h1>Fichier média :</h1><a href="'.$enclosure->link.'"> '.$enclosureName.'</a> <span>(Format '.strtoupper($enclosureFormat).', '.Functions::convertFileSize($enclosure->length).')</span></div>';
|
||||
}else{
|
||||
$enclosure = '';
|
||||
}
|
||||
|
||||
$event->setContent($item->get_content().$enclosure);
|
||||
$event->setDescription($item->get_description().$enclosure);
|
||||
|
||||
if(trim($event->getDescription())=='')
|
||||
$event->setDescription(
|
||||
substr($event->getContent(),0,300)
|
||||
.'…<br><a href="'.$event->getLink()
|
||||
.'">Lire la suite de l\'article</a>'
|
||||
);
|
||||
if(trim($event->getContent())=='')
|
||||
$event->setContent($event->getDescription());
|
||||
|
||||
$event->setCategory($item->get_category());
|
||||
$event->save();
|
||||
$nbEvents++;
|
||||
}
|
||||
|
||||
$listid = "";
|
||||
foreach($events as $item){
|
||||
$listid.=','.$item;
|
||||
}
|
||||
$query='UPDATE `'.MYSQL_PREFIX.'event` SET syncId='.$syncId.' WHERE id in (0'.$listid.');';
|
||||
$myQuery = $this->customQuery($query);
|
||||
|
||||
$this->lastupdate = $_SERVER['REQUEST_TIME'];
|
||||
$this->save();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function removeOldEvents($maxEvent, $currentSyncId){
|
||||
if ($maxEvent<=0) return;
|
||||
$eventManager = new Event();
|
||||
$nbLines = $eventManager->rowCount(array(
|
||||
'feed'=>$this->id,
|
||||
'unread'=>0,
|
||||
'favorite'=>0,
|
||||
));
|
||||
$limit = $nbLines - $maxEvent;
|
||||
if ($limit<=0) return;
|
||||
$tableEvent = '`'.MYSQL_PREFIX."event`";
|
||||
$query = "
|
||||
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);
|
||||
}
|
||||
|
||||
function setId($id){
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function getDescription(){
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
function setDescription($description){
|
||||
$this->description = $description;
|
||||
}
|
||||
function getWebSite(){
|
||||
return $this->website;
|
||||
}
|
||||
|
||||
function setWebSite($website){
|
||||
$this->website = $website;
|
||||
}
|
||||
|
||||
function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getUrl(){
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
function setUrl($url){
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
function getName(){
|
||||
return (trim($this->name)!='' ? $this->name:$this->url);
|
||||
}
|
||||
|
||||
function setName($name){
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
|
||||
function getEvents($start=0,$limit=10000,$order,$columns='*'){
|
||||
$eventManager = new Event();
|
||||
$events = $eventManager->loadAllOnlyColumn($columns,array('feed'=>$this->getId()),$order,$start.','.$limit);
|
||||
return $events;
|
||||
}
|
||||
|
||||
function countUnreadEvents(){
|
||||
$unreads = array();
|
||||
$results = Feed::customQuery("SELECT COUNT(".MYSQL_PREFIX."event.id), ".MYSQL_PREFIX."event.feed FROM ".MYSQL_PREFIX."event WHERE ".MYSQL_PREFIX."event.unread = 1 GROUP BY ".MYSQL_PREFIX."event.feed") ;
|
||||
if($results!=false){
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$unreads[$item[1]] = $item[0];
|
||||
}
|
||||
}
|
||||
return $unreads;
|
||||
}
|
||||
|
||||
function getFeedsPerFolder(){
|
||||
$feedsFolderMap = array();
|
||||
$feedsIdMap = array();
|
||||
|
||||
$results = Feed::customQuery("SELECT ".MYSQL_PREFIX."feed.name AS name, ".MYSQL_PREFIX."feed.id AS id, ".MYSQL_PREFIX."feed.url AS url, ".MYSQL_PREFIX."folder.id AS folder FROM ".MYSQL_PREFIX."feed INNER JOIN ".MYSQL_PREFIX."folder ON ( ".MYSQL_PREFIX."feed.folder = ".MYSQL_PREFIX."folder.id ) ORDER BY ".MYSQL_PREFIX."feed.name ;");
|
||||
if($results!=false){
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$name = $item['name'];
|
||||
$feedsIdMap[$item['id']]['name'] = $name;
|
||||
|
||||
|
||||
$feedsFolderMap[$item['folder']][$item['id']]['id'] = $item['id'];
|
||||
$feedsFolderMap[$item['folder']][$item['id']]['name'] = $name;
|
||||
$feedsFolderMap[$item['folder']][$item['id']]['url'] = $item['url'];
|
||||
|
||||
}
|
||||
}
|
||||
$feeds['folderMap'] = $feedsFolderMap;
|
||||
$feeds['idMap'] = $feedsIdMap;
|
||||
return $feeds;
|
||||
}
|
||||
|
||||
function getFolder(){
|
||||
return $this->folder;
|
||||
}
|
||||
|
||||
function setFolder($folder){
|
||||
$this->folder = $folder;
|
||||
}
|
||||
|
||||
function getLastupdate(){
|
||||
return $this->lastUpdate;
|
||||
}
|
||||
|
||||
function setLastupdate($lastupdate){
|
||||
$this->lastupdate = $lastupdate;
|
||||
}
|
||||
|
||||
function getIsverbose(){
|
||||
return $this->isverbose;
|
||||
}
|
||||
|
||||
function setIsverbose($isverbose){
|
||||
$this->isverbose = $isverbose;
|
||||
}
|
||||
|
||||
/** @returns vrai si l'url n'est pas déjà connue .*/
|
||||
function notRegistered() {
|
||||
return $this->rowCount(array('url' => $this->url)) == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
99
sources/Folder.class.php
Executable file
99
sources/Folder.class.php
Executable file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: Folder
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de gestion des dossiers/catégories contenant les flux
|
||||
*/
|
||||
|
||||
class Folder extends MysqlEntity{
|
||||
|
||||
protected $id,$name,$parent,$isopen;
|
||||
protected $TABLE_NAME = 'folder';
|
||||
protected $CLASS_NAME = 'Folder';
|
||||
protected $object_fields =
|
||||
array(
|
||||
'id'=>'key',
|
||||
'name'=>'string',
|
||||
'parent'=>'integer',
|
||||
'isopen'=>'integer'
|
||||
);
|
||||
|
||||
function unreadCount(){
|
||||
$results = $this->customQuery('SELECT COUNT('.MYSQL_PREFIX.'event.id) FROM '.MYSQL_PREFIX.'event INNER JOIN '.MYSQL_PREFIX.'feed ON ('.MYSQL_PREFIX.'event.feed = '.MYSQL_PREFIX.'feed.id) WHERE '.MYSQL_PREFIX.'event.unread=1 AND '.MYSQL_PREFIX.'feed.folder = '.$this->getId());
|
||||
$number = mysql_fetch_array($results);
|
||||
return $number[0];
|
||||
}
|
||||
|
||||
|
||||
function getEvents($start=0,$limit=10000,$order,$columns='*'){
|
||||
$eventManager = new Event();
|
||||
$objects = array();
|
||||
$results = $this->customQuery('SELECT '.$columns.' FROM '.MYSQL_PREFIX.'event INNER JOIN '.MYSQL_PREFIX.'feed ON ('.MYSQL_PREFIX.'event.feed = '.MYSQL_PREFIX.'feed.id) WHERE '.MYSQL_PREFIX.'event.unread=1 AND '.MYSQL_PREFIX.'feed.folder = '.$this->getId().' ORDER BY '.$order.' LIMIT '.$start.','.$limit);
|
||||
if($results!=false){
|
||||
while($item = mysql_fetch_array($results)){
|
||||
$object = new Event();
|
||||
foreach($object->getObject_fields() as $field=>$type){
|
||||
$setter = 'set'.ucFirst($field);
|
||||
if(isset($item[$field])) $object->$setter($item[$field]);
|
||||
}
|
||||
$objects[] = $object;
|
||||
unset($object);
|
||||
}
|
||||
}
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
function __construct(){
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function setId($id){
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function getFeeds(){
|
||||
$feedManager = new Feed();
|
||||
return $feedManager->loadAll(array('folder'=>$this->getId()),'name');
|
||||
}
|
||||
|
||||
function getFolders(){
|
||||
$folderManager = new Folder();
|
||||
return $folderManager->loadAll(array('parent'=>$this->getId()));
|
||||
}
|
||||
|
||||
|
||||
function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name){
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function getParent(){
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
function setParent($parent){
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
function getIsopen(){
|
||||
return $this->isopen;
|
||||
}
|
||||
|
||||
function setIsopen($isopen){
|
||||
$this->isopen = $isopen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
371
sources/Functions.class.php
Executable file
371
sources/Functions.class.php
Executable file
|
@ -0,0 +1,371 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: constant
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de stockage des fonctions utiles (toutes disponibles en static)
|
||||
*/
|
||||
|
||||
class Functions
|
||||
{
|
||||
private $id;
|
||||
public $debug=0;
|
||||
|
||||
/**
|
||||
* Securise la variable utilisateur entrée en parametre
|
||||
* @author Valentin
|
||||
* @param<String> variable a sécuriser
|
||||
* @param<Integer> niveau de securisation
|
||||
* @return<String> variable securisée
|
||||
*/
|
||||
|
||||
public static function secure($var,$level = 1){
|
||||
$var = htmlspecialchars($var, ENT_QUOTES, "UTF-8");
|
||||
if($level<1)$var = mysql_real_escape_string($var);
|
||||
if($level<2)$var = addslashes($var);
|
||||
return $var;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return l'environnement/serveur sur lequel on se situe, permet de changer les
|
||||
* connexions bdd en fonction de la dev, la préprod ou la prod
|
||||
*/
|
||||
public static function whereImI(){
|
||||
|
||||
$maps = array (
|
||||
'LOCAL'=>array('localhost','127.0.0.1','0.0.0.1','::0.0.0.0'),
|
||||
'LAN'=>array('192.168.10.','valentin'),
|
||||
'PWAN'=>array('test.sys1.fr'),
|
||||
'WAN'=>array('www.sys1.fr'),
|
||||
);
|
||||
|
||||
|
||||
$return = 'UNKNOWN';
|
||||
foreach($maps as $map=>$values){
|
||||
|
||||
foreach($values as $ip){
|
||||
$pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
|
||||
if ($pos!==false){
|
||||
$return = $map;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function isLocal($perimeter='LOCAL'){
|
||||
$return = false;
|
||||
|
||||
$localTab = array('localhost','127.0.0.1','0.0.0.1','::0.0.0.0');
|
||||
$lanTab = array('192.168.10.','valentin');
|
||||
|
||||
switch($perimeter){
|
||||
case 'LOCAL':
|
||||
foreach($localTab as $ip){
|
||||
$pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
|
||||
if ($pos!==false){
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'LAN':
|
||||
foreach($lanTab as $ip){
|
||||
$pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
|
||||
if ($pos!==false){
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ALL':
|
||||
foreach($localTab as $ip){
|
||||
$pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
|
||||
if ($pos!==false){
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
foreach($lanTab as $ip){
|
||||
$pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
|
||||
if ($pos!==false){
|
||||
$return = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convertis la chaine passée en timestamp quel que soit sont format
|
||||
* (prend en charge les formats type dd-mm-yyy , dd/mm/yyy, yyyy/mm/ddd...)
|
||||
*/
|
||||
public static function toTime($string){
|
||||
$string = str_replace('/','-',$string);
|
||||
$string = str_replace('\\','-',$string);
|
||||
|
||||
$string = str_replace('Janvier','Jan',$string);
|
||||
$string = str_replace('Fevrier','Feb',$string);
|
||||
$string = str_replace('Mars','Mar',$string);
|
||||
$string = str_replace('Avril','Apr',$string);
|
||||
$string = str_replace('Mai','May',$string);
|
||||
$string = str_replace('Juin','Jun',$string);
|
||||
$string = str_replace('Juillet','Jul',$string);
|
||||
$string = str_replace('Aout','Aug',$string);
|
||||
$string = str_replace('Septembre','Sept',$string);
|
||||
$string = str_replace('Octobre','Oct',$string);
|
||||
$string = str_replace('Novembre','Nov',$string);
|
||||
$string = str_replace('Decembre','Dec',$string);
|
||||
return strtotime($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recupere l'ip de l'internaute courant
|
||||
* @author Valentin
|
||||
* @return<String> ip de l'utilisateur
|
||||
*/
|
||||
|
||||
public static function getIP(){
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
|
||||
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];}
|
||||
elseif(isset($_SERVER['HTTP_CLIENT_IP'])){
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];}
|
||||
else{ $ip = $_SERVER['REMOTE_ADDR'];}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne une version tronquée au bout de $limit caracteres de la chaine fournie
|
||||
* @author Valentin
|
||||
* @param<String> message a tronquer
|
||||
* @param<Integer> limite de caracteres
|
||||
* @return<String> chaine tronquée
|
||||
*/
|
||||
public static function truncate($msg,$limit){
|
||||
if(mb_strlen($msg)>$limit){
|
||||
$fin='…' ;
|
||||
$nb=$limit-mb_strlen($fin) ;
|
||||
}else{
|
||||
$nb=mb_strlen($msg);
|
||||
$fin='';
|
||||
}
|
||||
return mb_substr($msg, 0, $nb).$fin;
|
||||
}
|
||||
|
||||
|
||||
function getExtension($fileName){
|
||||
$dot = explode('.',$fileName);
|
||||
return $dot[sizeof($dot)-1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Definis si la chaine fournie est existante dans la reference fournie ou non
|
||||
* @param unknown_type $string
|
||||
* @param unknown_type $reference
|
||||
* @return false si aucune occurence du string, true dans le cas contraire
|
||||
*/
|
||||
public static function contain($string,$reference){
|
||||
$return = true;
|
||||
$pos = strpos($reference,$string);
|
||||
if ($pos === false) {
|
||||
$return = false;
|
||||
}
|
||||
return strtolower($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Définis si la chaine passée en parametre est une url ou non
|
||||
*/
|
||||
public static function isUrl($url){
|
||||
$return =false;
|
||||
if (preg_match('/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i', $url)) {
|
||||
$return =true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définis si la chaine passée en parametre est une couleur héxadécimale ou non
|
||||
*/
|
||||
public static function isColor($color){
|
||||
$return =false;
|
||||
if (preg_match('/^#(?:(?:[a-fd]{3}){1,2})$/i', $color)) {
|
||||
$return =true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définis si la chaine passée en parametre est un mail ou non
|
||||
*/
|
||||
public static function isMail($mail){
|
||||
$return =false;
|
||||
if (filter_var($mail, FILTER_VALIDATE_EMAIL)) {
|
||||
$return =true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Définis si la chaine passée en parametre est une IP ou non
|
||||
*/
|
||||
public static function isIp($ip){
|
||||
$return =false;
|
||||
if (preg_match('^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$',$ip)) {
|
||||
$return =true;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function sourceName($string){
|
||||
$name = strtolower($string);
|
||||
$name = str_replace(' ','-',$name);
|
||||
$name = str_replace(''','-',$name);
|
||||
$name = str_replace('\'','-',$name);
|
||||
$name = str_replace(',','-',$name);
|
||||
$name = str_replace(':','-',$name);
|
||||
$name = str_replace('à','a',$name);
|
||||
$name = trim($name);
|
||||
$name = html_entity_decode($name,null,'UTF-8');
|
||||
return $name;
|
||||
}
|
||||
|
||||
public static function makeCookie($name, $value, $expire='') {
|
||||
if($expire == '') {
|
||||
setcookie($name, $value, mktime(0,0,0, date("d"),
|
||||
date("m"), (date("Y")+1)),'/');
|
||||
}else {
|
||||
setcookie($name, '', mktime(0,0,0, date("d"),
|
||||
date("m"), (date("Y")-1)),'/');
|
||||
}
|
||||
}
|
||||
|
||||
public static function destroyCookie($name){
|
||||
Fonction::makeCookie($name,'',time()-3600);
|
||||
unset($_COOKIE[$name]);
|
||||
}
|
||||
|
||||
public static function wordwrap($str, $width = 75, $break = "\n", $cut = false)
|
||||
{
|
||||
$str = html_entity_decode($str);
|
||||
$str = htmlentities (wordwrap($str,$width,$break,$cut));
|
||||
$str = str_replace('<br/>','<br/>',$str);
|
||||
$str = str_replace('&','&',$str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function createFile($filePath,$content){
|
||||
$fichier = fopen($filePath,"w+");
|
||||
$fwriteResult = fwrite($fichier,$content);
|
||||
fclose($fichier);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function convertFileSize($bytes)
|
||||
{
|
||||
if($bytes<1024){
|
||||
return round(($bytes / 1024), 2).' o';
|
||||
}elseif(1024<$bytes && $bytes<1048576){
|
||||
return round(($bytes / 1024), 2).' ko';
|
||||
}elseif(1048576<$bytes && $bytes<1073741824){
|
||||
return round(($bytes / 1024)/1024, 2).' Mo';
|
||||
}elseif(1073741824<$bytes){
|
||||
return round(($bytes / 1024)/1024/1024, 2).' Go';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function hexaValue($str){
|
||||
$code = dechex(crc32($str));
|
||||
$code = substr($code, 0, 6);
|
||||
return $code;
|
||||
}
|
||||
|
||||
public static function scanRecursiveDir($dir){
|
||||
$files = scandir($dir);
|
||||
$allFiles = array();
|
||||
foreach($files as $file){
|
||||
if($file!='.' && $file!='..'){
|
||||
if(is_dir($dir.$file)){
|
||||
$allFiles = array_merge($allFiles,Fonction::scanRecursiveDir($dir.$file));
|
||||
}else{
|
||||
$allFiles[]=str_replace('//','/',$dir.'/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $allFiles;
|
||||
}
|
||||
|
||||
/** Permet la sortie directe de texte à l'écran, sans tampon.
|
||||
Source : http://php.net/manual/fr/function.flush.php
|
||||
*/
|
||||
public static function triggerDirectOutput() {
|
||||
// La ligne de commande n'en a pas besoin.
|
||||
if ('cli'==php_sapi_name()) return;
|
||||
if (function_exists('apache_setenv')) {
|
||||
/* Selon l'hébergeur la fonction peut être désactivée. Alors Php
|
||||
arrête le programme avec l'erreur :
|
||||
"PHP Fatal error: Call to undefined function apache_setenv()".
|
||||
*/
|
||||
@apache_setenv('no-gzip', 1);
|
||||
}
|
||||
@ini_set('zlib.output_compression', 0);
|
||||
@ini_set('implicit_flush', 1);
|
||||
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
|
||||
ob_implicit_flush(1);
|
||||
}
|
||||
|
||||
public static function relativePath($from, $to, $ps = '/') {
|
||||
$arFrom = explode($ps, rtrim($from, $ps));
|
||||
$arTo = explode($ps, rtrim($to, $ps));
|
||||
while(count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0])) {
|
||||
array_shift($arFrom);
|
||||
array_shift($arTo);
|
||||
}
|
||||
return str_pad("", count($arFrom) * 3, '..'.$ps).implode($ps, $arTo);
|
||||
}
|
||||
|
||||
|
||||
// Nettoyage de l'url avant la mise en base
|
||||
public static function clean_url( $url ) {
|
||||
$url = str_replace('&', '&', $url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Méthode de test de connexion.
|
||||
* @return true si ok
|
||||
* @param server
|
||||
* @param login
|
||||
* @param pass
|
||||
* @param db facultatif, si précisé alors tente de la séléctionner
|
||||
*/
|
||||
public static function testDb($server, $login, $pass, $db=null) {
|
||||
/* Méthode hors des classes dédiées aux BDD afin de supporter le moins
|
||||
de dépendances possibles. En particulier, pas besoin que le fichier
|
||||
de configuration existe. */
|
||||
$link = mysql_connect($server, $login, $pass);
|
||||
if (false===$link) return false;
|
||||
if (!is_null($db) && false===mysql_select_db($db, $link)) return false;
|
||||
mysql_close($link);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return les langues acceptées par le navigateur
|
||||
*/
|
||||
public static function getBrowserLanguages() {
|
||||
/* http://www.w3.org/International/questions/qa-lang-priorities.en.php
|
||||
* ex: da, en-gb;q=0.8,en;q=0.7 --> array('da','en');
|
||||
*/
|
||||
$languages = array();
|
||||
$chunks = preg_split('/,\s*/', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
||||
foreach($chunks as $chunk) $languages []= substr($chunk, 0, 2);
|
||||
return array_unique($languages);
|
||||
}
|
||||
}
|
||||
?>
|
199
sources/MysqlConnector.class.php
Executable file
199
sources/MysqlConnector.class.php
Executable file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: mysql
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@date de création:
|
||||
@description: Classe de gestion des connexions Mysql
|
||||
*/
|
||||
|
||||
class MysqlConnector
|
||||
{
|
||||
private $id;
|
||||
private $hote;
|
||||
private $login;
|
||||
private $mdp;
|
||||
private $bdd;
|
||||
private $port;
|
||||
public $debug=0;
|
||||
private $connection = null;
|
||||
public static $instance = null;
|
||||
|
||||
private function __construct(){
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Methode de recuperation unique de l'instance
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Singleton
|
||||
* @param <Aucun>
|
||||
* @return <mysql> $instance
|
||||
*/
|
||||
|
||||
public static function getInstance(){
|
||||
|
||||
if (MysqlConnector::$instance === null) {
|
||||
MysqlConnector::$instance = new self();
|
||||
}
|
||||
return MysqlConnector::$instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function connect(){
|
||||
$this->connection = mysql_connect(MYSQL_HOST,MYSQL_LOGIN,MYSQL_MDP);
|
||||
mysql_query('SET NAMES utf8');
|
||||
mysql_select_db(MYSQL_BDD,$this->connection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function __toString(){
|
||||
$retour = "";
|
||||
$retour .= "instance de la classe MysqlConnector : <br/>";
|
||||
$retour .= '$hote : '.$this->hote.'<br/>';
|
||||
$retour .= '$login : '.$this->login.'<br/>';
|
||||
$retour .= '$mdp : '.$this->mdp.'<br/>';
|
||||
$retour .= '$bdd : '.$this->bdd.'<br/>';
|
||||
$retour .= '$port : '.$this->port.'<br/>';
|
||||
return $retour;
|
||||
}
|
||||
|
||||
private function __clone(){
|
||||
//Action lors du clonage de l'objet
|
||||
}
|
||||
|
||||
// ACCESSEURS
|
||||
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId($id){
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut hote de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> hote
|
||||
*/
|
||||
|
||||
public function getHote(){
|
||||
return $this->hote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut hote de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <Attribute> $hote
|
||||
* @return Aucun retour
|
||||
*/
|
||||
|
||||
public function setHote($hote){
|
||||
$this->hote = $hote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut login de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> login
|
||||
*/
|
||||
|
||||
public function getLogin(){
|
||||
return $this->login;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut login de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <Attribute> $login
|
||||
* @return Aucun retour
|
||||
*/
|
||||
|
||||
public function setLogin($login){
|
||||
$this->login = $login;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut mdp de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> mdp
|
||||
*/
|
||||
|
||||
public function getMdp(){
|
||||
return $this->mdp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut mdp de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <Attribute> $mdp
|
||||
* @return Aucun retour
|
||||
*/
|
||||
|
||||
public function setMdp($mdp){
|
||||
$this->mdp = $mdp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut bdd de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> bdd
|
||||
*/
|
||||
|
||||
public function getBdd(){
|
||||
return $this->bdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut bdd de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <Attribute> $bdd
|
||||
* @return Aucun retour
|
||||
*/
|
||||
|
||||
public function setBdd($bdd){
|
||||
$this->bdd = $bdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut port de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> port
|
||||
*/
|
||||
|
||||
public function getPort(){
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut port de la classe Mysql
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <Attribute> $port
|
||||
* @return Aucun retour
|
||||
*/
|
||||
|
||||
public function setPort($port){
|
||||
$this->port = $port;
|
||||
}
|
||||
}
|
||||
?>
|
446
sources/MysqlEntity.class.php
Executable file
446
sources/MysqlEntity.class.php
Executable file
|
@ -0,0 +1,446 @@
|
|||
<?php
|
||||
require_once('constant.php');
|
||||
require_once('MysqlConnector.class.php');
|
||||
/*
|
||||
@nom: MysqlEntity
|
||||
@auteur: Valentin CARRUESCO (valentincarruesco@yahoo.fr)
|
||||
@date de création: 16/04/2012 02:34:15
|
||||
@description: Classe parent de tous les modèles (classe entitées) liées a la base de donnée,
|
||||
cette classe est configuré pour agir avec une base MySQL, mais il est possible de redefinir ses codes SQL pour l'adapter à un autre SGBD sans affecter
|
||||
le reste du code du projet.
|
||||
|
||||
*/
|
||||
|
||||
class MysqlEntity
|
||||
{
|
||||
|
||||
private $debug = false;
|
||||
private $debugAllQuery = false;
|
||||
|
||||
|
||||
function sgbdType($type){
|
||||
$return = false;
|
||||
switch($type){
|
||||
case 'string':
|
||||
case 'timestamp':
|
||||
$return = 'VARCHAR(225) CHARACTER SET utf8 COLLATE utf8_general_ci';
|
||||
break;
|
||||
case 'longstring':
|
||||
$return = 'TEXT CHARACTER SET utf8 COLLATE utf8_general_ci';
|
||||
break;
|
||||
case 'key':
|
||||
$return = 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY';
|
||||
break;
|
||||
case 'object':
|
||||
case 'integer':
|
||||
$return = 'INT(11)';
|
||||
break;
|
||||
case 'boolean':
|
||||
$return = 'INT(1)';
|
||||
break;
|
||||
default;
|
||||
$return = 'TEXT CHARACTER SET utf8 COLLATE utf8_general_ci';
|
||||
break;
|
||||
}
|
||||
return $return ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protège une variable pour MySQL
|
||||
*/
|
||||
protected function secure($value, $field){
|
||||
$type = false;
|
||||
|
||||
// ce champ n'existe pas : on le considère comme une chaîne de caractères
|
||||
if (isset($this->object_fields[$field]))
|
||||
$type = $this->object_fields[$field];
|
||||
|
||||
$return = false;
|
||||
switch($type){
|
||||
case 'key':
|
||||
case 'object':
|
||||
case 'integer':
|
||||
case 'boolean':
|
||||
$return = intval($value);
|
||||
break;
|
||||
case 'string':
|
||||
case 'timestamp':
|
||||
case 'longstring':
|
||||
default;
|
||||
$return = mysql_real_escape_string((string)$value);
|
||||
break;
|
||||
}
|
||||
return $return ;
|
||||
}
|
||||
|
||||
public function __construct(){
|
||||
MysqlConnector::getInstance();
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
|
||||
}
|
||||
|
||||
// GESTION SQL
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$query = 'DROP TABLE IF EXISTS '.MYSQL_PREFIX.$this->TABLE_NAME.';';
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$myQuery = $this->customQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$query = 'TRUNCATE TABLE '.MYSQL_PREFIX.$this->TABLE_NAME.';';
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$myQuery = $this->customQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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){
|
||||
$query = 'CREATE TABLE IF NOT EXISTS `'.MYSQL_PREFIX.$this->TABLE_NAME.'` (';
|
||||
|
||||
$i=false;
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .='`'.$field.'` '. $this->sgbdType($type).' NOT NULL';
|
||||
}
|
||||
if (isset($this->object_fields_index)){
|
||||
foreach($this->object_fields_index as $field=>$type){
|
||||
$query .= ',KEY `index'.$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>'.mysql_error();
|
||||
$myQuery = $this->customQuery($query);
|
||||
}
|
||||
|
||||
public function massiveInsert($events){
|
||||
if (empty($events)) return;
|
||||
$query = 'INSERT INTO `'.MYSQL_PREFIX.$this->TABLE_NAME.'`(';
|
||||
$i=false;
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if($type!='key'){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .='`'.$field.'`';
|
||||
}
|
||||
}
|
||||
$query .=') select';
|
||||
$u = false;
|
||||
|
||||
foreach($events as $event){
|
||||
|
||||
if($u){$query .=' union select ';}else{$u=true;}
|
||||
|
||||
$i=false;
|
||||
foreach($event->object_fields as $field=>$type){
|
||||
if($type!='key'){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .='"'.$this->secure($event->$field, $field).'"';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
$query .=';';
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
|
||||
$this->customQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode d'insertion ou de modifications d'elements de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @param Aucun
|
||||
* @return Aucun retour
|
||||
*/
|
||||
public function save(){
|
||||
if(isset($this->id)){
|
||||
$query = 'UPDATE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`';
|
||||
$query .= ' SET ';
|
||||
|
||||
$i=false;
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$id = $this->$field;
|
||||
$query .= '`'.$field.'`="'.$this->secure($id, $field).'"';
|
||||
}
|
||||
|
||||
$query .= ' WHERE `id`="'.$this->id.'";';
|
||||
}else{
|
||||
$query = 'INSERT INTO `'.MYSQL_PREFIX.$this->TABLE_NAME.'`(';
|
||||
$i=false;
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .='`'.$field.'`';
|
||||
}
|
||||
$query .=')VALUES(';
|
||||
$i=false;
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .='"'.$this->secure($this->$field, $field).'"';
|
||||
}
|
||||
|
||||
$query .=');';
|
||||
}
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$this->customQuery($query);
|
||||
$this->id = (!isset($this->id)?mysql_insert_id():$this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de modification d'éléments de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @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){
|
||||
$query = 'UPDATE `'.MYSQL_PREFIX.$this->TABLE_NAME.'` SET ';
|
||||
$i=false;
|
||||
foreach ($columns as $column=>$value){
|
||||
if($i){$query .=',';}else{$i=true;}
|
||||
$query .= '`'.$column.'`="'.$this->secure($value, $column).'" ';
|
||||
}
|
||||
$query .=' WHERE ';
|
||||
|
||||
$i = false;
|
||||
foreach ($columns2 as $column=>$value){
|
||||
if($i){$query .='AND ';}else{$i=true;}
|
||||
$query .= '`'.$column.'`'.$operation.'"'.$this->secure($value, $column).'" ';
|
||||
}
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$this->customQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de selection de tous les elements de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @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);
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de selection multiple d'elements de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @param <Array> $colonnes (WHERE)
|
||||
* @param <Array> $valeurs (WHERE)
|
||||
* @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='*'){
|
||||
$objects = array();
|
||||
$whereClause = '';
|
||||
|
||||
if($columns!=null && sizeof($columns)!=0){
|
||||
$whereClause .= ' WHERE ';
|
||||
$i = false;
|
||||
foreach($columns as $column=>$value){
|
||||
if($i){$whereClause .=' AND ';}else{$i=true;}
|
||||
$whereClause .= '`'.$column.'`'.$operation.'"'.$this->secure($value, $column).'"';
|
||||
}
|
||||
}
|
||||
$query = 'SELECT '.$selColumn.' FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` '.$whereClause.' ';
|
||||
if($order!=null) $query .='ORDER BY '.$order.' ';
|
||||
if($limit!=null) $query .='LIMIT '.$limit.' ';
|
||||
$query .=';';
|
||||
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$execQuery = $this->customQuery($query);
|
||||
while($queryReturn = mysql_fetch_assoc($execQuery)){
|
||||
|
||||
$object = new $this->CLASS_NAME();
|
||||
foreach($this->object_fields as $field=>$type){
|
||||
if(isset($queryReturn[$field])) $object->$field = $queryReturn[$field];
|
||||
}
|
||||
$objects[] = $object;
|
||||
unset($object);
|
||||
}
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public function loadAllOnlyColumn($selColumn,$columns,$order=null,$limit=null,$operation="=",$debug=false){
|
||||
$objects = $this->loadAll($columns,$order,$limit,$operation,$debug,$selColumn);
|
||||
if(count($objects)==0)$objects = array();
|
||||
return $objects;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Méthode de selection unique d'élements de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @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);
|
||||
if(!isset($objects[0]))$objects[0] = false;
|
||||
return $objects[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de selection unique d'élements de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$whereClause ='';
|
||||
if($columns!=null){
|
||||
$whereClause = ' WHERE ';
|
||||
$i=false;
|
||||
foreach($columns as $column=>$value){
|
||||
if($i){$whereClause .=' AND ';}else{$i=true;}
|
||||
$whereClause .= '`'.$column.'`="'.$this->secure($value, $column).'"';
|
||||
}
|
||||
}
|
||||
$query = 'SELECT COUNT(1) FROM '.MYSQL_PREFIX.$this->TABLE_NAME.$whereClause;
|
||||
if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.mysql_error();
|
||||
$myQuery = $this->customQuery($query);
|
||||
$number = mysql_fetch_array($myQuery);
|
||||
return $number[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de suppression d'éléments de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category manipulation SQL
|
||||
* @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){
|
||||
$whereClause = '';
|
||||
|
||||
$i=false;
|
||||
foreach($columns as $column=>$value){
|
||||
if($i){$whereClause .=' AND ';}else{$i=true;}
|
||||
$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>'.mysql_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>'.mysql_error();
|
||||
$result = mysql_query($request);
|
||||
if (false===$result) {
|
||||
throw new Exception(mysql_error());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
public function customQuery($request){
|
||||
if($this->debugAllQuery)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$request.'<br>'.mysql_error();
|
||||
$result = mysql_query($request);
|
||||
if (false===$result) {
|
||||
throw new Exception(mysql_error());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
// ACCESSEURS
|
||||
/**
|
||||
* Méthode de récuperation de l'attribut debug de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param Aucun
|
||||
* @return <Attribute> debug
|
||||
*/
|
||||
|
||||
public function getDebug(){
|
||||
return $this->debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode de définition de l'attribut debug de l'entité
|
||||
* @author Valentin CARRUESCO
|
||||
* @category Accesseur
|
||||
* @param <boolean> $debug
|
||||
*/
|
||||
|
||||
public function setDebug($debug){
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
public function getObject_fields(){
|
||||
return $this->object_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <boolean> VRAI si la table existe, FAUX sinon
|
||||
*/
|
||||
|
||||
public function tableExists() {
|
||||
$table = MYSQL_PREFIX.$this->TABLE_NAME;
|
||||
$result = $this->customQuery("SHOW TABLES LIKE '$table'");
|
||||
$assoc = mysql_fetch_assoc($result);
|
||||
return false===$assoc ? false : true;
|
||||
}
|
||||
}
|
||||
?>
|
168
sources/Opml.class.php
Executable file
168
sources/Opml.class.php
Executable file
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: Opml
|
||||
@auteur: Sbgodin (christophe.henry@sbgodin.fr)
|
||||
@description: Classe de gestion de l'import/export au format OPML
|
||||
*/
|
||||
|
||||
require_once("common.php");
|
||||
|
||||
class Opml {
|
||||
|
||||
// liens déjà connus, déjà abonnés, au moment de l'importation
|
||||
public $alreadyKnowns = array();
|
||||
|
||||
/**
|
||||
* Met à jour les données des flux.
|
||||
*/
|
||||
protected function update() {
|
||||
global $feedManager, $folderManager;
|
||||
$this->feeds = $feedManager->populate('name');
|
||||
$this->folders = $folderManager->loadAll(array('parent'=>-1),'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit les caractères qui interfèrent avec le XML
|
||||
*/
|
||||
protected function escapeXml($string) {
|
||||
/** Les entités sont utiles pour deux raisons : encodage et
|
||||
échappement. L'encodage n'est pas un problème, l'application travaille
|
||||
nativement avec Unicode. L'échappement dans XML impose d'échapper les
|
||||
esperluettes (&) et les guillemets. Ces derniers sont utilisés comme
|
||||
séparateur de chaine. Les simples cotes restent intactes.
|
||||
* On retire toutes les entités de sorte à obtenir une chaîne totalement
|
||||
en UTF-8. Elle peut alors contenir des & et des ", nocifs pour XML.
|
||||
* On échappe les caractères & et " de sorte à ce que le contenu dans le
|
||||
XML soit correct. On suppose qu'à la lecture, cet échappement est
|
||||
annulé.
|
||||
* Accessoirement, on remplace les espaces non signifiants par une seule
|
||||
espace. C'est le cas des retours chariots physiques, non
|
||||
interprétables.
|
||||
*/
|
||||
// Retire toutes les entités, & é etc.
|
||||
$string = html_entity_decode($string, ENT_COMPAT, 'UTF-8' );
|
||||
// Remet les entités HTML comme & mais ne touche pas aux accents.
|
||||
$string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
|
||||
// Supprime les blancs non signifiants comme les sauts de ligne.
|
||||
$string = preg_replace('/\s+/', ' ', $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exporte récursivement les flux.
|
||||
*/
|
||||
protected function exportRecursive($folders, $identLevel=0) {
|
||||
$_ = ' ';
|
||||
$__ = ''; for($i=0;$i<$identLevel;$i++) $__.=$_;
|
||||
$xmlStream = '';
|
||||
foreach($folders as $folder) {
|
||||
// Pas utilisé, vu qu'il n'y a qu'un seul niveau de dossiers.
|
||||
$xmlStream .= $this->exportRecursive(
|
||||
$folder->getFolders(), $identLevel+1
|
||||
);
|
||||
$feeds = $folder->getFeeds();
|
||||
if (empty($feeds)) continue;
|
||||
$text = $this->escapeXml($folder->getName());
|
||||
$xmlStream .= "{$__}<outline text=\"$text\">\n";
|
||||
foreach($feeds as $feed){
|
||||
$url = $this->escapeXml($feed->getUrl());
|
||||
$website = $this->escapeXml($feed->getWebsite());
|
||||
$title = $this->escapeXml($feed->getName());
|
||||
$text = $title;
|
||||
$description = $this->escapeXml($feed->getDescription());
|
||||
$xmlStream .= "{$__}{$_}<outline "
|
||||
."type=\"rss\" "
|
||||
."xmlUrl=\"$url\" "
|
||||
."htmlUrl=\"$website\" "
|
||||
."text=\"$text\" "
|
||||
."title=\"$title\" "
|
||||
."description=\"$description\""
|
||||
."/>\n";
|
||||
}
|
||||
$xmlStream .= "{$__}</outline>\n";
|
||||
}
|
||||
return $xmlStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exporte l'ensemble des flux et sort les en-têtes.
|
||||
*/
|
||||
function export() {
|
||||
$this->update();
|
||||
$date = date('D, d M Y H:i:s O');
|
||||
$xmlStream = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
||||
<opml version=\"2.0\">
|
||||
<head>
|
||||
<title>Leed export</title>
|
||||
<ownerName>Leed</ownerName>
|
||||
<ownerEmail>idleman@idleman.fr</ownerEmail>
|
||||
<dateCreated>$date</dateCreated>
|
||||
</head>
|
||||
<body>\n";
|
||||
$xmlStream .= $this->exportRecursive($this->folders, 2);
|
||||
$xmlStream .= " </body>\n</opml>\n";
|
||||
return $xmlStream;
|
||||
}
|
||||
|
||||
protected function importRec($folder, $folderId=1){
|
||||
$folderManager = new Folder();
|
||||
$feedManager = new Feed();
|
||||
foreach($folder as $item) {
|
||||
// Cela varie selon les implémentations d'OPML.
|
||||
$feedName = $item['text'] ? 'text' : 'title';
|
||||
if (isset($item->outline[0])) { // un dossier
|
||||
$folder = $folderManager->load(array('name'=>$item[$feedName]));
|
||||
$folder = (!$folder?new Folder():$folder);
|
||||
$folder->setName($item[$feedName]);
|
||||
$folder->setParent(($folderId==1?-1:$folderId));
|
||||
$folder->setIsopen(0);
|
||||
if($folder->getId()=='') $folder->save();
|
||||
$this->importRec($item->outline,$folder->getId());
|
||||
} else { // un flux
|
||||
$newFeed = $feedManager->load(array('url'=>$item[0]['xmlUrl']));
|
||||
$newFeed = (!$newFeed?new Feed():$newFeed);
|
||||
if($newFeed->getId()=='') {
|
||||
/* Ne télécharge pas à nouveau le même lien, même s'il est
|
||||
dans un autre dossier. */
|
||||
$newFeed->setName($item[0][$feedName]);
|
||||
$newFeed->setUrl($item[0]['xmlUrl']);
|
||||
$newFeed->setDescription($item[0]['description']);
|
||||
$newFeed->setWebsite($item[0]['htmlUrl']);
|
||||
$newFeed->setFolder($folderId);
|
||||
$newFeed->save();
|
||||
// $newFeed->parse();
|
||||
} else {
|
||||
$this->alreadyKnowns[]= (object) array(
|
||||
'description' => $newFeed->getDescription(),
|
||||
'feedName' => $newFeed->getName(),
|
||||
'xmlUrl' => $newFeed->getUrl()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Importe les flux.
|
||||
*/
|
||||
function import() {
|
||||
require_once("SimplePie.class.php");
|
||||
$file = $_FILES['newImport']['tmp_name'];
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
$xml = @simplexml_load_file($file);
|
||||
$errorOutput = array();
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$errorOutput []= "{$error->message} (line {$error->line})";
|
||||
}
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
if (!empty($xml) && empty($errorOutput)) {
|
||||
$this->importRec($xml->body->outline);
|
||||
}
|
||||
return $errorOutput;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
350
sources/Plugin.class.php
Executable file
350
sources/Plugin.class.php
Executable file
|
@ -0,0 +1,350 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: Plugin
|
||||
@auteur: Valentin CARRUESCO (idleman@idleman.fr)
|
||||
@description: Classe de gestion des plugins au travers de l'application
|
||||
*/
|
||||
|
||||
class Plugin{
|
||||
|
||||
const FOLDER = '/plugins';
|
||||
protected $name,$author,$mail,$link,$licence,$path,$description,$version,$state,$type;
|
||||
|
||||
function __construct(){
|
||||
}
|
||||
|
||||
public static function includeAll(){
|
||||
global $i18n, $i18n_js;
|
||||
$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)));
|
||||
// Inclusion du coeur de plugin
|
||||
include $pluginFile;
|
||||
// Gestion des css du plugin en fonction du thème actif
|
||||
$cssTheme = glob(dirname($pluginFile).'/*/'.DEFAULT_THEME.'.css');
|
||||
$cssDefault = glob(dirname($pluginFile).'/*/default.css');
|
||||
if(isset($cssTheme[0])){
|
||||
$GLOBALS['hooks']['css_files'][] = Functions::relativePath(str_replace('\\','/',dirname(__FILE__)),str_replace('\\','/',$cssTheme[0]));
|
||||
}else if(isset($cssDefault[0])){
|
||||
$GLOBALS['hooks']['css_files'][] = Functions::relativePath(str_replace('\\','/',dirname(__FILE__)),str_replace('\\','/',$cssDefault[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
$i18n_js = $i18n->getJson();
|
||||
}
|
||||
|
||||
private static function getStates(){
|
||||
$stateFile = dirname(__FILE__).Plugin::FOLDER.'/plugins.states.json';
|
||||
if(!file_exists($stateFile)) touch($stateFile);
|
||||
return json_decode(file_get_contents($stateFile),true);
|
||||
}
|
||||
private static function setStates($states){
|
||||
$stateFile = dirname(__FILE__).Plugin::FOLDER.'/plugins.states.json';
|
||||
file_put_contents($stateFile,json_encode($states));
|
||||
}
|
||||
public static function pruneStates() {
|
||||
$statesBefore = self::getStates();
|
||||
if(empty($statesBefore))
|
||||
$statesBefore = array();
|
||||
|
||||
$statesAfter = array();
|
||||
$error = false;
|
||||
if (is_array($statesBefore))
|
||||
{
|
||||
foreach($statesBefore as $file=>$state) {
|
||||
if (file_exists($file))
|
||||
$statesAfter[$file] = $state;
|
||||
else
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
if ($error) self::setStates($statesAfter);
|
||||
}
|
||||
|
||||
|
||||
private static function getObject($pluginFile){
|
||||
$plugin = new Plugin();
|
||||
$fileLines = file_get_contents($pluginFile);
|
||||
|
||||
if(preg_match("#@author\s(.+)\s\<#", $fileLines, $match))
|
||||
$plugin->setAuthor(trim($match[1]));
|
||||
|
||||
if(preg_match("#@author\s(.+)\s\<([a-z\@\.A-Z\s\-]+)\>#", $fileLines, $match))
|
||||
$plugin->setMail(strtolower($match[2]));
|
||||
|
||||
if(preg_match("#@name\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setName($match[1]);
|
||||
|
||||
if(preg_match("#@licence\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setLicence($match[1]);
|
||||
|
||||
if(preg_match("#@version\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setVersion($match[1]);
|
||||
|
||||
if(preg_match("#@link\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setLink(trim($match[1]));
|
||||
|
||||
if(preg_match("#@type\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setType(trim($match[1]));
|
||||
|
||||
if(preg_match("#@description\s(.+)[\r\n]#", $fileLines, $match))
|
||||
$plugin->setDescription(trim($match[1]));
|
||||
|
||||
if(Plugin::loadState($pluginFile) || $plugin->getType()=='component'){
|
||||
$plugin->setState(1);
|
||||
}else{
|
||||
$plugin->setState(0);
|
||||
}
|
||||
$plugin->setPath($pluginFile);
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
public static function getAll(){
|
||||
$pluginFiles = Plugin::getFiles();
|
||||
|
||||
$plugins = array();
|
||||
if(is_array($pluginFiles)) {
|
||||
foreach($pluginFiles as $pluginFile) {
|
||||
$plugin = Plugin::getObject($pluginFile);
|
||||
$plugins[]=$plugin;
|
||||
}
|
||||
}
|
||||
usort($plugins, "Plugin::sortPlugin");
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function addHook($hookName, $functionName) {
|
||||
$GLOBALS['hooks'][$hookName][] = $functionName;
|
||||
}
|
||||
|
||||
public static function addCss($css) {
|
||||
$bt = debug_backtrace();
|
||||
$pathInfo = explode('/',dirname($bt[0]['file']));
|
||||
$count = count($pathInfo);
|
||||
$name = $pathInfo[$count-1];
|
||||
$path = '.'.Plugin::FOLDER.'/'.$name.$css;
|
||||
|
||||
$GLOBALS['hooks']['css_files'][] = $path;
|
||||
}
|
||||
|
||||
public static function callCss(){
|
||||
$return='';
|
||||
if(isset($GLOBALS['hooks']['css_files'])) {
|
||||
foreach($GLOBALS['hooks']['css_files'] as $css_file) {
|
||||
$return .='<link rel="stylesheet" href="'.$css_file.'">'."\n";
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function addLink($rel, $link) {
|
||||
$GLOBALS['hooks']['head_link'][] = array("rel"=>$rel, "link"=>$link);
|
||||
}
|
||||
|
||||
public static function callLink(){
|
||||
$return='';
|
||||
if(isset($GLOBALS['hooks']['head_link'])) {
|
||||
foreach($GLOBALS['hooks']['head_link'] as $head_link) {
|
||||
$return .='<link rel="'.$head_link['rel'].'" href="'.$head_link['link'].'" />'."\n";
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function path(){
|
||||
$bt = debug_backtrace();
|
||||
$pathInfo = explode('/',dirname($bt[0]['file']));
|
||||
$count = count($pathInfo);
|
||||
$name = $pathInfo[$count-1];
|
||||
return '.'.Plugin::FOLDER.'/'.$name.'/';
|
||||
}
|
||||
|
||||
public static function addJs($js) {
|
||||
$bt = debug_backtrace();
|
||||
$pathInfo = explode('/',dirname($bt[0]['file']));
|
||||
$count = count($pathInfo);
|
||||
$name = $pathInfo[$count-1];
|
||||
$path = '.'.Plugin::FOLDER.'/'.$name.$js;
|
||||
|
||||
$GLOBALS['hooks']['js_files'][] = $path;
|
||||
}
|
||||
|
||||
public static function callJs(){
|
||||
$return='';
|
||||
if(isset($GLOBALS['hooks']['js_files'])) {
|
||||
foreach($GLOBALS['hooks']['js_files'] as $js_file) {
|
||||
$return .='<script type="text/javascript" src="'.$js_file.'"></script>'."\n";
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function callHook($hookName, $hookArguments) {
|
||||
//echo '<div style="display:inline;background-color:#CC47CB;padding:3px;border:5px solid #9F1A9E;border-radius:5px;color:#ffffff;font-size:15px;">'.$hookName.'</div>';
|
||||
if(isset($GLOBALS['hooks'][$hookName])) {
|
||||
foreach($GLOBALS['hooks'][$hookName] as $functionName) {
|
||||
call_user_func_array($functionName, $hookArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getFiles($onlyActivated=false){
|
||||
|
||||
$enabled = $disabled = array();
|
||||
$files = glob(dirname(__FILE__). Plugin::FOLDER .'/*/*.plugin*.php');
|
||||
if(empty($files))
|
||||
$files = array();
|
||||
|
||||
foreach($files as $file){
|
||||
$plugin = Plugin::getObject($file);
|
||||
if($plugin->getState()){
|
||||
$enabled [] = $file;
|
||||
}else{
|
||||
$disabled [] = $file;
|
||||
}
|
||||
}
|
||||
if(!$onlyActivated)$enabled = array_merge($enabled,$disabled);
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
|
||||
public static function loadState($plugin){
|
||||
$states = Plugin::getStates();
|
||||
return (isset($states[$plugin])?$states[$plugin]:false);
|
||||
}
|
||||
|
||||
public static function changeState($plugin,$state){
|
||||
$states = Plugin::getStates();
|
||||
$states[$plugin] = $state;
|
||||
|
||||
Plugin::setStates($states);
|
||||
}
|
||||
|
||||
|
||||
public static function enabled($pluginUid){
|
||||
$plugins = Plugin::getAll();
|
||||
|
||||
foreach($plugins as $plugin){
|
||||
if($plugin->getUid()==$pluginUid){
|
||||
Plugin::changeState($plugin->getPath(),true);
|
||||
$install = dirname($plugin->getPath()).'/install.php';
|
||||
if(file_exists($install))require_once($install);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static function disabled($pluginUid){
|
||||
$plugins = Plugin::getAll();
|
||||
foreach($plugins as $plugin){
|
||||
if($plugin->getUid()==$pluginUid){
|
||||
Plugin::changeState($plugin->getPath(),false);
|
||||
$uninstall = dirname($plugin->getPath()).'/uninstall.php';
|
||||
if(file_exists($uninstall))require_once($uninstall);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getUid(){
|
||||
$pathInfo = explode('/',$this->getPath());
|
||||
$count = count($pathInfo);
|
||||
$name = $pathInfo[$count-1];
|
||||
return $pathInfo[$count -2].'-'.substr($name,0,strpos($name,'.'));
|
||||
}
|
||||
|
||||
|
||||
static function sortPlugin($a, $b){
|
||||
if ($a->getName() == $b->getName())
|
||||
return 0;
|
||||
return ($a->getName() < $b->getName()) ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name){
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function setAuthor($author){
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
function getAuthor(){
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
function getMail(){
|
||||
return $this->mail;
|
||||
}
|
||||
|
||||
function setMail($mail){
|
||||
$this->mail = $mail;
|
||||
}
|
||||
|
||||
function getLicence(){
|
||||
return $this->licence;
|
||||
}
|
||||
|
||||
function setLicence($licence){
|
||||
$this->licence = $licence;
|
||||
}
|
||||
|
||||
function getPath(){
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
function setPath($path){
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
function getDescription(){
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
function setDescription($description){
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
|
||||
function getLink(){
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
function setLink($link){
|
||||
$this->link = $link;
|
||||
}
|
||||
|
||||
function getVersion(){
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
function setVersion($version){
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
function getState(){
|
||||
return $this->state;
|
||||
}
|
||||
function setState($state){
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
function getType(){
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
function setType($type){
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
70
sources/README.md
Executable file
70
sources/README.md
Executable file
|
@ -0,0 +1,70 @@
|
|||
Leed
|
||||
====
|
||||
|
||||
Leed (contraction de Light Feed) est un agrégateur [RSS](https://fr.wikipedia.org/wiki/Rss)/[ATOM](https://fr.wikipedia.org/wiki/Atom) minimaliste qui permet la consultation de flux RSS de manière rapide et non intrusive.
|
||||
|
||||
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)
|
||||
- Page du projet : http://projet.idleman.fr/leed
|
||||
- Licence : [CC by-nc-sa](http://creativecommons.org/licenses/by-nc-sa/2.0/fr/)
|
||||
|
||||
Toutes les tâches de traitements de flux sont effectuées de manière invisible par une tâche programmée (cron), ainsi, l'utilisateur ne subit pas les lenteurs dues à la récupération et au traitement de chacuns des flux suivis.
|
||||
|
||||
A noter que Leed est compatible toutes résolutions, sur pc, tablette et smartphone.
|
||||
|
||||
Leed est également compatible avec le format d'import/export [OPML](https://fr.wikipedia.org/wiki/OPML) ce qui le rend compatible avec les agrégateurs respectant ce standard.
|
||||
|
||||
Pré-requis
|
||||
====
|
||||
|
||||
- Serveur Apache conseillé (non testé sur les autres serveurs type Nginx…)
|
||||
- PHP 5.3 minimum
|
||||
- MySQL
|
||||
- Un peu de bon sens :-)
|
||||
|
||||
Installation
|
||||
====
|
||||
|
||||
1. Récupérez le projet sur [idleman.fr](http://projet.idleman.fr/leed/?page=Téléchargement) ou sur la page [github](https://github.com/ldleman/Leed).
|
||||
2. Placez le projet dans votre répertoire web et appliquez si nécessaire une permission _chmod 775_ (si vous êtes sur un hebergement ovh, préférez un _0755_ ou vous aurez une erreur 500) sur le dossier et son contenu.
|
||||
3. Depuis votre navigateur, accédez à la page d'installation _install.php_ (ex : votre.domaine.fr/leed/install.php) et suivez les instructions.
|
||||
4. Une fois l'installation terminée, supprimez le fichier _install.php_ par mesure de sécurité.
|
||||
5. [Optionnel] Si vous souhaitez que les mises à jour de flux se fassent automatiquement, mettez en place un cron. Voir ci-après. Il est conseillé de ne pas mettre une fréquence trop rapide pour laisser le temps au script de s'exécuter.
|
||||
6. Le script est installé, merci d'avoir choisi Leed, l'agrégateur RSS svelte :p
|
||||
|
||||
Tâches programmées avec cron
|
||||
====
|
||||
|
||||
On peut éditer les tâches programmées avec _crontab -e_. Il y a deux façons de mettre à jour les flux. Les exemples qui suivent mettent à jour toutes les heures.
|
||||
|
||||
1. En appelant directement Leed. Cette méthode a l'avantage d'être directe et de produire une sortie formatée pour la console mais requiert un accès local :
|
||||
``` crontab
|
||||
0 * * * * cd (...)/leed && php action.php >> logs/cron.log 2>&1
|
||||
```
|
||||
|
||||
1. En appelant Leed depuis le client web _wget_. Cette méthode nécessite un accès réseau mais a l'avantage de pouvoir être déclenchée à distance. Afin de contrôler l'accès, il est nécessaire de fournir le code de synchronisation :
|
||||
```
|
||||
0 * * * * wget --no-check-certificate --quiet --output-document /var/www/leed/cron.log
|
||||
"http://127.0.0.1/leed/action.php?action=synchronize&code=votre_code_synchronisation"
|
||||
```
|
||||
Si vous n'avez pas accès a la commande _wget_ sur votre serveur, vous pouvez essayer son chemin complet _/usr/bin/wget_.
|
||||
|
||||
Foire Aux Questions (F.A.Q.)
|
||||
====
|
||||
|
||||
Vous pouvez retrouver la FAQ du projet ici : http://projet.idleman.fr/leed/?page=FAQ
|
||||
|
||||
Plugins
|
||||
====
|
||||
Le dépot [Leed market](https://github.com/ldleman/Leed-market) contient tous les plugins à jour et approuvés officiellement pour le logiciel Leed.
|
||||
|
||||
Bibliothèques utilisées
|
||||
==
|
||||
|
||||
- Responsive / Cross browser : Initializr (http://www.initializr.com)
|
||||
- Javascript : JQuery (http://www.jquery.com)
|
||||
- Moteur template : RainTPL (http://www.raintpl.com)
|
||||
- Parseur RSS : SimplePie (http://simplepie.org)
|
1071
sources/RainTPL.php
Executable file
1071
sources/RainTPL.php
Executable file
File diff suppressed because it is too large
Load diff
17887
sources/SimplePie.class.php
Executable file
17887
sources/SimplePie.class.php
Executable file
File diff suppressed because it is too large
Load diff
113
sources/Update.class.php
Executable file
113
sources/Update.class.php
Executable file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
@nom: Update
|
||||
@auteur: Maël ILLOUZ (mael.illouz@cobestran.com)
|
||||
@description: Classe de gestion des mises à jour en BDD liées aux améliorations apportées dans Leed
|
||||
@todo : Ajouter la possiblité d'executer des fichiers php de maj.
|
||||
*/
|
||||
|
||||
class Update{
|
||||
const FOLDER = '/updates';
|
||||
|
||||
/**
|
||||
* Description : Récupération des fichiers déjà passés lors des anciennes mises à jour.
|
||||
*/
|
||||
private static function getUpdateFile(){
|
||||
$updateFile = dirname(__FILE__).Update::FOLDER.'/update.json';
|
||||
if(!file_exists($updateFile)) {
|
||||
if (!touch($updateFile)) {
|
||||
die ('Impossible d\'écrire dans le répertoire .'.dirname($updateFile).'. Merci d\'ajouter les droits necessaires.');
|
||||
}
|
||||
}
|
||||
|
||||
return json_decode(file_get_contents($updateFile),true);
|
||||
}
|
||||
|
||||
private static function addUpdateFile($addFile){
|
||||
$updateFile = dirname(__FILE__).Update::FOLDER.'/update.json';
|
||||
$originFile = Update::getUpdateFile();
|
||||
if(empty($originFile))
|
||||
$originFile = array();
|
||||
$newfile = array_merge($originFile,$addFile);
|
||||
if (is_writable($updateFile)){
|
||||
file_put_contents($updateFile,json_encode($newfile));
|
||||
} else {
|
||||
die ('Impossible d\'écrire dans le fichier .'.$updateFile.'. Merci d\'ajouter les droits nécessaires.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Description : Permet de trouver les fichiers qui n'ont pas encore été joués
|
||||
*/
|
||||
private static function getNewPatch() {
|
||||
$files = glob(dirname(__FILE__). Update::FOLDER .'/*.sql');
|
||||
if(empty($files))
|
||||
$files = array();
|
||||
|
||||
$jsonFiles = Update::getUpdateFile();
|
||||
|
||||
$alreadyPassed = array();
|
||||
$notPassed = array();
|
||||
|
||||
if ($jsonFiles==''){
|
||||
$jsonFiles[0] = array();
|
||||
}
|
||||
foreach($files as $file){
|
||||
if(in_array(basename($file), $jsonFiles[0])){
|
||||
$alreadyPassed [] = basename($file);
|
||||
}else{
|
||||
$notPassed [] = basename($file);
|
||||
}
|
||||
}
|
||||
return $notPassed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description : Permet l'execution des fichiers sql non joués
|
||||
* @simulation : true pour ne pas faire les actions en bdd
|
||||
*/
|
||||
public static function ExecutePatch($simulation=false) {
|
||||
$newFilesForUpdate = Update::getNewPatch();
|
||||
|
||||
//si aucun nouveau fichier de mise à jour à traiter @return : false
|
||||
if(count($newFilesForUpdate)==0) return false;
|
||||
if (!$simulation) {
|
||||
foreach($newFilesForUpdate as $file){
|
||||
// récupération du contenu du sql
|
||||
$sql = file_get_contents(dirname(__FILE__).Update::FOLDER.'/'.$file);
|
||||
|
||||
$conn = new MysqlEntity();
|
||||
//on sépare chaque requête par les ;
|
||||
$sql_array = explode (";",$sql);
|
||||
foreach ($sql_array as $val) {
|
||||
$val = preg_replace('#([-].*)|(\n)#','',$val);
|
||||
if ($val != '') {
|
||||
//remplacement des préfixes de table
|
||||
$val = str_replace('##MYSQL_PREFIX##',MYSQL_PREFIX,$val);
|
||||
$result = mysql_query($val);
|
||||
$ficlog = dirname(__FILE__).Update::FOLDER.'/'.substr($file,0,strlen($file)-3).'log';
|
||||
if (false===$result) {
|
||||
file_put_contents($ficlog, date('d/m/Y H:i:s').' : SQL : '.$val."\n", FILE_APPEND);
|
||||
file_put_contents($ficlog, date('d/m/Y H:i:s').' : '.mysql_error()."\n", FILE_APPEND);
|
||||
} else {
|
||||
file_put_contents($ficlog, date('d/m/Y H:i:s').' : SQL : '.$val."\n", FILE_APPEND);
|
||||
file_put_contents($ficlog, date('d/m/Y H:i:s').' : '.mysql_affected_rows().' rows affected'."\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($conn);
|
||||
}
|
||||
$_SESSION = array();
|
||||
session_unset();
|
||||
session_destroy();
|
||||
}
|
||||
// quand toutes les requêtes ont été executées, on insert le sql dans le json
|
||||
Update::addUpdateFile(array($newFilesForUpdate));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
95
sources/User.class.php
Executable file
95
sources/User.class.php
Executable file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: User
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Classe de gestion des utilisateurs
|
||||
*/
|
||||
|
||||
class User extends MysqlEntity{
|
||||
|
||||
protected $id,$login,$password;
|
||||
protected $TABLE_NAME = 'user';
|
||||
protected $CLASS_NAME = 'User';
|
||||
protected $object_fields =
|
||||
array(
|
||||
'id'=>'key',
|
||||
'login'=>'string',
|
||||
'password'=>'string'
|
||||
);
|
||||
|
||||
function __construct(){
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function setId($id){
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function exist($login,$password,$salt=''){
|
||||
$userManager = new User();
|
||||
return $userManager->load(array('login'=>$login,'password'=>User::encrypt($password,$salt)));
|
||||
}
|
||||
|
||||
function get($login){
|
||||
$userManager = new User();
|
||||
return $userManager->load(array('login'=>$login,));
|
||||
}
|
||||
|
||||
function getToken() {
|
||||
assert('!empty($this->password)');
|
||||
assert('!empty($this->login)');
|
||||
return sha1($this->password.$this->login);
|
||||
}
|
||||
|
||||
static function existAuthToken($auth=null){
|
||||
$result = false;
|
||||
$userManager = new User();
|
||||
$users = $userManager->populate('id');
|
||||
if (empty($auth)) $auth = @$_COOKIE['leedStaySignedIn'];
|
||||
foreach($users as $user){
|
||||
if($user->getToken()==$auth) $result = $user;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function setStayConnected() {
|
||||
///@TODO: set the current web directory, here and on del
|
||||
setcookie('leedStaySignedIn', $this->getToken(), time()+31536000);
|
||||
}
|
||||
|
||||
static function delStayConnected() {
|
||||
setcookie('leedStaySignedIn', '', -1);
|
||||
}
|
||||
|
||||
function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getLogin(){
|
||||
return $this->login;
|
||||
}
|
||||
|
||||
function setLogin($login){
|
||||
$this->login = $login;
|
||||
}
|
||||
|
||||
function getPassword(){
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
function setPassword($password,$salt=''){
|
||||
$this->password = User::encrypt($password,$salt);
|
||||
}
|
||||
|
||||
static function encrypt($password, $salt=''){
|
||||
return sha1($password.$salt);
|
||||
}
|
||||
|
||||
static function generateSalt() {
|
||||
return ''.mt_rand().mt_rand();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
17
sources/about.php
Executable file
17
sources/about.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: about
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page "A propos" d'information contextuelles sur le projet
|
||||
*/
|
||||
|
||||
require_once('header.php');
|
||||
require_once('constant.php');
|
||||
|
||||
$tpl->assign('VERSION_NUMBER',VERSION_NUMBER);
|
||||
$tpl->assign('VERSION_NAME',VERSION_NAME);
|
||||
$view = 'about';
|
||||
require_once('footer.php');
|
||||
|
||||
?>
|
604
sources/action.php
Executable file
604
sources/action.php
Executable file
|
@ -0,0 +1,604 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: action
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page de gestion des évenements non liés a une vue particulière (appels ajax, requetes sans resultats etc...)
|
||||
*/
|
||||
|
||||
if(!ini_get('safe_mode')) @set_time_limit(0);
|
||||
require_once("common.php");
|
||||
|
||||
///@TODO: déplacer dans common.php?
|
||||
$commandLine = 'cli'==php_sapi_name();
|
||||
|
||||
if ($commandLine) {
|
||||
$action = 'commandLine';
|
||||
} else {
|
||||
$action = @$_['action'];
|
||||
}
|
||||
///@TODO: pourquoi ne pas refuser l'accès dès le début ?
|
||||
Plugin::callHook("action_pre_case", array(&$_,$myUser));
|
||||
|
||||
//Execution du code en fonction de l'action
|
||||
switch ($action){
|
||||
case 'commandLine':
|
||||
case 'synchronize':
|
||||
require_once("SimplePie.class.php");
|
||||
$syncCode = $configurationManager->get('synchronisationCode');
|
||||
if ( false==$myUser
|
||||
&& !$commandLine
|
||||
&& !(isset($_['code'])
|
||||
&& $configurationManager->get('synchronisationCode')!=null
|
||||
&& $_['code']==$configurationManager->get('synchronisationCode')
|
||||
)
|
||||
) {
|
||||
die(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
}
|
||||
Functions::triggerDirectOutput();
|
||||
|
||||
if (!$commandLine)
|
||||
echo '<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="./templates/'.DEFAULT_THEME.'/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="sync">';
|
||||
$synchronisationType = $configurationManager->get('synchronisationType');
|
||||
$maxEvents = $configurationManager->get('feedMaxEvents');
|
||||
if('graduate'==$synchronisationType){
|
||||
// sélectionne les 10 plus vieux flux
|
||||
$feeds = $feedManager->loadAll(null,'lastupdate',defined('SYNC_GRAD_COUNT') ? SYNC_GRAD_COUNT : 10);
|
||||
$syncTypeStr = _t('SYNCHRONISATION_TYPE').' : '._t('GRADUATE_SYNCHRONISATION');
|
||||
}else{
|
||||
// sélectionne tous les flux, triés par le nom
|
||||
$feeds = $feedManager->populate('name');
|
||||
$syncTypeStr = _t('SYNCHRONISATION_TYPE').' : '._t('FULL_SYNCHRONISATION');
|
||||
}
|
||||
|
||||
|
||||
$currentDate = date('d/m/Y H:i:s');
|
||||
if (!$commandLine) {
|
||||
echo "<p>{$syncTypeStr} {$currentDate}</p>\n";
|
||||
echo "<dl>\n";
|
||||
} else {
|
||||
echo "{$syncTypeStr}\t{$currentDate}\n";
|
||||
}
|
||||
$nbErrors = 0;
|
||||
$nbOk = 0;
|
||||
$nbTotal = 0;
|
||||
$localTotal = 0; // somme de tous les temps locaux, pour chaque flux
|
||||
$nbTotalEvents = 0;
|
||||
$syncId = time();
|
||||
$enableCache = ($configurationManager->get('synchronisationEnableCache')=='')?0:$configurationManager->get('synchronisationEnableCache');
|
||||
$forceFeed = ($configurationManager->get('synchronisationForceFeed')=='')?0:$configurationManager->get('synchronisationForceFeed');
|
||||
|
||||
foreach ($feeds as $feed) {
|
||||
$nbEvents = 0;
|
||||
$nbTotal++;
|
||||
$startLocal = microtime(true);
|
||||
$parseOk = $feed->parse($syncId,$nbEvents, $enableCache, $forceFeed);
|
||||
$parseTime = microtime(true)-$startLocal;
|
||||
$localTotal += $parseTime;
|
||||
$parseTimeStr = number_format($parseTime, 3);
|
||||
if ($parseOk) { // It's ok
|
||||
$errors = array();
|
||||
$nbTotalEvents += $nbEvents;
|
||||
$nbOk++;
|
||||
} else {
|
||||
// tableau au cas où il arrive plusieurs erreurs
|
||||
$errors = array($feed->getError());
|
||||
|
||||
$nbErrors++;
|
||||
}
|
||||
$feedName = Functions::truncate($feed->getName(),30);
|
||||
$feedUrl = $feed->getUrl();
|
||||
$feedUrlTxt = Functions::truncate($feedUrl, 30);
|
||||
if ($commandLine) {
|
||||
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";
|
||||
|
||||
}
|
||||
foreach($errors as $error) {
|
||||
if ($commandLine)
|
||||
echo "$error\n";
|
||||
else
|
||||
echo "<dd>$error</dd>\n";
|
||||
}
|
||||
if (!$parseOk && !$commandLine) echo '</div>';
|
||||
// if ($commandLine) echo "\n";
|
||||
$feed->removeOldEvents($maxEvents, $syncId);
|
||||
}
|
||||
assert('$nbTotal==$nbOk+$nbErrors');
|
||||
$totalTime = microtime(true)-$start;
|
||||
assert('$totalTime>=$localTotal');
|
||||
$totalTimeStr = number_format($totalTime, 3);
|
||||
$currentDate = date('d/m/Y H:i:s');
|
||||
if ($commandLine) {
|
||||
echo "\t{$nbErrors}\t"._t('ERRORS')."\n";
|
||||
echo "\t{$nbOk}\t"._t('GOOD')."\n";
|
||||
echo "\t{$nbTotal}\t"._t('AT_TOTAL')."\n";
|
||||
echo "\t$currentDate\n";
|
||||
echo "\t$nbTotalEvents\n";
|
||||
echo "\t{$totalTimeStr}\t"._t('SECONDS')."\n";
|
||||
} else {
|
||||
echo "</dl>\n";
|
||||
echo "<div id='syncSummary'\n";
|
||||
echo "<p>"._t('SYNCHRONISATION_COMPLETE')."</p>\n";
|
||||
echo "<ul>\n";
|
||||
echo "<li>{$nbErrors} "._t('ERRORS')."\n";
|
||||
echo "<li>{$nbOk} "._t('GOOD')."\n";
|
||||
echo "<li>{$nbTotal} "._t('AT_TOTAL')."\n";
|
||||
echo "<li>{$totalTimeStr}\t"._t('SECONDS')."\n";
|
||||
echo "<li>{$nbTotalEvents} nouveaux articles\n";
|
||||
echo "</ul>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
if (!$commandLine) {
|
||||
echo '</div></body></html>';
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'readAll':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
$whereClause = array();
|
||||
$whereClause['unread'] = '1';
|
||||
if(isset($_['feed']))$whereClause['feed'] = $_['feed'];
|
||||
$eventManager->change(array('unread'=>'0'),$whereClause);
|
||||
header('location: ./index.php');
|
||||
break;
|
||||
|
||||
case 'readFolder':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
|
||||
$feeds = $feedManager->loadAllOnlyColumn('id',array('folder'=>$_['folder']));
|
||||
|
||||
foreach($feeds as $feed){
|
||||
$eventManager->change(array('unread'=>'0'),array('feed'=>$feed->getId()));
|
||||
}
|
||||
|
||||
header('location: ./index.php');
|
||||
|
||||
break;
|
||||
|
||||
case 'updateConfiguration':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
|
||||
//Ajout des préférences et réglages
|
||||
$configurationManager->put('root',(substr($_['root'], strlen($_['root'])-1)=='/'?$_['root']:$_['root'].'/'));
|
||||
//$configurationManager->put('view',$_['view']);
|
||||
if(isset($_['articleView']))
|
||||
$configurationManager->put('articleView',$_['articleView']);
|
||||
$configurationManager->put('articleDisplayContent',$_['articleDisplayContent']);
|
||||
$configurationManager->put('articleDisplayAnonymous',$_['articleDisplayAnonymous']);
|
||||
|
||||
$configurationManager->put('articlePerPages',$_['articlePerPages']);
|
||||
$configurationManager->put('articleDisplayLink',$_['articleDisplayLink']);
|
||||
$configurationManager->put('articleDisplayDate',$_['articleDisplayDate']);
|
||||
$configurationManager->put('articleDisplayAuthor',$_['articleDisplayAuthor']);
|
||||
$configurationManager->put('articleDisplayHomeSort',$_['articleDisplayHomeSort']);
|
||||
$configurationManager->put('articleDisplayFolderSort',$_['articleDisplayFolderSort']);
|
||||
$configurationManager->put('synchronisationType',$_['synchronisationType']);
|
||||
$configurationManager->put('synchronisationEnableCache',$_['synchronisationEnableCache']);
|
||||
$configurationManager->put('synchronisationForceFeed',$_['synchronisationForceFeed']);
|
||||
$configurationManager->put('feedMaxEvents',$_['feedMaxEvents']);
|
||||
|
||||
$userManager->change(array('login'=>$_['login']),array('id'=>$myUser->getId()));
|
||||
if(trim($_['password'])!='') {
|
||||
$salt = User::generateSalt();
|
||||
$userManager->change(array('password'=>User::encrypt($_['password'], $salt)),array('id'=>$myUser->getId()));
|
||||
/* /!\ En multi-utilisateur, il faudra changer l'information au
|
||||
niveau du compte lui-même et non au niveau du déploiement comme
|
||||
ici. C'est ainsi parce que c'est plus efficace de stocker le sel
|
||||
dans la config que dans le fichier de constantes, difficile à
|
||||
modifier. */
|
||||
$oldSalt = $configurationManager->get('cryptographicSalt');
|
||||
if (empty($oldSalt))
|
||||
/* Pendant la migration à ce système, les déploiements
|
||||
ne posséderont pas cette donnée. */
|
||||
$configurationManager->add('cryptographicSalt', $salt);
|
||||
else
|
||||
$configurationManager->change(array('value'=>$salt), array('key'=>'cryptographicSalt'));
|
||||
|
||||
}
|
||||
|
||||
header('location: ./settings.php#preferenceBloc');
|
||||
break;
|
||||
|
||||
|
||||
case 'purge':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
$eventManager->truncate();
|
||||
header('location: ./settings.php');
|
||||
break;
|
||||
|
||||
|
||||
case 'exportFeed':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
/*********************/
|
||||
/** Export **/
|
||||
/*********************/
|
||||
if(isset($_POST['exportButton'])){
|
||||
$opml = new Opml();
|
||||
$xmlStream = $opml->export();
|
||||
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=leed-'.date('d-m-Y').'.opml');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . strlen($xmlStream));
|
||||
/*
|
||||
//A decommenter dans le cas ou on a des pb avec ie
|
||||
if(preg_match('/msie|(microsoft internet explorer)/i', $_SERVER['HTTP_USER_AGENT'])){
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Pragma: public');
|
||||
}else{
|
||||
header('Pragma: no-cache');
|
||||
}
|
||||
*/
|
||||
ob_clean();
|
||||
flush();
|
||||
echo $xmlStream;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'importForm':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
echo '<html style="height:auto;"><link rel="stylesheet" href="templates/marigolds/css/style.css">
|
||||
<body style="height:auto;">
|
||||
<form action="action.php?action=importFeed" method="POST" enctype="multipart/form-data">
|
||||
<p>'._t('OPML_FILE').' : <input name="newImport" type="file"/> <button name="importButton">'._t('IMPORT').'</button></p>
|
||||
<p>'._t('IMPORT_COFFEE_TIME').'</p>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
';
|
||||
break;
|
||||
|
||||
case 'synchronizeForm':
|
||||
if(isset($myUser) && $myUser!=false){
|
||||
echo '<link rel="stylesheet" href="templates/marigolds/css/style.css">
|
||||
<a class="button" href="action.php?action=synchronize">'._t('SYNCHRONIZE_NOW').'</a>
|
||||
<p>'._t('SYNCHRONIZE_COFFEE_TIME').'</p>
|
||||
|
||||
';
|
||||
}else{
|
||||
echo _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'changeFolderState':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
$folderManager->change(array('isopen'=>$_['isopen']),array('id'=>$_['id']));
|
||||
break;
|
||||
|
||||
case 'importFeed':
|
||||
// On ne devrait pas mettre de style ici.
|
||||
echo "<html>
|
||||
<style>
|
||||
a {
|
||||
color:#F16529;
|
||||
}
|
||||
|
||||
html,body{
|
||||
font-family:Verdana;
|
||||
font-size: 11px;
|
||||
}
|
||||
.error{
|
||||
background-color:#C94141;
|
||||
color:#ffffff;
|
||||
padding:5px;
|
||||
border-radius:5px;
|
||||
margin:10px 0px 10px 0px;
|
||||
box-shadow: 0 0 3px 0 #810000;
|
||||
}
|
||||
.error a{
|
||||
color:#ffffff;
|
||||
}
|
||||
</style>
|
||||
</style><body>
|
||||
\n";
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(!isset($_POST['importButton'])) break;
|
||||
$opml = new Opml();
|
||||
echo "<h3>"._t('IMPORT')."</h3><p>"._t('PENDING')."</p>\n";
|
||||
try {
|
||||
$errorOutput = $opml->import($_FILES['newImport']['tmp_name']);
|
||||
} catch (Exception $e) {
|
||||
$errorOutput = array($e->getMessage());
|
||||
}
|
||||
if (empty($errorOutput)) {
|
||||
echo "<p>"._t('IMPORT_NO_PROBLEM')."</p>\n";
|
||||
} else {
|
||||
echo "<div class='error'>"._t('IMPORT_ERROR')."\n";
|
||||
foreach($errorOutput as $line) {
|
||||
echo "<p>$line</p>\n";
|
||||
}
|
||||
echo "</div>";
|
||||
}
|
||||
if (!empty($opml->alreadyKnowns)) {
|
||||
echo "<h3>"._t('IMPORT_FEED_ALREADY_KNOWN')." : </h3>\n<ul>\n";
|
||||
foreach($opml->alreadyKnowns as $alreadyKnown) {
|
||||
foreach($alreadyKnown as &$elt) $elt = htmlspecialchars($elt);
|
||||
$text = Functions::truncate($alreadyKnown->feedName, 60);
|
||||
echo "<li><a target='_parent' href='{$alreadyKnown->xmlUrl}'>"
|
||||
."{$text}</a></li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
}
|
||||
$syncLink = "action.php?action=synchronize&format=html";
|
||||
echo "<p>";
|
||||
echo "<a href='$syncLink' style='text-decoration:none;font-size:3em'>"
|
||||
."↺</a>";
|
||||
echo "<a href='$syncLink'>"._t('CLIC_HERE_SYNC_IMPORT')."</a>";
|
||||
echo "<p></body></html>\n";
|
||||
break;
|
||||
|
||||
|
||||
case 'addFeed':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
require_once("SimplePie.class.php");
|
||||
if(!isset($_['newUrl'])) break;
|
||||
$newFeed = new Feed();
|
||||
$newFeed->setUrl(Functions::clean_url($_['newUrl']));
|
||||
if ($newFeed->notRegistered()) {
|
||||
///@TODO: avertir l'utilisateur du doublon non ajouté
|
||||
$newFeed->getInfos();
|
||||
$newFeed->setFolder(
|
||||
(isset($_['newUrlCategory'])?$_['newUrlCategory']:1)
|
||||
);
|
||||
$newFeed->save();
|
||||
$enableCache = ($configurationManager->get('synchronisationEnableCache')=='')?0:$configurationManager->get('synchronisationEnableCache');
|
||||
$forceFeed = ($configurationManager->get('synchronisationForceFeed')=='')?0:$configurationManager->get('synchronisationForceFeed');
|
||||
$newFeed->parse(time(), $_, $enableCache, $forceFeed);
|
||||
}
|
||||
header('location: ./settings.php#manageBloc');
|
||||
break;
|
||||
|
||||
case 'changeFeedFolder':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(isset($_['feed'])){
|
||||
$feedManager->change(array('folder'=>$_['folder']),array('id'=>$_['feed']));
|
||||
}
|
||||
header('location: ./settings.php');
|
||||
break;
|
||||
|
||||
case 'removeFeed':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(isset($_GET['id'])){
|
||||
$feedManager->delete(array('id'=>$_['id']));
|
||||
$eventManager->delete(array('feed'=>$_['id']));
|
||||
}
|
||||
header('location: ./settings.php');
|
||||
break;
|
||||
|
||||
case 'addFolder':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(isset($_['newFolder'])){
|
||||
$folder = new Folder();
|
||||
if($folder->rowCount(array('name'=>$_['newFolder']))==0){
|
||||
$folder->setParent(-1);
|
||||
$folder->setIsopen(0);
|
||||
$folder->setName($_['newFolder']);
|
||||
$folder->save();
|
||||
}
|
||||
}
|
||||
header('location: ./settings.php');
|
||||
break;
|
||||
|
||||
|
||||
case 'renameFolder':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(isset($_['id'])){
|
||||
$folderManager->change(array('name'=>$_['name']),array('id'=>$_['id']));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'renameFeed':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
if(isset($_['id'])){
|
||||
$feedManager->change(array('name'=>$_['name'],'url'=>Functions::clean_url($_['url'])),array('id'=>$_['id']));
|
||||
}
|
||||
break;
|
||||
|
||||
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']).'\') ;');
|
||||
$feedManager->delete(array('folder'=>$_['id']));
|
||||
$folderManager->delete(array('id'=>$_['id']));
|
||||
}
|
||||
header('location: ./settings.php');
|
||||
break;
|
||||
|
||||
case 'readContent':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
if(isset($_['id'])){
|
||||
$event = $eventManager->load(array('id'=>$_['id']));
|
||||
$eventManager->change(array('unread'=>'0'),array('id'=>$_['id']));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'unreadContent':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
if(isset($_['id'])){
|
||||
$event = $eventManager->load(array('id'=>$_['id']));
|
||||
$eventManager->change(array('unread'=>'1'),array('id'=>$_['id']));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'addFavorite':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
$eventManager->change(array('favorite'=>'1'),array('id'=>$_['id']));
|
||||
break;
|
||||
|
||||
case 'removeFavorite':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
$eventManager->change(array('favorite'=>'0'),array('id'=>$_['id']));
|
||||
break;
|
||||
|
||||
case 'login':
|
||||
|
||||
define('RESET_PASSWORD_FILE', 'resetPassword');
|
||||
if (file_exists(RESET_PASSWORD_FILE)) {
|
||||
/* Pour réinitialiser le mot de passe :
|
||||
* créer le fichier RESET_PASSWORD_FILE vide.
|
||||
* Le nouveau mot de passe sera celui fourni à la connexion.
|
||||
*/
|
||||
@unlink(RESET_PASSWORD_FILE);
|
||||
if (file_exists(RESET_PASSWORD_FILE)) {
|
||||
$message = 'Unable to remove "'.RESET_PASSWORD_FILE.'"!';
|
||||
/* Pas supprimable ==> on ne remet pas à zéro */
|
||||
} else {
|
||||
$resetPassword = $_['password'];
|
||||
assert('!empty($resetPassword)');
|
||||
$tmpUser = User::get($_['login']);
|
||||
if (false===$tmpUser) {
|
||||
$message = "Unknown user '{$_['login']}'! No password reset.";
|
||||
} else {
|
||||
$id = $tmpUser->getId();
|
||||
$salt = $configurationManager->get('cryptographicSalt');
|
||||
$userManager->change(
|
||||
array('password'=>User::encrypt($resetPassword, $salt)),
|
||||
array('id'=>$id)
|
||||
);
|
||||
$message = "User '{$_['login']}' (id=$id) Password reset to '$resetPassword'.";
|
||||
}
|
||||
}
|
||||
error_log($message);
|
||||
}
|
||||
|
||||
if(isset($_['usr'])){
|
||||
$user = User::existAuthToken($_['usr']);
|
||||
if($user==false){
|
||||
exit("erreur identification : le compte est inexistant");
|
||||
}else{
|
||||
$_SESSION['currentUser'] = serialize($user);
|
||||
header('location: ./action.php?action=addFeed&newUrl='.$_['newUrl']);
|
||||
}
|
||||
}else{
|
||||
$salt = $configurationManager->get('cryptographicSalt');
|
||||
if (empty($salt)) $salt = '';
|
||||
$user = $userManager->exist($_['login'],$_['password'],$salt);
|
||||
if($user==false){
|
||||
exit("erreur identification : le compte est inexistant");
|
||||
}else{
|
||||
$_SESSION['currentUser'] = serialize($user);
|
||||
if (isset($_['rememberMe'])) $user->setStayConnected();
|
||||
}
|
||||
header('location: ./index.php');
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'changePluginState':
|
||||
if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
|
||||
|
||||
if($_['state']=='0'){
|
||||
Plugin::enabled($_['plugin']);
|
||||
|
||||
}else{
|
||||
Plugin::disabled($_['plugin']);
|
||||
}
|
||||
header('location: ./settings.php#pluginBloc');
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case 'logout':
|
||||
User::delStayConnected();
|
||||
$_SESSION = array();
|
||||
session_unset();
|
||||
session_destroy();
|
||||
header('location: ./index.php');
|
||||
break;
|
||||
|
||||
case 'displayOnlyUnreadFeedFolder':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
$configurationManager->put('displayOnlyUnreadFeedFolder',$_['displayOnlyUnreadFeedFolder']);
|
||||
break;
|
||||
|
||||
case 'displayFeedIsVerbose':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
// changement du statut isverbose du feed
|
||||
$feed = new Feed();
|
||||
$feed = $feed->getById($_['idFeed']);
|
||||
$feed->setIsverbose(($_['displayFeedIsVerbose']=="0"?1:0));
|
||||
$feed->save();
|
||||
break;
|
||||
|
||||
case 'optionFeedIsVerbose':
|
||||
if($myUser==false) {
|
||||
$response_array['status'] = 'noconnect';
|
||||
$response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($response_array);
|
||||
exit();
|
||||
}
|
||||
// changement du statut de l'option
|
||||
$configurationManager = new Configuration();
|
||||
$conf = $configurationManager->getAll();
|
||||
$configurationManager->put('optionFeedIsVerbose',($_['optionFeedIsVerbose']=="0"?0:1));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
require_once("SimplePie.class.php");
|
||||
Plugin::callHook("action_post_case", array(&$_,$myUser));
|
||||
//exit('0');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
?>
|
93
sources/article.php
Executable file
93
sources/article.php
Executable file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: article
|
||||
@auteur: Maël ILLOUZ (mael.illouz@cobestran.com)
|
||||
@description: Page de gestion de l'affichage des articles. Sera utilisé de base ainsi que pour le scroll infini
|
||||
*/
|
||||
|
||||
include ('common.php');
|
||||
$view = "article";
|
||||
//recuperation de tous les flux
|
||||
$allFeeds = $feedManager->getFeedsPerFolder();
|
||||
$tpl->assign('allFeeds',$allFeeds);
|
||||
$tpl->assign('scrollpage',$_['scroll']);
|
||||
// récupération des variables pour l'affichage
|
||||
$articleDisplayContent = $configurationManager->get('articleDisplayContent');
|
||||
$articleView = $configurationManager->get('articleView');
|
||||
$articlePerPages = $configurationManager->get('articlePerPages');
|
||||
$articleDisplayLink = $configurationManager->get('articleDisplayLink');
|
||||
$articleDisplayDate = $configurationManager->get('articleDisplayDate');
|
||||
$articleDisplayAuthor = $configurationManager->get('articleDisplayAuthor');
|
||||
$articleDisplayHomeSort = $configurationManager->get('articleDisplayHomeSort');
|
||||
$articleDisplayFolderSort = $configurationManager->get('articleDisplayFolderSort');
|
||||
$optionFeedIsVerbose = $configurationManager->get('optionFeedIsVerbose');
|
||||
|
||||
$tpl->assign('articleView',$articleView);
|
||||
$tpl->assign('articleDisplayLink',$articleDisplayLink);
|
||||
$tpl->assign('articleDisplayDate',$articleDisplayDate);
|
||||
$tpl->assign('articleDisplayAuthor',$articleDisplayAuthor);
|
||||
$tpl->assign('articleDisplayContent',$articleDisplayContent);
|
||||
|
||||
|
||||
$hightlighted = $_['hightlighted'];
|
||||
$tpl->assign('hightlighted',$hightlighted);
|
||||
|
||||
$tpl->assign('time',$_SERVER['REQUEST_TIME']);
|
||||
|
||||
$target = MYSQL_PREFIX.'event.title,'.MYSQL_PREFIX.'event.unread,'.MYSQL_PREFIX.'event.favorite,'.MYSQL_PREFIX.'event.feed,';
|
||||
if($articleDisplayContent && $articleView=='partial') $target .= MYSQL_PREFIX.'event.description,';
|
||||
if($articleDisplayContent && $articleView!='partial') $target .= MYSQL_PREFIX.'event.content,';
|
||||
if($articleDisplayLink) $target .= MYSQL_PREFIX.'event.link,';
|
||||
if($articleDisplayDate) $target .= MYSQL_PREFIX.'event.pubdate,';
|
||||
if($articleDisplayAuthor) $target .= MYSQL_PREFIX.'event.creator,';
|
||||
$target .= MYSQL_PREFIX.'event.id';
|
||||
|
||||
$startArticle = ($_['scroll']*$articlePerPages)-$_['nblus'];
|
||||
if ($startArticle < 0) $startArticle=0;
|
||||
$action = $_['action'];
|
||||
|
||||
switch($action){
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER */
|
||||
case 'selectedFeed':
|
||||
$currentFeed = $feedManager->getById($_['feed']);
|
||||
$allowedOrder = array('date'=>'pubdate DESC','older'=>'pubdate','unread'=>'unread DESC,pubdate DESC');
|
||||
$order = (isset($_['order'])?$allowedOrder[$_['order']]:$allowedOrder['date']);
|
||||
$events = $currentFeed->getEvents($startArticle,$articlePerPages,$order,$target);
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER en mode non lus */
|
||||
case 'selectedFeedNonLu':
|
||||
$currentFeed = $feedManager->getById($_['feed']);
|
||||
$filter = array('unread'=>1, 'feed'=>$currentFeed->getId());
|
||||
$order = 'pubdate DESC';
|
||||
$events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$startArticle.','.$articlePerPages);
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN DOSSIER EN PARTICULIER */
|
||||
case 'selectedFolder':
|
||||
$currentFolder = $folderManager->getById($_['folder']);
|
||||
if($articleDisplayFolderSort) {$order = MYSQL_PREFIX.'event.pubdate desc';} else {$order = MYSQL_PREFIX.'event.pubdate asc';}
|
||||
$events = $currentFolder->getEvents($startArticle,$articlePerPages,$order,$target);
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS FAVORIS */
|
||||
case 'favorites':
|
||||
$events = $eventManager->loadAllOnlyColumn($target,array('favorite'=>1),'pubdate DESC',$startArticle.','.$articlePerPages);
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS NON LUS (COMPORTEMENT PAR DEFAUT) */
|
||||
case 'unreadEvents':
|
||||
default:
|
||||
$filter = array('unread'=>1);
|
||||
if($articleDisplayHomeSort) {$order = 'pubdate desc';} else {$order = 'pubdate asc';}
|
||||
if($optionFeedIsVerbose) {
|
||||
$events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$startArticle.','.$articlePerPages);
|
||||
} else {
|
||||
$events = $eventManager->getEventsNotVerboseFeed($startArticle,$articlePerPages,$order,$target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
$tpl->assign('events',$events);
|
||||
$tpl->assign('scroll',$_['scroll']);
|
||||
$view = "article";
|
||||
Plugin::callHook("index_post_treatment", array(&$events));
|
||||
$html = $tpl->draw($view);
|
||||
|
||||
?>
|
127
sources/common.php
Executable file
127
sources/common.php
Executable file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: common
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@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.6.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);
|
||||
}
|
||||
};
|
||||
/* ---------------------------------------------------------------- */
|
||||
// Mise en place d'un timezone par default pour utiliser les fonction de date en php
|
||||
$timezone_default = 'Europe/Paris'; // valeur par défaut :)
|
||||
date_default_timezone_set($timezone_default);
|
||||
$timezone_phpini = ini_get('date.timezone');
|
||||
if (($timezone_phpini!='') && (strcmp($timezone_default, $timezone_phpini))) {
|
||||
date_default_timezone_set($timezone_phpini);
|
||||
}
|
||||
/* ---------------------------------------------------------------- */
|
||||
$cookiedir = '';
|
||||
if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
|
||||
session_set_cookie_params(0, $cookiedir);
|
||||
session_start();
|
||||
mb_internal_encoding('UTF-8'); // UTF8 pour fonctions mb_*
|
||||
$start=microtime(true);
|
||||
require_once('constant.php');
|
||||
//@todo requis pour la MAJ 1.5 vers 1.6 mais pourra être supprimé.
|
||||
if (!defined('LANGUAGE')) {
|
||||
preg_match('#define\(\'LANGAGE\',\'([A-Za-z0-9.]+)\'\);?#',$content,$matches_language);
|
||||
if (isset($matches_language[1]) && isset($matches_language[1])!='') {
|
||||
// pour ceux qui viennent de la branche de dev avant update en LANGUAGE.
|
||||
$content = preg_replace('#define\(\'LANGAGE\',\'([A-Za-z0-9.]+)\'\);?#','define(\'LANGUAGE\',\''.$matches_language[1].'\');', $content);
|
||||
file_put_contents('constant.php', $content);
|
||||
define('LANGUAGE', $matches_language[1]); // ancienne constante encore utilisée
|
||||
} else {
|
||||
// pour ceux qui viennent de la v1.5. la variable n'existait pas
|
||||
$content = preg_replace('#\?\>#',"//Langue utilisée\ndefine('LANGUAGE','fr');\n?>", $content);
|
||||
file_put_contents('constant.php', $content);
|
||||
define('LANGUAGE', 'fr');
|
||||
}
|
||||
}
|
||||
// fin MAJ 1.5 vers 1.6
|
||||
require_once('RainTPL.php');
|
||||
require_once('i18n.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');
|
||||
class_exists('Opml') or require_once('Opml.class.php');
|
||||
|
||||
|
||||
//error_reporting(E_ALL);
|
||||
|
||||
//Calage de la date
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
|
||||
$userManager = new User();
|
||||
$myUser = (isset($_SESSION['currentUser'])?unserialize($_SESSION['currentUser']):false);
|
||||
if (empty($myUser)) {
|
||||
/* Pas d'utilisateur dans la session ?
|
||||
* On tente de récupérer une nouvelle session avec un jeton. */
|
||||
$myUser = User::existAuthToken();
|
||||
$_SESSION['currentUser'] = serialize($myUser);
|
||||
}
|
||||
|
||||
$feedManager = new Feed();
|
||||
$eventManager = new Event();
|
||||
$folderManager = new Folder();
|
||||
$configurationManager = new Configuration();
|
||||
$conf = $configurationManager->getAll();
|
||||
|
||||
//Instanciation du template
|
||||
$tpl = new RainTPL();
|
||||
//Definition des dossiers de template
|
||||
raintpl::configure("base_url", null );
|
||||
raintpl::configure("tpl_dir", './templates/'.DEFAULT_THEME.'/' );
|
||||
raintpl::configure("cache_dir", "./cache/tmp/" );
|
||||
|
||||
i18n_init(LANGUAGE);
|
||||
if ($resultUpdate) die (_t('LEED_UPDATE_MESSAGE'));
|
||||
|
||||
$view = '';
|
||||
$tpl->assign('myUser',$myUser);
|
||||
$tpl->assign('feedManager',$feedManager);
|
||||
$tpl->assign('eventManager',$eventManager);
|
||||
$tpl->assign('userManager',$userManager);
|
||||
$tpl->assign('folderManager',$folderManager);
|
||||
$tpl->assign('configurationManager',$configurationManager);
|
||||
$tpl->assign('synchronisationCode',$configurationManager->get('synchronisationCode'));
|
||||
|
||||
//Récuperation et sécurisation de toutes les variables POST et GET
|
||||
$_ = array();
|
||||
foreach($_POST as $key=>$val){
|
||||
$_[$key]=Functions::secure($val, 2); // on ne veut pas d'addslashes
|
||||
}
|
||||
foreach($_GET as $key=>$val){
|
||||
$_[$key]=Functions::secure($val, 2); // on ne veut pas d'addslashes
|
||||
}
|
||||
|
||||
$tpl->assign('_',$_);
|
||||
$tpl->assign('action','');
|
||||
|
||||
//Inclusion des plugins
|
||||
Plugin::includeAll();
|
||||
// pour inclure aussi les traductions des plugins dans les js
|
||||
$tpl->assign('i18n_js',$i18n_js);
|
||||
|
||||
?>
|
5
sources/footer.php
Executable file
5
sources/footer.php
Executable file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
$tpl->assign('executionTime',number_format(microtime(true)-$start,3));
|
||||
$html = $tpl->draw($view);
|
||||
?>
|
8
sources/header.php
Executable file
8
sources/header.php
Executable file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
if(!file_exists('constant.php')) {
|
||||
header('location: install.php');
|
||||
exit();
|
||||
}
|
||||
require_once('common.php');
|
||||
|
||||
?>
|
21
sources/humans.txt
Executable file
21
sources/humans.txt
Executable file
|
@ -0,0 +1,21 @@
|
|||
/* the humans responsible & colophon */
|
||||
/* humanstxt.org */
|
||||
|
||||
|
||||
/* TEAM */
|
||||
Creator: Idleman (idleman@idleman.fr)
|
||||
Contributors: Sbgodin (http://sbgodin.fr)
|
||||
Simounet (contact@simounet.net)
|
||||
Alef-Burzmali (thomas.fargeix@burzmali.com)
|
||||
Cobalt74 (cobalt74@gmail.com)
|
||||
Site: http://blog.idleman.fr
|
||||
Twitter: none
|
||||
Location: Nowhere
|
||||
|
||||
/* THANKS */
|
||||
Names (& URL): BoilerPlate, Modernizr, jQuery, Initializr, PHP authors & chuck norris
|
||||
|
||||
/* SITE */
|
||||
Standards: HTML5, CSS3
|
||||
Components: Modernizr, jQuery
|
||||
Software: Sublime Text2
|
129
sources/i18n.php
Executable file
129
sources/i18n.php
Executable file
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: i18n
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Fonctions de gestion de la traduction
|
||||
*/
|
||||
|
||||
class Translation {
|
||||
|
||||
// Répertoire contenant les traductions
|
||||
const LOCALE_DIR = 'locale';
|
||||
|
||||
/* Langue utilisée si aucune langue n'est demandée ou si les langues
|
||||
* demandées ne sont pas disponibles. Idem pour les traductions.*/
|
||||
const DEFAULT_LANGUAGE = 'fr';
|
||||
|
||||
// tableau associatif des traductions
|
||||
var $trans = array();
|
||||
var $language = ''; // langue courante
|
||||
var $languages = array(); // langues disponibles
|
||||
|
||||
/** @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();
|
||||
$languages[]=self::DEFAULT_LANGUAGE;
|
||||
foreach ($languages as $language)
|
||||
if ($this->load($language)) {
|
||||
$this->language = $language;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Peuple la liste des langues avec une traduction */
|
||||
protected function listLanguages() {
|
||||
$this->languages = 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Charge la traduction
|
||||
* @param language la langue sélectionnée
|
||||
* @return TRUE si le chargement s'est bien fait, FALSE sinon */
|
||||
protected function load($language) {
|
||||
if (!preg_match('/^[a-z]{2}$/', $language)) {
|
||||
error_log("Invalid language: '$language'");
|
||||
return false;
|
||||
}
|
||||
$trans = $this->loadFile($language);
|
||||
if (empty($trans)) return false;
|
||||
assert('in_array($language, $this->languages)');
|
||||
if ($language!=self::DEFAULT_LANGUAGE) {
|
||||
$defaultTrans = $this->loadFile(self::DEFAULT_LANGUAGE);
|
||||
assert('!empty($defaultTrans)');
|
||||
$trans = array_merge($defaultTrans, $trans);
|
||||
}
|
||||
$this->trans = $trans;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Charge un fichier
|
||||
* @param $language Le fichier de langue concerné
|
||||
* @return Tableau associatif contenant les traductions */
|
||||
protected function loadFile($language) {
|
||||
$fileName = $this->location.'/'.self::LOCALE_DIR.'/'.$language.'.json';
|
||||
$content = @file_get_contents($fileName);
|
||||
if (empty($content)) {
|
||||
$translations = array();
|
||||
} else {
|
||||
$translations = json_decode($content, true);
|
||||
}
|
||||
return $translations;
|
||||
}
|
||||
|
||||
/* Retourne la traduction et substitue les variables.
|
||||
* get('TEST_TRANS', array('4'))
|
||||
* Retournera 'Nombre : 4' si TEST_TRANS == 'Nombre : $1' */
|
||||
function get($key, $args=array()) {
|
||||
if (isset($this->trans[$key])) {
|
||||
$value = $this->trans[$key];
|
||||
for($i=0;$i<count($args);$i++){
|
||||
$value = str_replace('$'.($i+1), $args[$i], $value);
|
||||
}
|
||||
} else {
|
||||
$value = $key;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/* Ajoute une traduction à la suite de celle-ci.
|
||||
* Note : il faudra appeler getJson() si nécessaire */
|
||||
function append(Translation $other) {
|
||||
$this->trans = array_merge($this->trans, $other->trans);
|
||||
}
|
||||
|
||||
/* @return la version Json des traductions */
|
||||
function getJson() {
|
||||
return json_encode($this->trans);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Initialise le singleton, avec les langues possibles
|
||||
function i18n_init($languages){
|
||||
global $i18n,$i18n_js;
|
||||
if (!isset($i18n)) {
|
||||
$i18n = new Translation(dirname(__FILE__), $languages);
|
||||
$i18n_js = $i18n->getJson();
|
||||
}
|
||||
return $i18n->language;
|
||||
}
|
||||
|
||||
// Appel rapide de la traduction
|
||||
function _t($key,$args=array(),$debug=false){
|
||||
global $i18n;
|
||||
return $i18n->get($key, $args);
|
||||
}
|
||||
|
||||
|
||||
?>
|
161
sources/index.php
Executable file
161
sources/index.php
Executable file
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: index
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page d'accueil et de lecture des flux
|
||||
*/
|
||||
|
||||
require_once('header.php');
|
||||
|
||||
|
||||
Plugin::callHook("index_pre_treatment", array(&$_));
|
||||
|
||||
//Récuperation de l'action (affichage) demandée
|
||||
$action = (isset($_['action'])?$_['action']:'');
|
||||
$tpl->assign('action',$action);
|
||||
//Récuperation des dossiers de flux par ordre de nom
|
||||
$tpl->assign('folders',$folderManager->populate('name'));
|
||||
//Recuperation de tous les non Lu
|
||||
$tpl->assign('unread',$feedManager->countUnreadEvents());
|
||||
//recuperation de tous les flux
|
||||
$allFeeds = $feedManager->getFeedsPerFolder();
|
||||
$tpl->assign('allFeeds',$allFeeds);
|
||||
//recuperation de tous les flux par dossier
|
||||
$tpl->assign('allFeedsPerFolder',$allFeeds['folderMap']);
|
||||
//recuperation de tous les event nons lu par dossiers
|
||||
$tpl->assign('allEvents',$eventManager->getEventCountPerFolder());
|
||||
|
||||
|
||||
$articleDisplayContent = $configurationManager->get('articleDisplayContent');
|
||||
$articleView = $configurationManager->get('articleView');
|
||||
$articlePerPages = $configurationManager->get('articlePerPages');
|
||||
$articleDisplayLink = $configurationManager->get('articleDisplayLink');
|
||||
$articleDisplayDate = $configurationManager->get('articleDisplayDate');
|
||||
$articleDisplayAuthor = $configurationManager->get('articleDisplayAuthor');
|
||||
$articleDisplayHomeSort = $configurationManager->get('articleDisplayHomeSort');
|
||||
$articleDisplayFolderSort = $configurationManager->get('articleDisplayFolderSort');
|
||||
$displayOnlyUnreadFeedFolder = $configurationManager->get('displayOnlyUnreadFeedFolder');
|
||||
if (!isset($displayOnlyUnreadFeedFolder)) $displayOnlyUnreadFeedFolder=false;
|
||||
($displayOnlyUnreadFeedFolder=='true')?$displayOnlyUnreadFeedFolder_reverse='false':$displayOnlyUnreadFeedFolder_reverse='true';
|
||||
$optionFeedIsVerbose = $configurationManager->get('optionFeedIsVerbose');
|
||||
|
||||
$tpl->assign('articleDisplayContent',$configurationManager->get('articleDisplayContent'));
|
||||
$tpl->assign('articleView',$configurationManager->get('articleView'));
|
||||
$tpl->assign('articlePerPages',$configurationManager->get('articlePerPages'));
|
||||
$tpl->assign('articleDisplayLink',$configurationManager->get('articleDisplayLink'));
|
||||
$tpl->assign('articleDisplayDate',$configurationManager->get('articleDisplayDate'));
|
||||
$tpl->assign('articleDisplayAuthor',$configurationManager->get('articleDisplayAuthor'));
|
||||
$tpl->assign('articleDisplayHomeSort',$configurationManager->get('articleDisplayHomeSort'));
|
||||
$tpl->assign('articleDisplayFolderSort',$configurationManager->get('articleDisplayFolderSort'));
|
||||
$tpl->assign('displayOnlyUnreadFeedFolder',$displayOnlyUnreadFeedFolder);
|
||||
$tpl->assign('displayOnlyUnreadFeedFolder_reverse',$displayOnlyUnreadFeedFolder_reverse);
|
||||
|
||||
$target = MYSQL_PREFIX.'event.title,'.MYSQL_PREFIX.'event.unread,'.MYSQL_PREFIX.'event.favorite,'.MYSQL_PREFIX.'event.feed,';
|
||||
if($articleDisplayContent && $articleView=='partial') $target .= MYSQL_PREFIX.'event.description,';
|
||||
if($articleDisplayContent && $articleView!='partial') $target .= MYSQL_PREFIX.'event.content,';
|
||||
$target .= MYSQL_PREFIX.'event.link,';
|
||||
if($articleDisplayDate) $target .= MYSQL_PREFIX.'event.pubdate,';
|
||||
if($articleDisplayAuthor) $target .= MYSQL_PREFIX.'event.creator,';
|
||||
$target .= MYSQL_PREFIX.'event.id';
|
||||
|
||||
$tpl->assign('target',$target);
|
||||
$tpl->assign('feeds','');
|
||||
$tpl->assign('order','');
|
||||
$tpl->assign('unreadEventsForFolder','');
|
||||
$pagesArray = array();
|
||||
|
||||
switch($action){
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER */
|
||||
case 'selectedFeed':
|
||||
$currentFeed = $feedManager->getById($_['feed']);
|
||||
$tpl->assign('currentFeed',$currentFeed);
|
||||
$numberOfItem = $eventManager->rowCount(array('feed'=>$currentFeed->getId()));
|
||||
$allowedOrder = array('date'=>'pubdate DESC','older'=>'pubdate','unread'=>'unread DESC,pubdate DESC');
|
||||
$order = (isset($_['order'])?$allowedOrder[$_['order']]:$allowedOrder['date']);
|
||||
$page = (isset($_['page'])?$_['page']:1);
|
||||
$pages = ceil($numberOfItem/$articlePerPages);
|
||||
$startArticle = ($page-1)*$articlePerPages;
|
||||
$events = $currentFeed->getEvents($startArticle,$articlePerPages,$order,$target);
|
||||
|
||||
$tpl->assign('order',(isset($_['order'])?$_['order']:''));
|
||||
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER en mode non lus */
|
||||
case 'selectedFeedNonLu':
|
||||
$currentFeed = $feedManager->getById($_['feed']);
|
||||
$tpl->assign('currentFeed',$currentFeed);
|
||||
$filter = array('unread'=>1, 'feed'=>$currentFeed->getId());
|
||||
$numberOfItem = $eventManager->rowCount($filter);
|
||||
$order = 'pubdate DESC';
|
||||
$page = (isset($_['page'])?$_['page']:1);
|
||||
$pages = ceil($numberOfItem/$articlePerPages);
|
||||
$startArticle = ($page-1)*$articlePerPages;
|
||||
$events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$startArticle.','.$articlePerPages);
|
||||
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS D'UN DOSSIER EN PARTICULIER */
|
||||
case 'selectedFolder':
|
||||
$currentFolder = $folderManager->getById($_['folder']);
|
||||
$tpl->assign('currentFolder',$currentFolder);
|
||||
$numberOfItem = $currentFolder->unreadCount();
|
||||
$page = (isset($_['page'])?$_['page']:1);
|
||||
$pages = ceil($numberOfItem/$articlePerPages);
|
||||
$startArticle = ($page-1)*$articlePerPages;
|
||||
if($articleDisplayFolderSort) {$order = MYSQL_PREFIX.'event.pubdate desc';} else {$order = MYSQL_PREFIX.'event.pubdate asc';}
|
||||
$events = $currentFolder->getEvents($startArticle,$articlePerPages,$order,$target);
|
||||
|
||||
|
||||
break;
|
||||
/* AFFICHAGE DES EVENEMENTS FAVORIS */
|
||||
case 'favorites':
|
||||
$numberOfItem = $eventManager->rowCount(array('favorite'=>1));
|
||||
$page = (isset($_['page'])?$_['page']:1);
|
||||
$pages = ceil($numberOfItem/$articlePerPages);
|
||||
$startArticle = ($page-1)*$articlePerPages;
|
||||
$events = $eventManager->loadAllOnlyColumn($target,array('favorite'=>1),'pubdate DESC',$startArticle.','.$articlePerPages);
|
||||
$tpl->assign('numberOfItem',$numberOfItem);
|
||||
break;
|
||||
|
||||
/* AFFICHAGE DES EVENEMENTS NON LUS (COMPORTEMENT PAR DEFAUT) */
|
||||
case 'unreadEvents':
|
||||
default:
|
||||
$filter = array('unread'=>1);
|
||||
if($optionFeedIsVerbose) {
|
||||
$numberOfItem = $eventManager->rowCount($filter);
|
||||
} else {
|
||||
$numberOfItem = $eventManager->getEventCountNotVerboseFeed();
|
||||
}
|
||||
$page = (isset($_['page'])?$_['page']:1);
|
||||
$pages = ($articlePerPages>0?ceil($numberOfItem/$articlePerPages):1);
|
||||
$startArticle = ($page-1)*$articlePerPages;
|
||||
if($articleDisplayHomeSort) {$order = 'pubdate desc';} else {$order = 'pubdate asc';}
|
||||
if($optionFeedIsVerbose) {
|
||||
$events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$startArticle.','.$articlePerPages);
|
||||
} else {
|
||||
$events = $eventManager->getEventsNotVerboseFeed($startArticle,$articlePerPages,$order,$target);
|
||||
}
|
||||
$tpl->assign('numberOfItem',$numberOfItem);
|
||||
|
||||
break;
|
||||
}
|
||||
$tpl->assign('pages',$pages);
|
||||
$tpl->assign('page',$page);
|
||||
|
||||
for($i=($page-PAGINATION_SCALE<=0?1:$page-PAGINATION_SCALE);$i<($page+PAGINATION_SCALE>$pages+1?$pages+1:$page+PAGINATION_SCALE);$i++){
|
||||
$pagesArray[]=$i;
|
||||
}
|
||||
$tpl->assign('pagesArray',$pagesArray);
|
||||
$tpl->assign('previousPages',($page-PAGINATION_SCALE<0?-1:$page-PAGINATION_SCALE-1));
|
||||
$tpl->assign('nextPages',($page+PAGINATION_SCALE>$pages+1?-1:$page+PAGINATION_SCALE));
|
||||
|
||||
|
||||
Plugin::callHook("index_post_treatment", array(&$events));
|
||||
$tpl->assign('events',$events);
|
||||
$tpl->assign('time',$_SERVER['REQUEST_TIME']);
|
||||
$tpl->assign('hightlighted',0);
|
||||
$tpl->assign('scroll',false);
|
||||
|
||||
$view = 'index';
|
||||
require_once('footer.php');
|
||||
?>
|
386
sources/install.php
Executable file
386
sources/install.php
Executable file
|
@ -0,0 +1,386 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: install
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page d'installation du script (a supprimer après installation)
|
||||
*/
|
||||
|
||||
require_once('Functions.class.php');
|
||||
require_once('i18n.php');
|
||||
global $i18n;
|
||||
$install_terminee=false;
|
||||
|
||||
if (isset($_GET['lang']))
|
||||
$currentLanguage = i18n_init($_GET['lang']);
|
||||
else
|
||||
$currentLanguage = i18n_init(Functions::getBrowserLanguages());
|
||||
|
||||
$languageList = $i18n->languages;
|
||||
|
||||
if (file_exists('constant.php')) {
|
||||
die(_t('ALREADY_INSTALLED'));
|
||||
}
|
||||
|
||||
// Cookie de la session
|
||||
$cookiedir = '';
|
||||
if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
|
||||
session_set_cookie_params(0, $cookiedir);
|
||||
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__),
|
||||
'',
|
||||
'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']
|
||||
);
|
||||
}
|
||||
if (!isset($_['mysqlPrefix'])) {
|
||||
// Le formulaire n'étant pas soumis, on met cette valeur par défaut.
|
||||
$mysqlPrefix = 'leed_';
|
||||
}
|
||||
|
||||
$lib_errors = _t('ERROR');
|
||||
$lib_success = _t('SUCCESS');
|
||||
|
||||
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('mysql_connect')){
|
||||
$test[$lib_errors][] = _t('INSTALL_ERROR_MYSQLCONNECT');
|
||||
}else{
|
||||
$test[$lib_success][] = _t('INSTALL_INFO_MYSQLCONNECT');
|
||||
}
|
||||
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 (@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','Stable');
|
||||
|
||||
//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}');
|
||||
//Theme graphique
|
||||
define('DEFAULT_THEME','marigolds');
|
||||
//Nombre de pages affichées dans la barre de pagination
|
||||
define('PAGINATION_SCALE',5);
|
||||
//Nombre de flux mis à jour lors de la synchronisation graduée
|
||||
define('SYNC_GRAD_COUNT',10);
|
||||
//Langue utilisée
|
||||
define('LANGUAGE','".$_POST['install_changeLngLeed']."');
|
||||
?>";
|
||||
|
||||
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('root',$root);
|
||||
$configurationManager->add('articleView','partial');
|
||||
$configurationManager->add('articleDisplayContent','1');
|
||||
$configurationManager->add('articleDisplayAnonymous','0');
|
||||
$configurationManager->add('articlePerPages','5');
|
||||
$configurationManager->add('articleDisplayLink','1');
|
||||
$configurationManager->add('articleDisplayDate','1');
|
||||
$configurationManager->add('articleDisplayAuthor','1');
|
||||
$configurationManager->add('articleDisplayHomeSort','1');
|
||||
$configurationManager->add('articleDisplayFolderSort','1');
|
||||
$configurationManager->add('displayOnlyUnreadFeedFolder','false');
|
||||
$configurationManager->add('optionFeedIsVerbose',1);
|
||||
$configurationManager->add('synchronisationType','auto');
|
||||
$configurationManager->add('feedMaxEvents','50');
|
||||
$configurationManager->add('synchronisationCode',$synchronisationCode);
|
||||
$configurationManager->add('synchronisationEnableCache','1');
|
||||
$configurationManager->add('synchronisationForceFeed','0');
|
||||
$configurationManager->add('cryptographicSalt', $cryptographicSalt);
|
||||
|
||||
$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]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title><?php echo _t('INSTALL_TITLE') ?></title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" href="templates/marigolds/css/style.css">
|
||||
<style>
|
||||
code {
|
||||
color:#000;
|
||||
font-size: 1em;
|
||||
}
|
||||
.install h1 {
|
||||
margin-bottom: 1.3em;
|
||||
}
|
||||
.install h2 {
|
||||
margin-bottom: 0.1em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.install ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.install li {
|
||||
list-style: none outside none;
|
||||
}
|
||||
.install span {
|
||||
display: inline-block;
|
||||
width: 8em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
button#installButton {
|
||||
margin-top: 1em;
|
||||
font-size: 2em;
|
||||
}
|
||||
.message {
|
||||
color: #ffffff;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
.message li {
|
||||
border:1px solid #212121
|
||||
}
|
||||
.messageError {
|
||||
background-color: #F16529;
|
||||
}
|
||||
.messageSuccess {
|
||||
background-color: #008000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="global-wrapper">
|
||||
<div id="header-container">
|
||||
<header class="wrapper clearfix">
|
||||
<h1 class="logo" id="title"><a href="./index.php">L<i>eed</i></a></h1>
|
||||
<nav>
|
||||
</nav>
|
||||
</header>
|
||||
</div>
|
||||
<?php
|
||||
if ($install_terminee){
|
||||
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>
|
||||
';
|
||||
// écriture des balises de fin et ne pas faire la suite
|
||||
echo '</div>
|
||||
<div id="footer-container">
|
||||
<footer class="wrapper">
|
||||
<p>Leed "Light Feed" by <a target="_blank" href="http://blog.idleman.fr">Idleman</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>';
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<div id="main-container">
|
||||
<div id="main" class="wrapper clearfix">
|
||||
<div id="menuBar">
|
||||
<aside>
|
||||
<h3 class="left"><?php echo _t('INSTALL_PRE_REQUIS') ?></h3>
|
||||
<ul class="clear" style="margin:0">
|
||||
<?php
|
||||
foreach($test as $type=>$messages){
|
||||
$class = 'message ';
|
||||
$class .= $lib_errors==$type ? 'messageError':'messageSuccess';
|
||||
echo "<li class='$class'>$type :\n<ul>";
|
||||
foreach ($messages as $message){
|
||||
echo "<li>$message</li>\n";
|
||||
}
|
||||
echo "</ul></li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</aside>
|
||||
</div>
|
||||
<form action="install.php" method="POST" class="install">
|
||||
<h1><?php echo _t('INSTALL_TITLE') ?></h1>
|
||||
<h2><?php echo _t('INSTALL_TAB_GENERAL') ?></h2>
|
||||
<ul>
|
||||
<li>
|
||||
<span><?php echo _t('INSTALL_LANGUAGE') ?></span>
|
||||
<select name="install_changeLngLeed" onchange="window.location.href='install.php?lang='+this[this.selectedIndex].value">
|
||||
<?php
|
||||
foreach($languageList as $lang){
|
||||
$sel = $lang==$currentLanguage?'selected=selected':'';
|
||||
echo "<option $sel value='$lang'>$lang</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<span><?php echo _t('PROJECT_ROOT') ?></span>
|
||||
<input type="text" name="root" value="<?php echo $root; ?>">
|
||||
</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') ?>">
|
||||
</li>
|
||||
<li>
|
||||
<span><?php echo _t('LOGIN') ?></span>
|
||||
<input type="text" name="mysqlLogin" value="<?php echo $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') ?>">
|
||||
</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') ?>">
|
||||
</li>
|
||||
<li>
|
||||
<span><?php echo _t('INSTALL_PREFIX_TABLE') ?></span>
|
||||
<input type="text" name="mysqlPrefix" value="<?php echo $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') ?>">
|
||||
</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') ?>">
|
||||
</li>
|
||||
</ul>
|
||||
<button id="installButton" name="installButton"><?php echo _t('INSTALL_BTN') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
<div id="footer-container">
|
||||
<footer class="wrapper">
|
||||
<p>Leed "Light Feed" by <a target="_blank" href="http://blog.idleman.fr">Idleman</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
196
sources/locale/en.json
Executable file
196
sources/locale/en.json
Executable file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"ABOUT":"About",
|
||||
"ABOUT_LEED":"About Leed (Light Feed)",
|
||||
"ADD":"Add",
|
||||
"ADD_FEED":"Add feed",
|
||||
"ADD_FOLDER":"Add folder",
|
||||
"ADD_TO_LEED":"Add to Leed",
|
||||
"ALLOW_ANONYMOUS_READ":"Allow anonymous readers",
|
||||
"ALLOW_ANONYMOUS_READ_DESC":"NB : If you choose this option, everybody can read your feeds (without the possibility to mark them as read/unread).",
|
||||
"ALREADY_INSTALLED":"Leed is already configured. Delete or rename the configuration file.",
|
||||
"APPLICATION":"Application",
|
||||
"AT_TOTAL":"in total",
|
||||
"AUTHOR":"Author",
|
||||
"AUTOMATIC_FULL":"Complete",
|
||||
"AUTOMATIC_FULL_DESC":"The script will update automatically all your feeds, this will update all your feeds at once but can slow down the server, don't use too frequent calls in your cron",
|
||||
"AUTOMATIC_GRADUATE":"Graduated",
|
||||
"AUTOMATIC_GRADUATE_DESC":"The script will automaticaly update the oldest 10 feeds, this will relax the server and avoid too frequent timeouts, but requires more frequent calls from your cron",
|
||||
"AVAILABLES_PLUGINS":"Available plugins",
|
||||
"AVAILABLE_PLUGIN_LIST":"Installed plugins",
|
||||
"BLOG":"Blog",
|
||||
"BOOKMARKLET":"Bookmarklet",
|
||||
"BY":"by",
|
||||
"CAN_DOWNLOAD_PLUGINS":"You can download and install new plugins for free",
|
||||
"CLIC_HERE_SYNC_IMPORT":"Click here to synchronize your imported feeds.",
|
||||
"CONFIRM_DELETE_FEED":"Do you really want to delete this feed?",
|
||||
"CONFIRM_DELETE_FOLDER":"Do you really want to delete this folder? All its feeds will be also deleted.",
|
||||
"CONFIRM_MARK_ALL_AS_READ":"Mark all as read for all the feeds?",
|
||||
"CONFIRM_MARK_FEED_AS_READ":"Do you really want to mark all the news as read for this feed?",
|
||||
"CONFIRM_TRASH_EVENTS":"Do you really want to empty the events?",
|
||||
"CONTRIBUTORS":"Contributors",
|
||||
"DELETE":"Delete",
|
||||
"DISABLE":"Disable",
|
||||
"DISCONNECT":"Log out",
|
||||
"DISPLAY_ONLY_UNREAD_FEEDFOLDER":"Show/hide feeds without unread articles",
|
||||
"ENABLE":"Enable",
|
||||
"ENABLE_CACHE":"Enable caching",
|
||||
"ENABLE_CACHE_DESC":"This option allows you to disable caching. However, disabling caching may cause longer loading time.",
|
||||
"ERROR":"Errors",
|
||||
"ERRORS":"error(s)",
|
||||
"EVENT_NUMBER_PER_PAGES":"Number of articles per page",
|
||||
"EXPORT":"Export",
|
||||
"EXPORT_FEED_OPML_FORMAT":"Export feeds as opml format",
|
||||
"FABULOUS_AGREGATOR_LAUNCHED_IN":"fabulous news aggregator executed in $1 secondes by $2",
|
||||
"FAVORITES":"Favorites",
|
||||
"FAVORITES_EVENTS":"Favorite articles ($1)",
|
||||
"FAVORIZE":"Favorize",
|
||||
"FEED":"Feed",
|
||||
"FEED_MANAGING":"Feed managing",
|
||||
"FEED_OPTION":"Feed options",
|
||||
"FEED_OPTION_ISVERBOSE":"Hide selected RSS feeds from the home page:",
|
||||
"FEED_RSS_LINK":"RSS feed link ",
|
||||
"FEED_SYNCHRONISATION":"Feed synchronization",
|
||||
"FOLD":"Fold",
|
||||
"FOLDER":"Folder",
|
||||
"FOLD_UNFOLD_FOLDER":"Fold/Unfold folder",
|
||||
"FORCE_INTEGRATION":"Force integration",
|
||||
"FORCE_INTEGRATION_DESC":"RSS and Atom feeds are supposed to have specific MIME ypes to allow the softwares to identify them. Some feeds don't follow the rules (for example text/plain). By default SimplePie follows the best pratices, but you can still force the integration with this option. ",
|
||||
"FULL":"Complete",
|
||||
"FULL_SYNCHRONISATION":"Complete synchronization…",
|
||||
"GENERAL_FOLDER":"General",
|
||||
"GENERALITY":"Generality",
|
||||
"GIT_REPOSITORY":"Git repository",
|
||||
"GOOD":"good",
|
||||
"GRADUATE_SYNCHRONISATION":"Graduated synchronization",
|
||||
"HELP_H":"<strong>h</strong> show/hide the help panel",
|
||||
"HELP_H_?":"Key h show/hide the help panel",
|
||||
"HELP_K":"<strong>k</strong> previous element (opening it)",
|
||||
"HELP_L":"<strong>l</strong> mark the previous element as unread",
|
||||
"HELP_M":"<strong>m</strong> mark the selected element as read / unread",
|
||||
"HELP_N":"<strong>n</strong> next element (without opening)",
|
||||
"HELP_O_ENTER":"<strong>o</strong> or <strong>enter</strong> open selected element",
|
||||
"HELP_P":"<strong>p</strong> previous element (without opening it)",
|
||||
"HELP_S":"<strong>s</strong> mark the selected element as favorite / not favorite",
|
||||
"HELP_SPC":"<strong>espace</strong> next element (opening it)",
|
||||
"HELP_V":"<strong>v</strong> open the selected element URL",
|
||||
"HIDE_FEED_IS_VERBOSE":"Do not load on the home page",
|
||||
"HOME":"Home",
|
||||
"HOWTO_RESET_PASSWORD":"<b>To reset the password</b>, create a file <em>resetPassword</em> at the site's root. The login will always work, the provided password will replace the former one.",
|
||||
"IDENTIFIED_WITH":"Identified as $1",
|
||||
"IF_ADMIN_THEN_CONFIG":"If you are admin, you can manage access rights from the admin panel.",
|
||||
"IMPORT":"Import",
|
||||
"IMPORT_COFFEE_TIME":"NB : the import can take time, leave your browser do the job and go grab a coffee :).",
|
||||
"IMPORT_ERROR":"Errors during the import!",
|
||||
"IMPORT_FEED_ALREADY_KNOWN":"Some feeds were alreadw known, they were not imported again",
|
||||
"IMPORT_FEED_OPML_FORMAT":"Import feeds as opml format",
|
||||
"IMPORT_NO_PROBLEM":"Import successfuly done.",
|
||||
"INSTALLATION":"INSTALLATION",
|
||||
"INSTALLATION_PARAGRAPH":"<ul><li>1. Get the current version of the project from the <a href='https://github.com/ldleman/Leed.git'>GIT repository</a> or the <a href='http://projet.idleman.fr/leed/?page=Téléchargement'>archive</a></li><li>2. Place the content on your web folder and give it and its content all the read/write rights (chmod 777)</li><li>3. From your browser, navigate to the installation page (http://mysite.com/leed/install.php) and follow the instructions.</li><li>4. Once the installation is finished, delete the install.php file for security reasons.</li><li>5. Edit your cron (to access the cron file: sudo crontab -e) and place a call to the following page http://mysite.com/leed/action.php?action=synchronize&code=votre_code_synchronisation ex : <br/><code>0 * * * * wget --no-check-certificate -q -O /var/www/leed/logsCron 'http://mysite.com/leed/action.php?action=synchronize&code=votre_code_synchronisation'</code><br/>The synchronization code is indicated in <a href=settings.php#preferenceBloc>Manage > Preferences</a><br/>To update all the feeds every hour at minute 0 (do not place too frequent call to the script to allow it to takes place correctly).</li>6. The script is installed, thank you for choosing Leed, the free and svelte RSS aggregator :p.</li></ul>",
|
||||
"INSTALL_BDD":"Base",
|
||||
"INSTALL_BTN":"Start the installation",
|
||||
"INSTALL_BTN_END":"Acces to my Leed",
|
||||
"INSTALL_COMMENT_BDD":"(to be created before)",
|
||||
"INSTALL_COMMENT_HOST":"(Generally 'localhost')",
|
||||
"INSTALL_DISPLAY_CLEAR":"(will be displayed in clear)",
|
||||
"INSTALL_END":"You can customize your installation through many plugins available <a target='_blank' href='https://github.com/ldleman/Leed-market#leed-market'>Leed-market</a>.",
|
||||
"INSTALL_ERROR_CONNEXION":"Unable to connect to database",
|
||||
"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_MYSQLCONNECT":"The required function 'mysql_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)",
|
||||
"INSTALL_ERROR_SAFEMODE":"The script can not manage the timeout alone because your safe mode is enabled,<br/>in your PHP configuration file, set the max_execution_time variable to 0 or disable safemode.",
|
||||
"INSTALL_ERROR_USERPWD":"For safety, it is necessary to provide a user name and password.",
|
||||
"INSTALL_HOST":"Host",
|
||||
"INSTALL_INFO_CONNEXION":"Connecting to the database : OK",
|
||||
"INSTALL_INFO_FILEGET":"Requested function 'file_get_contents' : OK",
|
||||
"INSTALL_INFO_FILEPUT":"Requested function 'file_put_contents' : OK",
|
||||
"INSTALL_INFO_MYSQLCONNECT":"Requested function 'mysql_connect' : OK",
|
||||
"INSTALL_INFO_PHPV":"Php version compatibility ($1) : OK",
|
||||
"INSTALL_INFO_RIGHT":"Permissions on the current folder: OK ",
|
||||
"INSTALL_INFO_SAFEMODE":"Management timeout: OK",
|
||||
"INSTALL_LANGUAGE":"Language",
|
||||
"INSTALL_PREFIX_TABLE":"Table prefix",
|
||||
"INSTALL_PRE_REQUIS":"Prerequisites for installation",
|
||||
"INSTALL_TAB_ADMIN":"Administrator",
|
||||
"INSTALL_TAB_BDD":"Database",
|
||||
"INSTALL_TAB_GENERAL":"General",
|
||||
"INSTALL_TITLE":"Installing Leed",
|
||||
"INSTALL_TITLE_END":"Leed Installation Complete!",
|
||||
"IN_FIRST":"first",
|
||||
"KEEP_LAST_X_EVENTS_FEED":"Keep the last $1 events of a feed",
|
||||
"KEEP_LAST_X_EVENTS_FEED_DESC":"NB : To keep a better performance, we suggest you to keep the last 50 events at most. Notice that events marked as favorites will never be deleted.",
|
||||
"LAUNCH_SYNCHRONISATION":"Start a manual synchronization",
|
||||
"LEED_UPDATE_MESSAGE":"Leed has been updated. Refresh the page to return to your Leed.",
|
||||
"LET_EMPTY_IF_NO_PASS_CHANGE":"Leave this part empty if you don't want to change your password.",
|
||||
"LET_SLASH_AT_END":"Leave a '/' at the end of the URL, example : http://mysite.com/leed/",
|
||||
"LIBRARIES":"LIBRARIES",
|
||||
"LIBRARIES_PARAGRAPHE":"<ul><li><b>Responsive / Cross browser :</b> Initializr (<a href='http://www.initializr.com'>http://www.initializr.com</a>)</li><li><b>Javascript :</b> JQuery (<a href='http://www.jquery.com'>http://www.jquery.com</a>)</li><li><b>PHP Template :</b> RainTPL (<a href='http://www.raintpl.com'>http://www.raintpl.com</a>)</li><li><b>RSS parser :</b> SimplePie (<a href='http://simplepie.org'>http://simplepie.org</a>)</li></ul>",
|
||||
"LICENCE":"LICENCE",
|
||||
"LOADING":"Loading...",
|
||||
"LOGIN":"Username",
|
||||
"MAIL":"E-mail",
|
||||
"MANAGE":"Manage",
|
||||
"MANUAL_FEED_UPDATE":"Manual feed update",
|
||||
"MARK_ALL_AS_READ":"Mark all as read",
|
||||
"MARK_AS_READ":"Mark as read",
|
||||
"MARK_AS_READ_FOLDER_ITEMS":"mark as read the first $1 unread events of this folder",
|
||||
"NAME":"Name",
|
||||
"NEW_FOLDER":"New folder",
|
||||
"NO":"No",
|
||||
"NO_INSTALLED_PLUGINS":"There is no installed plugin yet.",
|
||||
"OLDER":"oldest",
|
||||
"OPML_FILE":"OPML File",
|
||||
"PARTIAL":"Partial",
|
||||
"PASSWORD":"Password",
|
||||
"PENDING":"In progress...",
|
||||
"PLUGINS":"Plugins",
|
||||
"PLUGINS_INSTALLED":"Plugins configuration",
|
||||
"PREFERENCES":"Preferences",
|
||||
"PRESENTATION":"PRESENTATION",
|
||||
"PRESENTATION_PARAGRAPH":"<b>Leed (contraction of Light Feed)</b> is a minimalistic RSS feed aggregator which allows quick and non-intrusive reading of feeds.</p><p> All the tasks are done silently with a scheduled task (Cron), thus the user is not faced with the slow down due to the retrieveing and processing of the feeds.</p><p> Leed is compatible with all monitors' resolution, desktop computers, tablets and smartphones and accessible from all the browsers.</p><p> The script is also compatible with OPML import/export, which makes easier the migration from aggregators respecting the OPML standard.",
|
||||
"PROJECT_PAGE":"Project page",
|
||||
"PROJECT_ROOT":"Project root",
|
||||
"QUESTIONS_SUGGESTIONS":"QUESTIONS & SUGGESTIONS",
|
||||
"QUESTIONS_SUGGESTIONS_PARAGRAPH":"<ul><li><b>For any question and suggestion:</b> Check first whether the answer is present in the <a href='http://projet.idleman.fr/leed/?page=FAQ'>FAQ</a> or <a href='http://projet.idleman.fr/leed'>the projects' wiki</a>, if not send me your questions/suggestions at <a href='mailto:idleman@idleman.fr'>idleman@idleman.fr</a></li><li><b>To reset the password</b>, create a file <em>resetPassword</em> at the site's root. The login will always work, the provided password will replace the former one.</li></ul>",
|
||||
"READ":"Read",
|
||||
"READ_ALL_FOLDER_CONFIRM":"Mark all as read for this folder?",
|
||||
"READ_FOLDER_ITEMS":"Read events from this folder",
|
||||
"REMEMBER_ME":"Remember me",
|
||||
"RENAME":"Rename",
|
||||
"RETURN_TO_TOP":"Return to top",
|
||||
"SAVE":"Save",
|
||||
"SECONDS":"secondes",
|
||||
"SEE_EVENTS_FOR_FOLDER":"All unread events for folder $1",
|
||||
"SEE_THE":"See the",
|
||||
"SHOW_EVENT_AUTHOR":"Show the author of the article",
|
||||
"SHOW_EVENT_CONTENT":"Show the content of the article",
|
||||
"SHOW_EVENT_DATE":"Show the date of the article",
|
||||
"SHOW_EVENT_LINK":"Show direct link to the article",
|
||||
"SHOW_PARTIAL_CONTENT_DESC":"NB : if you choose partial, a click on the article will redirect to the authors' blog.",
|
||||
"SITE":"Website",
|
||||
"SORT_BY_RECENT_EVENT_FOLDER":"Most recent articles first (in folders)",
|
||||
"SORT_BY_RECENT_EVENT_HOME":"Most recent articles first (on the home page)",
|
||||
"SUCCESS":"Success",
|
||||
"SYNCHRONISATION":"Synchronization",
|
||||
"SYNCHRONISATION_CODE":"Synchronization code",
|
||||
"SYNCHRONISATION_COMPLETE":"Synchronization finished.",
|
||||
"SYNCHRONISATION_OPTION":"Synchronization options",
|
||||
"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",
|
||||
"TRASH_EVENTS":"Empty events",
|
||||
"UNFAVORIZE":"Unfavorize",
|
||||
"UNFOLD":"Unfold",
|
||||
"UNREAD":"Unread",
|
||||
"USER":"User",
|
||||
"USE_BOOKMARK":"Use the bookmarklet",
|
||||
"USE_BOOKMARK_DESC":"You can add the following bookmarklet to your browser, this will allow you to subscribe more rapidly to a new feed. ",
|
||||
"VERSION":"Version",
|
||||
"YES":"Yes",
|
||||
"YOU_MUST_BE_CONNECTED_ACTION":"You must be logged in for this action.",
|
||||
"YOU_MUST_BE_CONNECTED_BOOKMARK":"You must be logged in to see the bookmarklet.",
|
||||
"YOU_MUST_BE_CONNECTED_FEED":"You must be logged in to see your feeds.",
|
||||
"YOU_MUST_BE_CONNECTED_PLUGIN":"You must be logged in to see the plugins.",
|
||||
"YOU_MUST_BE_LOGGED":"You must be logged to read your feeds"
|
||||
}
|
196
sources/locale/es.json
Executable file
196
sources/locale/es.json
Executable file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"ABOUT":"Acerca de Leed",
|
||||
"ABOUT_LEED":"Acerca de Leed (Light Feed)",
|
||||
"ADD":"Añadir",
|
||||
"ADD_FEED":"Añadir un RSS",
|
||||
"ADD_FOLDER":"Añadir un directorio",
|
||||
"ADD_TO_LEED":"Añadir a Leed",
|
||||
"ALLOW_ANONYMOUS_READ":"Permitir la lectura anónima",
|
||||
"ALLOW_ANONYMOUS_READ_DESC":"NB : si usted elige esta opción, los usuarios que no han iniciado sesión seran capaz de ver sus RSS (sin ser capaz de marcarlos como leídos / no leídos).",
|
||||
"ALREADY_INSTALLED":"Leed ya está configurado. Suprimir o renombrar el archivo de configuración.",
|
||||
"APPLICATION":"Applicación",
|
||||
"AT_TOTAL":"en total",
|
||||
"AUTHOR":"Autor",
|
||||
"AUTOMATIC_FULL":"Completo",
|
||||
"AUTOMATIC_FULL_DESC":"El script actualizará automáticamente todos los RSS en una vez. Esto permite la actualización de todos los RSS en una vez pero puede ralentizar su servidor, las llamadas cron no deben ser demasiado cercanas.",
|
||||
"AUTOMATIC_GRADUATE":"Gradual",
|
||||
"AUTOMATIC_GRADUATE_DESC":"El script actualizará automáticamente los 10 RSS más antiguos. Esto permite aligerar la carga del servidor y evitar los timeouts intempestivos pero necesita llamadas cron más frecuentes para actualizar el mayor número de RSS posible.",
|
||||
"AVAILABLES_PLUGINS":"Complementos disponibles",
|
||||
"AVAILABLE_PLUGIN_LIST":"Aquí está la lista de los complementos instalados",
|
||||
"BLOG":"Blog",
|
||||
"BOOKMARKLET":"Bookmarklet",
|
||||
"BY":"por",
|
||||
"CAN_DOWNLOAD_PLUGINS":"Usted puede descargar e instalar gratis nuevos complementos",
|
||||
"CLIC_HERE_SYNC_IMPORT":"Haz clic aquí para actualisar los RSS importados.",
|
||||
"CONFIRM_DELETE_FEED":"¿ Está seguro que desea suprimir este RSS ?",
|
||||
"CONFIRM_DELETE_FOLDER":"¿ Está seguro que desea suprimir este directorio ? Va a suprimir también los RSS que él contiene.",
|
||||
"CONFIRM_MARK_ALL_AS_READ":"¿ Marcar como leído todos los RSS ?",
|
||||
"CONFIRM_MARK_FEED_AS_READ":"¿ Está seguro que desea marcar todos los eventos como leidos para este RSS ?",
|
||||
"CONFIRM_TRASH_EVENTS":"¿ Está seguro que desea suprimir todos los eventos ?",
|
||||
"CONTRIBUTORS":"Contribuidor",
|
||||
"DELETE":"Suprimir",
|
||||
"DISABLE":"Desactivar",
|
||||
"DISCONNECT":"Desconexión",
|
||||
"DISPLAY_ONLY_UNREAD_FEEDFOLDER":"Mostrar/disfrazar los RSS sin articulos no leidos",
|
||||
"ENABLE":"Activar",
|
||||
"ENABLE_CACHE":"Activar el caché",
|
||||
"ENABLE_CACHE_DESC":"Esta opción permite desactivar el caché. Sin embargo, la desactivación del caché puede llevar tiempos de cargamiento más largos.",
|
||||
"ERROR":"Errores",
|
||||
"ERRORS":"error(es)",
|
||||
"EVENT_NUMBER_PER_PAGES":"Número de articulos por página",
|
||||
"EXPORT":"Exportación ",
|
||||
"EXPORT_FEED_OPML_FORMAT":"Exportar los RSS con el formato OPML",
|
||||
"FABULOUS_AGREGATOR_LAUNCHED_IN":"fabuloso agregador ejecutado en $1 segundos por $2",
|
||||
"FAVORITES":"Favoritos",
|
||||
"FAVORITES_EVENTS":"Articulos favoritos ($1)",
|
||||
"FAVORIZE":"Marcar favorito",
|
||||
"FEED":"RSS",
|
||||
"FEED_MANAGING":"Gestión de los RSS",
|
||||
"FEED_OPTION":"Opción de los RSS",
|
||||
"FEED_OPTION_ISVERBOSE":"Disfrazar los RSS seleccionados en la portada.",
|
||||
"FEED_RSS_LINK":"Vínculo del RSS",
|
||||
"FEED_SYNCHRONISATION":"Syncronización de los RSS",
|
||||
"FOLD":"Plegar",
|
||||
"FOLDER":"Directorio",
|
||||
"FOLD_UNFOLD_FOLDER":"Plegar/Desplegar el directorio",
|
||||
"FORCE_INTEGRATION":"Forzar la integración",
|
||||
"FORCE_INTEGRATION_DESC":"Los RSS y Atom deben tener tipos MIME asociados especificados para que el script sepa de que tipo de datos se trata. Algunos RSS no siguen estas reglas (por ejemplo text/plain). SimplePie sigue las mejoras practicas por defecto, pero se puede forzar la integración con este parámetro.",
|
||||
"FULL":"Completo",
|
||||
"FULL_SYNCHRONISATION":"Syncronización completa…",
|
||||
"GENERAL_FOLDER":"General",
|
||||
"GENERALITY":"Generalidades",
|
||||
"GIT_REPOSITORY":"Repositorio Git",
|
||||
"GOOD":"bueno(s)",
|
||||
"GRADUATE_SYNCHRONISATION":"Syncronización gradual",
|
||||
"HELP_H":"<strong>h</strong> Mostrar/disfrazar el panel de ayuda",
|
||||
"HELP_H_?":"tecla h para mostrar/disfrazar el panel de ayuda",
|
||||
"HELP_K":"<strong>k</strong> elémento precedente (sin abrirlo)",
|
||||
"HELP_L":"<strong>l</strong> marcar el elemento precedente como no leído",
|
||||
"HELP_M":"<strong>m</strong> marcar el elemento seleccionado como leído / no leído",
|
||||
"HELP_N":"<strong>n</strong> elemento siguiente (sin abrirlo)",
|
||||
"HELP_O_ENTER":"<strong>o</strong> o <strong>enter</strong> abrir el elemento seleccionado",
|
||||
"HELP_P":"<strong>p</strong> elemento precedente (sin abrirlo)",
|
||||
"HELP_S":"<strong>s</strong> marcar el elemento seleccionado como favorito / no favorito",
|
||||
"HELP_SPC":"<strong>tecla de espacio</strong> elemento siguiente (y abrirlo)",
|
||||
"HELP_V":"<strong>v</strong> abre la URL del elemento seleccionado",
|
||||
"HIDE_FEED_IS_VERBOSE":"No cargar en la portada",
|
||||
"HOME":"Portada",
|
||||
"HOWTO_RESET_PASSWORD":"<b>Para reiniciar la contraseña</b>, crear un archivo <em>resetPassword</em> en la raíz del script. La connexión seguirá funcionando, la contraseña dada reemplazará la antigua.",
|
||||
"IDENTIFIED_WITH":"Identificado con $1",
|
||||
"IF_ADMIN_THEN_CONFIG":"Si usted es administrador, puede arreglar los derechos de visualización en la parte administración.",
|
||||
"IMPORT":"Importación",
|
||||
"IMPORT_COFFEE_TIME":"NB : La importación puede tomar cierto tiempo, deje su navegador y vaya tomarse un cafe. :)",
|
||||
"IMPORT_ERROR":"Errores durante la importación !",
|
||||
"IMPORT_FEED_ALREADY_KNOWN":"Algunos RSS ya estaban conocidos, no fueron importados",
|
||||
"IMPORT_FEED_OPML_FORMAT":"Importar los RSS con el formato OPML",
|
||||
"IMPORT_NO_PROBLEM":"La importación se ha pasado sin problema.",
|
||||
"INSTALLATION":"INSTALACIÓN",
|
||||
"INSTALLATION_PARAGRAPH":"<ol><li>Recuperar el proyecto sobre el <a href='https://github.com/ldleman/Leed.git'>repositorio GIT</a> de la versión actual o descarga el <a href='http://projet.idleman.fr/leed/?page=Téléchargement'>archivo</a>.</li><li>Poner el proyecto en su directorio web y aplicar un permiso chmod 777 sobre el directorio y su contenido.</li><li>Desde el navegador, ir a la página de configuración install.php (por ejemplo : http://su.sitio.fr/leed/install.php) y seguir las instrucciones.</li><li>Una vez terminada la instalación, suprimir el archivo install.php por medida de seguridad.</li><li>Establecer un cron (sudo crontab -e para abrir el archivo de cron) y poner una llamada a la página http://su.sitio.fr/leed/action.php?action=synchronize&code=su_código_de_sincronización.<br/>Por ejemplo : <br/><code>0 * * * * wget --no-check-certificate -q -O /var/www/leed/logsCron 'http://su.sitio.fr/leed/action.php?action=synchronize&code=su_código_de_sincronización'</code><br/>Se puede encontrar el código de sincronización en las <a href=settings.php#preferenceBloc>Preferencias</a><br/>para actualizar sus RSS todas las horas en el minuto 0 (se aconseja no poner una frecuencia demasiada rápida para dejar tiempo al script para ejecutarse).<li>El script está instalado, gracias por elegir Leed, el agregator RSS libre y esbelta :p.</li></ol>",
|
||||
"INSTALL_BDD":"Base",
|
||||
"INSTALL_BTN":"Empezar la instalación",
|
||||
"INSTALL_BTN_END":"Ir a mi Leed",
|
||||
"INSTALL_COMMENT_BDD":"(crearlo antes)",
|
||||
"INSTALL_COMMENT_HOST":"(En general 'localhost')",
|
||||
"INSTALL_DISPLAY_CLEAR":"(no va a ser escrito cifrado en el campo)",
|
||||
"INSTALL_END":"Puede personalizar su instancia gracias a numerosos complementos que son disponibles sobre el <a target='_blank' href='https://github.com/ldleman/Leed-market#leed-market'>Leed-market</a>.",
|
||||
"INSTALL_ERROR_CONNEXION":"No se puede conectar a la 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_MYSQLCONNECT":"Se necesita la función 'mysql_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)",
|
||||
"INSTALL_ERROR_SAFEMODE":"El script no puede administrar el timeout solo ya que el safe mode está activado,<br/> en su archivo de configuración de PHP, poner la variable max_execution_time a 0 o desactivar el safe mode.",
|
||||
"INSTALL_ERROR_USERPWD":"Por medida de seguridad, es necesario que proporzione un login y una contraseña.",
|
||||
"INSTALL_HOST":"Huésped",
|
||||
"INSTALL_INFO_CONNEXION":"Connexión a la base de datos : OK",
|
||||
"INSTALL_INFO_FILEGET":"Función necesaria 'file_get_contents' : OK",
|
||||
"INSTALL_INFO_FILEPUT":"Función necesaria 'file_put_contents' : OK",
|
||||
"INSTALL_INFO_MYSQLCONNECT":"Función necesaria 'mysql_connect' : OK",
|
||||
"INSTALL_INFO_PHPV":"Version de PHP ($1) compatible : OK",
|
||||
"INSTALL_INFO_RIGHT":"Permisos sobre el directorio corriente : OK",
|
||||
"INSTALL_INFO_SAFEMODE":"Gestión del timeout : OK",
|
||||
"INSTALL_LANGUAGE":"Idioma",
|
||||
"INSTALL_PREFIX_TABLE":"Prefijo de las tablas",
|
||||
"INSTALL_PRE_REQUIS":"Prerequisito para la instalación",
|
||||
"INSTALL_TAB_ADMIN":"Administrador",
|
||||
"INSTALL_TAB_BDD":"Base de datos",
|
||||
"INSTALL_TAB_GENERAL":"General",
|
||||
"INSTALL_TITLE":"Instalación de Leed",
|
||||
"INSTALL_TITLE_END":"Instalación de Leed terminada !",
|
||||
"IN_FIRST":"el primero",
|
||||
"KEEP_LAST_X_EVENTS_FEED":"Conservar los $1 ultimos eventos de un RSS",
|
||||
"KEEP_LAST_X_EVENTS_FEED_DESC":"NB : Cuanto más conservará eventos, más larga será la base de datos. Le aconsejamos a usted que mantenga sólo los 50 ultimos eventos al máximo para mantener una buena reactividad.<br />Los eventos marcados como favoritos no serán nunca suprimidos.",
|
||||
"LAUNCH_SYNCHRONISATION":"Lanzar una syncronisación manual",
|
||||
"LEED_UPDATE_MESSAGE":"Se ha actualizado Leed. Actualizar la página para volver a Leed.",
|
||||
"LET_EMPTY_IF_NO_PASS_CHANGE":"Deja el campo vacio si no quiere cambiar de contraseña.",
|
||||
"LET_SLASH_AT_END":"Deja un '/' en el fin de la cadena. Por ejemplo : http://monsite.com/leed/",
|
||||
"LIBRARIES":"BIBLIOTECAS",
|
||||
"LIBRARIES_PARAGRAPHE":"<ul><li><b>Responsive / Cross browser :</b> Initializr (<a href='http://www.initializr.com'>http://www.initializr.com</a>)</li><li><b>Javascript :</b> JQuery (<a href='http://www.jquery.com'>http://www.jquery.com</a>)</li><li><b>PHP Template :</b> RainTPL (<a href='http://www.raintpl.com'>http://www.raintpl.com</a>)</li><li><b>RSS parser :</b> SimplePie (<a href='http://simplepie.org'>http://simplepie.org</a>)</li></ul>",
|
||||
"LICENCE":"LICENCIA",
|
||||
"LOADING":"Cargamiento en curso…",
|
||||
"LOGIN":"Login",
|
||||
"MAIL":"E-mail",
|
||||
"MANAGE":"Gestión",
|
||||
"MANUAL_FEED_UPDATE":"Actualización manual de los RSS",
|
||||
"MARK_ALL_AS_READ":"Marcarlo todo como leído",
|
||||
"MARK_AS_READ":"Marcar como leído",
|
||||
"MARK_AS_READ_FOLDER_ITEMS":"marcar como leído el (los) $1 evento(s) no leído(s) de este directorio",
|
||||
"NAME":"Nombre",
|
||||
"NEW_FOLDER":"Nuevo directorio",
|
||||
"NO":"No",
|
||||
"NO_INSTALLED_PLUGINS":"No se ha instalado ningún complemento ya.",
|
||||
"OLDER":"Más antiguo",
|
||||
"OPML_FILE":"Archivo OPML",
|
||||
"PARTIAL":"Parcial",
|
||||
"PASSWORD":"Contraseña",
|
||||
"PENDING":"En curso…",
|
||||
"PLUGINS":"Complementos",
|
||||
"PLUGINS_INSTALLED":"Configuración de los complementos",
|
||||
"PREFERENCES":"Preferencias",
|
||||
"PRESENTATION":"PRESENTACIÓN",
|
||||
"PRESENTATION_PARAGRAPH":"<b>Leed (contracción de Light Feed)</b> es un agregator RSS minimalista que permite leer sus RSS rapidamente y facilmente.</p><p>Todas las tareas de tratamiento de los RSS se efectuan de manera invisible gracias a una tarea sincronizada (Cron). Así, el usuario no debe sufrir los largos tiempos necesarios para recuperar y tratar los RSS.</p><p>Se debe notar que Leed es compatible con todas las resoluciones, sobre un ordenador, una tablet o un móvil y funciona con todos los navegadores.</p><p>El script también está compatible con los archivos de exportación/importación OPML para permitir una migración rápida y fácil a partir de todos los agregadores que respetan el formato OPML.",
|
||||
"PROJECT_PAGE":"Página del proyecto",
|
||||
"PROJECT_ROOT":"Raíz del proyecto",
|
||||
"QUESTIONS_SUGGESTIONS":"PREGUNTAS y SUGERENCIAS",
|
||||
"QUESTIONS_SUGGESTIONS_PARAGRAPH":"<ul><li><b>Para preguntas y comentarios :</b> En un primer tiempo, asegúrese que la respuesta no está ya en las <a href='http://projet.idleman.fr/leed/?page=FAQ'>PP.FF.</a> o en <a href='http://projet.idleman.fr/leed'>el wiki del proyecto</a>. Si no es el caso, envieme su preguntas / sugerencias / comentarios sobre <a href='mailto:idleman@idleman.fr'>idleman@idleman.fr</a></li><li><b>Para reiniciar la contraseña</b>, crear un archivo <em>resetPassword</em> en la raíz del script. La connexión seguirá funcionando, la contraseña dada reemplazará la antigua.</li></ul>",
|
||||
"READ":"Leído",
|
||||
"READ_ALL_FOLDER_CONFIRM":"¿ Marcar lo todo como leído para este directorio ?",
|
||||
"READ_FOLDER_ITEMS":"Leer los eventos de este directorio",
|
||||
"REMEMBER_ME":"Recordarme",
|
||||
"RENAME":"Renombrar",
|
||||
"RETURN_TO_TOP":"Volver al principio",
|
||||
"SAVE":"Guardar",
|
||||
"SECONDS":"segundos",
|
||||
"SEE_EVENTS_FOR_FOLDER":"Todos los eventos no leidos para el directorio $1",
|
||||
"SEE_THE":"Ver los",
|
||||
"SHOW_EVENT_AUTHOR":"Mostrar el autor del artículo",
|
||||
"SHOW_EVENT_CONTENT":"Mostrar el contenido del artículo",
|
||||
"SHOW_EVENT_DATE":"Mostrar la fecha del artículo",
|
||||
"SHOW_EVENT_LINK":"Mostrar el vínculo directo del artículo",
|
||||
"SHOW_PARTIAL_CONTENT_DESC":"NB : si usted elige una visualización parcial de los articulos, un clic sobre ellos permitirá ir sobre el blog del autor.",
|
||||
"SITE":"Sitio web",
|
||||
"SORT_BY_RECENT_EVENT_FOLDER":"Articulos los más recientes en primero (en los directorios)",
|
||||
"SORT_BY_RECENT_EVENT_HOME":"Articles los más recientes en primero (en la portada)",
|
||||
"SUCCESS":"Éxito",
|
||||
"SYNCHRONISATION":"Syncronisación",
|
||||
"SYNCHRONISATION_CODE":"Código de syncronisación",
|
||||
"SYNCHRONISATION_COMPLETE":"Syncronisación terminada.",
|
||||
"SYNCHRONISATION_OPTION":"Opciones de syncronisación",
|
||||
"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. :)",
|
||||
"SYNCHRONIZE_NOW":"Syncronisar ahora",
|
||||
"TRASH_EVENTS":"Vaciar los eventos",
|
||||
"UNFAVORIZE":"Marcar no favorito",
|
||||
"UNFOLD":"Desplegar",
|
||||
"UNREAD":"No leído ",
|
||||
"USER":"Usuario",
|
||||
"USE_BOOKMARK":"Utilizar el bookmarklet",
|
||||
"USE_BOOKMARK_DESC":"Puede añadir el bookmarklet más abajo a su navegador para inscribirse más rápidamente a los RSS.",
|
||||
"VERSION":"Versión",
|
||||
"YES":"Si",
|
||||
"YOU_MUST_BE_CONNECTED_ACTION":"Usted debe haber iniciado una sesión para continuar.",
|
||||
"YOU_MUST_BE_CONNECTED_BOOKMARK":"Usted debe haber iniciado una sesión para ver el bookmarklet.",
|
||||
"YOU_MUST_BE_CONNECTED_FEED":"Usted debe haber iniciado una sesión para ver sus RSS.",
|
||||
"YOU_MUST_BE_CONNECTED_PLUGIN":"Usted debe haber iniciado una sesión para ver los complementos.",
|
||||
"YOU_MUST_BE_LOGGED":"Usted debe haber iniciado una sesión para ver sus RSS."
|
||||
}
|
196
sources/locale/fr.json
Executable file
196
sources/locale/fr.json
Executable file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"ABOUT":"À propos",
|
||||
"ABOUT_LEED":"À propos de Leed (Light Feed)",
|
||||
"ADD":"Ajouter",
|
||||
"ADD_FEED":"Ajout d’un flux",
|
||||
"ADD_FOLDER":"Ajout d’un dossier",
|
||||
"ADD_TO_LEED":"Ajouter à Leed",
|
||||
"ALLOW_ANONYMOUS_READ":"Autoriser la lecture anonyme",
|
||||
"ALLOW_ANONYMOUS_READ_DESC":"NB : si vous choisissez cette option, les utilisateurs non authentifiés pourront consulter vos flux (sans pouvoir les marquer comme lu/non lu).",
|
||||
"ALREADY_INSTALLED":"Leed est déjà configuré. Supprimez ou renommez le fichier de configuration.",
|
||||
"APPLICATION":"Application",
|
||||
"AT_TOTAL":"au total",
|
||||
"AUTHOR":"Auteur",
|
||||
"AUTOMATIC_FULL":"Complet",
|
||||
"AUTOMATIC_FULL_DESC":"Le script mettra à jour automatiquement tous vos flux en une seule fois, ceci permet la mise à jour en une fois de tous vos flux mais peut faire ramer votre serveur, les appels cron ne doivent pas être trop rapprochés.",
|
||||
"AUTOMATIC_GRADUATE":"Gradué",
|
||||
"AUTOMATIC_GRADUATE_DESC":"Le script mettra à jour automatiquement les 10 flux les plus vieux en termes de mise à jour, ceci permet d’alléger la charge serveur et d’éviter les timeouts intempestifs mais nécessite un appel de cron plus fréquent afin de mettre à jour le plus de flux possible.",
|
||||
"AVAILABLES_PLUGINS":"Plugins disponibles",
|
||||
"AVAILABLE_PLUGIN_LIST":"Voici la liste des plugins installés",
|
||||
"BLOG":"Blog",
|
||||
"BOOKMARKLET":"Bookmarklet",
|
||||
"BY":"par",
|
||||
"CAN_DOWNLOAD_PLUGINS":"Vous pouvez télécharger et installer gratuitement de nouveaux plugins",
|
||||
"CLIC_HERE_SYNC_IMPORT":"Cliquez ici pour synchroniser vos flux importés.",
|
||||
"CONFIRM_DELETE_FEED":"Êtes vous sur de vouloir supprimer ce flux ?",
|
||||
"CONFIRM_DELETE_FOLDER":"Êtes vous sur de vouloir supprimer ce dossier ? Cela supprimera tous les flux qu’il contient.",
|
||||
"CONFIRM_MARK_ALL_AS_READ":"Tout marquer comme lu pour tous les flux ?",
|
||||
"CONFIRM_MARK_FEED_AS_READ":"Êtes vous sûr de vouloir marquer tous les événements comme lus pour ce flux ?",
|
||||
"CONFIRM_TRASH_EVENTS":"Êtes vous sûr de vouloir vider tous les événements ?",
|
||||
"CONTRIBUTORS":"Contributeurs",
|
||||
"DELETE":"Supprimer",
|
||||
"DISABLE":"Désactiver",
|
||||
"DISCONNECT":"Déconnexion",
|
||||
"DISPLAY_ONLY_UNREAD_FEEDFOLDER":"Afficher/masquer les feeds sans articles non lus",
|
||||
"ENABLE":"Activer",
|
||||
"ENABLE_CACHE":"Activer le cache",
|
||||
"ENABLE_CACHE_DESC":"Cette option vous permet de désactiver la mise en cache. Cependant, la désactivation du cache peut entraîner des temps de chargement plus longs.",
|
||||
"ERROR":"Erreurs",
|
||||
"ERRORS":"erreur(s)",
|
||||
"EVENT_NUMBER_PER_PAGES":"Nombre d’articles par page",
|
||||
"EXPORT":"Export",
|
||||
"EXPORT_FEED_OPML_FORMAT":"Exporter les flux au format OPML",
|
||||
"FABULOUS_AGREGATOR_LAUNCHED_IN":"fabuleux agrégateur exécuté en $1 secondes par $2",
|
||||
"FAVORITES":"Favoris",
|
||||
"FAVORITES_EVENTS":"Articles favoris ($1)",
|
||||
"FAVORIZE":"Favoriser",
|
||||
"FEED":"Flux",
|
||||
"FEED_MANAGING":"Gestion des flux",
|
||||
"FEED_OPTION":"Option des flux",
|
||||
"FEED_OPTION_ISVERBOSE":"Cacher les flux sélectionnés de la page d'accueil :",
|
||||
"FEED_RSS_LINK":"Lien du flux RSS",
|
||||
"FEED_SYNCHRONISATION":"Synchronisation des flux",
|
||||
"FOLD":"Plier",
|
||||
"FOLDER":"Dossier",
|
||||
"FOLD_UNFOLD_FOLDER":"Plier/Déplier le dossier",
|
||||
"FORCE_INTEGRATION":"Forcer l’intégration",
|
||||
"FORCE_INTEGRATION_DESC":"Les flux RSS et Atom sont censés avoir des types MIME associés spécifiques afin que le logiciel sache quel type de données il s’agit. Certains flux ne suivent pas ces règles (par exemple text/plain). SimplePie suit les meilleures pratiques par défaut, mais vous pouvez forcer l’intégration avec ce paramètre.",
|
||||
"FULL":"Complet",
|
||||
"FULL_SYNCHRONISATION":"Synchronisation complète…",
|
||||
"GENERAL_FOLDER":"Générale",
|
||||
"GENERALITY":"Généralités",
|
||||
"GIT_REPOSITORY":"Dépôt Git",
|
||||
"GOOD":"bon(s)",
|
||||
"GRADUATE_SYNCHRONISATION":"Synchronisation graduée",
|
||||
"HELP_H":"<strong>h</strong> afficher/masquer le panneau d’aide",
|
||||
"HELP_H_?":"touche h pour afficher/masquer le panneau d’aide",
|
||||
"HELP_K":"<strong>k</strong> élément précédent (et l’ouvrir)",
|
||||
"HELP_L":"<strong>l</strong> marque l’élément précédent comme non lu",
|
||||
"HELP_M":"<strong>m</strong> marque l’élément sélectionné comme lu / non lu",
|
||||
"HELP_N":"<strong>n</strong> élément suivant (sans l’ouvrir)",
|
||||
"HELP_O_ENTER":"<strong>o</strong> ou <strong>enter</strong> ouvrir l’élément sélectionné",
|
||||
"HELP_P":"<strong>p</strong> élément précédent (sans l’ouvrir)",
|
||||
"HELP_S":"<strong>s</strong> marque l’élément sélectionné comme favori / non favori",
|
||||
"HELP_SPC":"<strong>espace</strong> élément suivant (et l’ouvrir)",
|
||||
"HELP_V":"<strong>v</strong> ouvre l’URL de l’élément sélectionné",
|
||||
"HIDE_FEED_IS_VERBOSE":"Ne pas charger sur la page d'accueil",
|
||||
"HOME":"Accueil",
|
||||
"HOWTO_RESET_PASSWORD":"<b>Pour réinitialiser le mot de passe</b>, créez un fichier <em>resetPassword</em> à la racine du site. La connexion marchera toujours, le mot de passe fourni remplacera l'ancien.",
|
||||
"IDENTIFIED_WITH":"Identifié avec $1",
|
||||
"IF_ADMIN_THEN_CONFIG":"Si vous êtes administrateur, vous pouvez régler les droits de visualisation dans la partie administration.",
|
||||
"IMPORT":"Import",
|
||||
"IMPORT_COFFEE_TIME":"NB : L’import peut prendre un certain temps, laissez votre navigateur tourner et allez vous prendre un café. :)",
|
||||
"IMPORT_ERROR":"Erreurs durant l’import !",
|
||||
"IMPORT_FEED_ALREADY_KNOWN":"Certains flux étaient déjà connus, ils n’ont pas été réimportés",
|
||||
"IMPORT_FEED_OPML_FORMAT":"Importer les flux au format OPML",
|
||||
"IMPORT_NO_PROBLEM":"L’import s’est déroulé sans problème.",
|
||||
"INSTALLATION":"INSTALLATION",
|
||||
"INSTALLATION_PARAGRAPH":"<ol><li>Récupérez le projet sur le <a href='https://github.com/ldleman/Leed.git'>dépot GIT</a> de la version courante ou en téléchargeant l’<a href='http://projet.idleman.fr/leed/?page=Téléchargement'>archive</a>.</li><li>Placez le projet dans votre répertoire web et appliquez une permission chmod 777 sur le dossier et son contenu.</li><li>Depuis votre navigateur, accédez à la page d’installation install.php (par exemple : http://votre.domaine.fr/leed/install.php) et suivez les instructions.</li><li>Une fois l’installation terminée, supprimez le fichier install.php par mesure de sécurité.</li><li>Mettez en place un cron (sudo crontab -e pour ouvrir le fichier de cron) et placez y un appel vers la page http://votre.domaine.fr/leed/action.php?action=synchronize&code=votre_code_synchronisation.<br/>Par exemple : <br/><code>0 * * * * wget --no-check-certificate -q -O /var/www/leed/logsCron 'http://votre.domaine.fr/leed/action.php?action=synchronize&code=votre_code_synchronisation'</code><br/>Le code de synchronisation est indiqué dans <a href=settings.php#preferenceBloc>Gestion > Préférences</a>.<br/>Pour mettre à jour vos flux toutes les heures à la minute 0 (il est conseillé de ne pas mettre une fréquence trop rapide pour laisser le temps au script de s’exécuter).<li>Le script est installé, merci d’avoir choisi Leed, l’agrégateur RSS libre et svelte :p.</li></ol>",
|
||||
"INSTALL_BDD":"Base",
|
||||
"INSTALL_BTN":"Lancer l'installation",
|
||||
"INSTALL_BTN_END":"Accéder à mon Leed",
|
||||
"INSTALL_COMMENT_BDD":"(à créer avant)",
|
||||
"INSTALL_COMMENT_HOST":"(Généralement 'localhost')",
|
||||
"INSTALL_DISPLAY_CLEAR":"(sera affiché en clair)",
|
||||
"INSTALL_END":"Vous pouvez personnaliser votre installation graçe à de nombreux plugins disponibles sur <a target='_blank' href='https://github.com/ldleman/Leed-market#leed-market'>Leed-market</a>.",
|
||||
"INSTALL_ERROR_CONNEXION":"Connexion impossible à la base de données.",
|
||||
"INSTALL_ERROR_FILEGET":"La fonction requise 'file_get_contents' est inaccessible sur votre serveur, verifiez votre version de PHP.",
|
||||
"INSTALL_ERROR_FILEPUT":"La fonction requise 'file_put_contents' est inaccessible sur votre serveur, verifiez votre version de PHP.",
|
||||
"INSTALL_ERROR_MYSQLCONNECT":"La fonction requise 'mysql_connect' est inaccessible sur votre serveur, verifiez vote installation de MySql.",
|
||||
"INSTALL_ERROR_PHPV":"Votre version de PHP ($1) est trop ancienne, il est possible que certaines fonctionalitees du script comportent des disfonctionnements.",
|
||||
"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)",
|
||||
"INSTALL_ERROR_SAFEMODE":"Le script ne peux pas gerer le timeout tout seul car votre safe mode est activé,<br/> dans votre fichier de configuration PHP, mettez la variable max_execution_time à 0 ou désactivez le safemode.",
|
||||
"INSTALL_ERROR_USERPWD":"Par sécurité, il est nécessaire de fournir un nom d'utilisateur et un mot de passe.",
|
||||
"INSTALL_HOST":"Hôte",
|
||||
"INSTALL_INFO_CONNEXION":"Connexion à la base de données : OK",
|
||||
"INSTALL_INFO_FILEGET":"Fonction requise 'file_get_contents' : OK",
|
||||
"INSTALL_INFO_FILEPUT":"Fonction requise 'file_put_contents' : OK",
|
||||
"INSTALL_INFO_MYSQLCONNECT":"Fonction requise 'mysql_connect' : OK",
|
||||
"INSTALL_INFO_PHPV":"Compatibilité version PHP ($1) : OK",
|
||||
"INSTALL_INFO_RIGHT":"Permissions sur le dossier courant : OK",
|
||||
"INSTALL_INFO_SAFEMODE":"Gestion du timeout : OK",
|
||||
"INSTALL_LANGUAGE":"Langue",
|
||||
"INSTALL_PREFIX_TABLE":"Préfixe des tables",
|
||||
"INSTALL_PRE_REQUIS":"Pré-requis à l'installation",
|
||||
"INSTALL_TAB_ADMIN":"Administrateur",
|
||||
"INSTALL_TAB_BDD":"Base de donnée",
|
||||
"INSTALL_TAB_GENERAL":"Général",
|
||||
"INSTALL_TITLE":"Installation de Leed",
|
||||
"INSTALL_TITLE_END":"Installation de Leed terminée !",
|
||||
"IN_FIRST":"en premier",
|
||||
"KEEP_LAST_X_EVENTS_FEED":"Conserver les $1 derniers événements d’un flux",
|
||||
"KEEP_LAST_X_EVENTS_FEED_DESC":"NB : Plus il y aura d’événements à conserver, plus votre base de données sera importante. Nous vous conseillons de garder les 50 derniers événements au maximum pour conserver une performance correcte.<br />Notez que vos événements marqués comme favoris ne seront jamais supprimés.",
|
||||
"LAUNCH_SYNCHRONISATION":"Lancer une synchronisation manuelle",
|
||||
"LEED_UPDATE_MESSAGE":"Leed à été mis à jour. Rafraîchir la page pour retourner sur votre Leed.",
|
||||
"LET_EMPTY_IF_NO_PASS_CHANGE":"Laissez le champ vide si vous ne souhaitez pas changer le mot de passe.",
|
||||
"LET_SLASH_AT_END":"Laissez bien un '/' en fin de chaine. Par exemple : http://monsite.com/leed/",
|
||||
"LIBRARIES":"LIBRAIRIES",
|
||||
"LIBRARIES_PARAGRAPHE":"<ul><li><b>Responsive / Cross browser :</b> Initializr (<a href='http://www.initializr.com'>http://www.initializr.com</a>)</li><li><b>Javascript :</b> JQuery (<a href='http://www.jquery.com'>http://www.jquery.com</a>)</li><li><b>PHP Template :</b> RainTPL (<a href='http://www.raintpl.com'>http://www.raintpl.com</a>)</li><li><b>Parseur RSS :</b> SimplePie (<a href='http://simplepie.org'>http://simplepie.org</a>)</li></ul>",
|
||||
"LICENCE":"LICENCE",
|
||||
"LOADING":"Chargement en cours…",
|
||||
"LOGIN":"Identifiant",
|
||||
"MAIL":"E-mail",
|
||||
"MANAGE":"Gestion",
|
||||
"MANUAL_FEED_UPDATE":"Mise à jour manuelle des flux",
|
||||
"MARK_ALL_AS_READ":"Tout marquer comme lu",
|
||||
"MARK_AS_READ":"Marquer comme lu",
|
||||
"MARK_AS_READ_FOLDER_ITEMS":"marquer comme lu le(s) $1 evenement(s) non lu(s) de ce dossier",
|
||||
"NAME":"Nom",
|
||||
"NEW_FOLDER":"Nouveau dossier",
|
||||
"NO":"Non",
|
||||
"NO_INSTALLED_PLUGINS":"Aucun plugin n’est installé pour le moment.",
|
||||
"OLDER":"Plus vieux",
|
||||
"OPML_FILE":"Fichier OPML",
|
||||
"PARTIAL":"Partiel",
|
||||
"PASSWORD":"Mot de passe",
|
||||
"PENDING":"En cours…",
|
||||
"PLUGINS":"Plugins",
|
||||
"PLUGINS_INSTALLED":"Configuration des plugins",
|
||||
"PREFERENCES":"Préférences",
|
||||
"PRESENTATION":"PRÉSENTATION",
|
||||
"PRESENTATION_PARAGRAPH":"<b>Leed (contraction de Light Feed)</b> est un agrégateur RSS minimaliste qui permet la consultation de flux RSS de manière rapide et non intrusive.</p><p>Toutes les tâches de traitement de flux sont effectuées de manière invisible par une tâche planifiée (Cron). Ainsi, l’utilisateur ne subit pas les lenteurs dues à la récupération et au traitement de chacun des flux suivis.</p><p>À noter que Leed est compatible toutes résolutions, sur pc, tablettes et smartphones et fonctionne avec tous les navigateurs.</p><p>Le script est également compatible avec les fichiers d’export/import OPML ce qui rend la migration de tous les agrégateurs respectant le standard OPML simple et rapide.",
|
||||
"PROJECT_PAGE":"Page projet",
|
||||
"PROJECT_ROOT":"Racine du projet",
|
||||
"QUESTIONS_SUGGESTIONS":"QUESTIONS & SUGGESTIONS",
|
||||
"QUESTIONS_SUGGESTIONS_PARAGRAPH":"<ul><li><b>Pour toutes questions et remarques:</b> Vérifiez dans un premier temps que la réponse ne se trouve pas dans la <a href='http://projet.idleman.fr/leed/?page=FAQ'>FAQ</a> ou sur <a href='http://projet.idleman.fr/leed'>le wiki du projet</a>, si ce n’est pas le cas, envoyez moi vos questions/suggestions/remarques sur <a href='mailto:idleman@idleman.fr'>idleman@idleman.fr</a></li><li><b>Pour réinitialiser le mot de passe</b>, créez un fichier <em>resetPassword</em> à la racine du site. La connexion marchera toujours, le mot de passe fourni remplacera l'ancien.</li></ul>",
|
||||
"READ":"Lu",
|
||||
"READ_ALL_FOLDER_CONFIRM":"Tout marquer comme lu pour ce dossier ?",
|
||||
"READ_FOLDER_ITEMS":"Lire les événements de ce dossier",
|
||||
"REMEMBER_ME":"Se souvenir de moi",
|
||||
"RENAME":"Renommer",
|
||||
"RETURN_TO_TOP":"Revenir en haut de page",
|
||||
"SAVE":"Enregistrer",
|
||||
"SECONDS":"secondes",
|
||||
"SEE_EVENTS_FOR_FOLDER":"Tous les événements non lus pour le dossier $1",
|
||||
"SEE_THE":"Voir les",
|
||||
"SHOW_EVENT_AUTHOR":"Affichage de l’auteur de l’article",
|
||||
"SHOW_EVENT_CONTENT":"Affichage du contenu de l’article",
|
||||
"SHOW_EVENT_DATE":"Affichage de la date de l’article",
|
||||
"SHOW_EVENT_LINK":"Affichage du lien direct de l’article",
|
||||
"SHOW_PARTIAL_CONTENT_DESC":"NB : si vous choissisez un affichage partiel des articles, un clic sur ces derniers mènera à l’article sur le blog de l’auteur.",
|
||||
"SITE":"Site web",
|
||||
"SORT_BY_RECENT_EVENT_FOLDER":"Articles les plus récents en premier (sur les dossiers)",
|
||||
"SORT_BY_RECENT_EVENT_HOME":"Articles les plus récents en premier (sur la page d’accueil)",
|
||||
"SUCCESS":"Succès",
|
||||
"SYNCHRONISATION":"Synchronisation",
|
||||
"SYNCHRONISATION_CODE":"Code de synchronisation",
|
||||
"SYNCHRONISATION_COMPLETE":"Synchronisation terminée.",
|
||||
"SYNCHRONISATION_OPTION":"Options de synchronisation",
|
||||
"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é. :)",
|
||||
"SYNCHRONIZE_NOW":"Synchroniser maintenant",
|
||||
"TRASH_EVENTS":"Vider les événements",
|
||||
"UNFAVORIZE":"Défavoriser",
|
||||
"UNFOLD":"Déplier",
|
||||
"UNREAD":"Non lu",
|
||||
"USER":"Utilisateur",
|
||||
"USE_BOOKMARK":"Utiliser le bookmarklet",
|
||||
"USE_BOOKMARK_DESC":"Vous pouvez ajouter le bookmarklet ci-dessus à votre navigateur pour vous inscrire plus rapidement aux flux.",
|
||||
"VERSION":"Version",
|
||||
"YES":"Oui",
|
||||
"YOU_MUST_BE_CONNECTED_ACTION":"Vous devez être connecté pour effecuer cette action.",
|
||||
"YOU_MUST_BE_CONNECTED_BOOKMARK":"Vous devez être connecté pour voir le bookmarklet.",
|
||||
"YOU_MUST_BE_CONNECTED_FEED":"Vous devez être connecté pour voir vos flux.",
|
||||
"YOU_MUST_BE_CONNECTED_PLUGIN":"Vous devez être connecté pour voir les plugins.",
|
||||
"YOU_MUST_BE_LOGGED":"Vous devez être connecté pour consulter vos flux"
|
||||
}
|
1
sources/logs/.htaccess
Executable file
1
sources/logs/.htaccess
Executable file
|
@ -0,0 +1 @@
|
|||
deny from all
|
0
sources/plugins/index.html
Executable file
0
sources/plugins/index.html
Executable file
35
sources/settings.php
Executable file
35
sources/settings.php
Executable file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
@nom: settings
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page de gestion de toutes les préférences/configurations administrateur
|
||||
*/
|
||||
|
||||
require_once('header.php');
|
||||
|
||||
|
||||
|
||||
$tpl->assign('feeds',$feedManager->populate('name'));
|
||||
$tpl->assign('folders',$folderManager->populate('name'));
|
||||
$tpl->assign('synchronisationType',$configurationManager->get('synchronisationType'));
|
||||
$tpl->assign('synchronisationEnableCache',$configurationManager->get('synchronisationEnableCache'));
|
||||
$tpl->assign('synchronisationForceFeed',$configurationManager->get('synchronisationForceFeed'));
|
||||
$tpl->assign('articleDisplayAnonymous', $configurationManager->get('articleDisplayAnonymous'));
|
||||
$tpl->assign('articleDisplayLink', $configurationManager->get('articleDisplayLink'));
|
||||
$tpl->assign('articleDisplayDate', $configurationManager->get('articleDisplayDate'));
|
||||
$tpl->assign('articleDisplayAuthor', $configurationManager->get('articleDisplayAuthor'));
|
||||
$tpl->assign('articleDisplayHomeSort', $configurationManager->get('articleDisplayHomeSort'));
|
||||
$tpl->assign('articleDisplayFolderSort', $configurationManager->get('articleDisplayFolderSort'));
|
||||
$tpl->assign('articleDisplayContent', $configurationManager->get('articleDisplayContent'));
|
||||
$tpl->assign('articleView', $configurationManager->get('articleView'));
|
||||
$tpl->assign('optionFeedIsVerbose', $configurationManager->get('optionFeedIsVerbose'));
|
||||
|
||||
//Suppression de l'état des plugins inexistants
|
||||
Plugin::pruneStates();
|
||||
|
||||
//Récuperation des plugins
|
||||
$tpl->assign('plugins',Plugin::getAll());
|
||||
|
||||
$view = "settings";
|
||||
require_once('footer.php'); ?>
|
57
sources/templates/marigolds/about.html
Executable file
57
sources/templates/marigolds/about.html
Executable file
|
@ -0,0 +1,57 @@
|
|||
{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="http://creativecommons.org/licenses/by-nc-sa/2.0/fr/">CC by-nc-sa</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"}
|
72
sources/templates/marigolds/article.html
Executable file
72
sources/templates/marigolds/article.html
Executable file
|
@ -0,0 +1,72 @@
|
|||
{loop="$events"}
|
||||
{$plainDescription=strip_tags($value->getDescription())}
|
||||
|
||||
<!-- CORPS ARTICLE -->
|
||||
|
||||
{function="Plugin::callHook("event_pre_section", array(&$value))"}
|
||||
<section id="{$value->getId()}" 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" 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">{$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}
|
||||
|
||||
<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="$articleDisplayContent"}
|
||||
<div class="articleContent">
|
||||
{if="$articleView=='partial'"}
|
||||
{function="Plugin::callHook("event_pre_description", array(&$value))"}
|
||||
{$value->getDescription()}
|
||||
{function="Plugin::callHook("event_post_description", array(&$value))"}
|
||||
{else}
|
||||
{function="Plugin::callHook("event_pre_content", array(&$value))"}
|
||||
{$value->getContent()}
|
||||
{function="Plugin::callHook("event_post_content", array(&$value))"}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{if="$articleView!='partial'"}
|
||||
<!-- RAPPEL DETAILS + OPTIONS POUR LES ARTICLES AFFICHES EN ENTIER -->
|
||||
<h3 class="articleDetails">
|
||||
{function="Plugin::callHook("event_pre_bottom_options", array(&$value))"}
|
||||
|
||||
<a class="pointer right readUnreadButton">(lu/non lu)</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>
|
||||
{/if}
|
||||
{/if}
|
||||
</section>
|
||||
{function="Plugin::callHook("event_post_section", array(&$value))"}
|
||||
{$hightlighted=$hightlighted+1}
|
||||
{/loop}
|
||||
{if="$scroll && $events"}<div class='scriptaddbutton'><script>addEventsButtonLuNonLus();</script></div>{/if}
|
812
sources/templates/marigolds/css/style.css
Executable file
812
sources/templates/marigolds/css/style.css
Executable file
|
@ -0,0 +1,812 @@
|
|||
/* =============================================================================
|
||||
HTML5 Boilerplate CSS: h5bp.com/css
|
||||
========================================================================== */
|
||||
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
|
||||
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
|
||||
audio:not([controls]) { display: none; }
|
||||
[hidden] { display: none; }
|
||||
|
||||
html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
|
||||
html, button, input, select, textarea { font-family: sans-serif; color: #222; }
|
||||
body { margin: 0; font-size: 1em; line-height: 1.4; }
|
||||
|
||||
::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
|
||||
::selection { background: #fe57a1; color: #fff; text-shadow: none; }
|
||||
|
||||
a { color: #00e; }
|
||||
a:visited { color: #551a8b; }
|
||||
a:hover { color: #06e; }
|
||||
|
||||
|
||||
|
||||
|
||||
a:focus { outline: thin dotted; }
|
||||
a:hover, a:active { outline: 0; }
|
||||
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
b, strong { font-weight: bold; }
|
||||
blockquote { margin: 1em 40px; }
|
||||
dfn { font-style: italic; }
|
||||
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
|
||||
ins { background: #ff9; color: #000; text-decoration: none; }
|
||||
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
|
||||
pre, code, kbd, samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; }
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
q { quotes: none; }
|
||||
q:before, q:after { content: ""; content: none; }
|
||||
small { font-size: 85%; }
|
||||
|
||||
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
sup { top: -0.5em; }
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
|
||||
dd { margin: 0 0 0 40px; }
|
||||
nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
|
||||
|
||||
img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
|
||||
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
|
||||
figure { margin: 0; }
|
||||
|
||||
form { margin: 0; }
|
||||
fieldset { border: 1px solid #CCCCCC; margin: 0; padding: 5px; }
|
||||
label { cursor: pointer; }
|
||||
legend { border: 0; *margin-left: -7px; padding: 5px; white-space: normal; }
|
||||
button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
|
||||
button, input { line-height: normal; }
|
||||
button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; *overflow: visible; }
|
||||
button[disabled], input[disabled] { cursor: default; }
|
||||
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; margin: 0 5px 0 10px; padding: 0; *width: 13px; *height: 13px; }
|
||||
input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
|
||||
input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
|
||||
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
||||
textarea { overflow: auto; vertical-align: top; resize: vertical; }
|
||||
input:valid, textarea:valid { }
|
||||
input:invalid, textarea:invalid { background-color: #f0dddd; }
|
||||
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
td { vertical-align: top; }
|
||||
|
||||
.chromeframe { margin: 0.2em 0; background: #ccc; color: black; padding: 0.2em 0; }
|
||||
|
||||
|
||||
/* ===== Initializr Styles =====================================================
|
||||
Author: Jonathan Verrecchia - verekia.com/initializr/responsive-template
|
||||
========================================================================== */
|
||||
|
||||
body{ font:16px/26px Helvetica, Helvetica Neue, Arial; }
|
||||
|
||||
.wrapper{
|
||||
width:96%;
|
||||
margin:0 2%;
|
||||
}
|
||||
|
||||
/* ===================
|
||||
ALL: Orange Theme
|
||||
=================== */
|
||||
|
||||
html, body { position: relative; height: 100%; }
|
||||
.global-wrapper {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
#header-container{ border-bottom: 5px solid #e44d26; }
|
||||
#footer-container{ position: absolute; width: 100%; bottom: 0; border-top: 5px solid #e44d26; }
|
||||
#main aside { border-top: 5px solid #e44d26; }
|
||||
|
||||
#header-container,
|
||||
#footer-container,
|
||||
#main aside{
|
||||
background:#222222;
|
||||
}
|
||||
|
||||
#main aside{
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#title{ color:#ffffff; }
|
||||
|
||||
::-moz-selection { background: #f16529; color: #fff; text-shadow: none; }
|
||||
::selection { background: #f16529; color: #fff; text-shadow: none; }
|
||||
|
||||
/* ==============
|
||||
MOBILE: Menu
|
||||
============== */
|
||||
|
||||
code{
|
||||
padding:5px;
|
||||
color:#f16529;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
display:block;
|
||||
margin:5px;
|
||||
font-size:12px;
|
||||
font-family:Courier,Verdana,Arial;
|
||||
background:#FFEBE2;
|
||||
}
|
||||
|
||||
nav a{
|
||||
display:block;
|
||||
margin-bottom:10px;
|
||||
background:#e44d26;
|
||||
color:#ffffff;
|
||||
text-align:center;
|
||||
text-decoration:none;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
nav a.synchronyzeButton{
|
||||
cursor:pointer;
|
||||
font-size:40px;
|
||||
}
|
||||
|
||||
nav a:hover, nav a:visited{
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
nav a:hover, nav a:visited{
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
header a,header a:hover,header a:visited{
|
||||
text-decoration:none;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
/* ==============
|
||||
MOBILE: Main
|
||||
============== */
|
||||
|
||||
#main{
|
||||
padding:15px 0 45px;
|
||||
}
|
||||
|
||||
#main article a.goTopButton{
|
||||
background-color:#CECECE;
|
||||
border:0px;
|
||||
color:#ffffff;
|
||||
padding:10px 5px 0px 5px;
|
||||
line-height: 5px;
|
||||
float:right;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#main button, .loginBloc button,.button,.readUnreadButton{
|
||||
background-color:#f16529;
|
||||
border:0px;
|
||||
color:#ffffff;
|
||||
text-decoration:none;
|
||||
padding:3px 8px 3px 8px;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
min-width: 35px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.readUnreadButton{
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
line-height:20px;
|
||||
}
|
||||
|
||||
#main aside a.unreadForFolder,#main aside a.readFolder{
|
||||
|
||||
background-color:#F16529;
|
||||
border:0px;
|
||||
color:#ffffff;
|
||||
margin:3px 3px 3px 0px;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
padding:0px 3px 0px 3px;
|
||||
line-height: 20px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
min-width:55px;
|
||||
display:block;
|
||||
text-align: center;
|
||||
float:right;
|
||||
}
|
||||
|
||||
#main aside a.readFolder{
|
||||
background-color:#222222;
|
||||
margin-left:3px;
|
||||
min-width: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#main aside ul li h1.folder{
|
||||
text-align:left;
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
.loginBloc span{
|
||||
color:#fff;
|
||||
margin-right:5px;
|
||||
padding:0;
|
||||
display:inline;
|
||||
}
|
||||
.loginBloc span span{
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#main .aside a button a{
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#main article header.articleHead{
|
||||
|
||||
padding:5px;
|
||||
background-color:#222222;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
#main article div.articleContent{
|
||||
|
||||
margin:10px 0px 0px 0px;
|
||||
text-align: justify;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
#main article header h1.articleSection{
|
||||
font-size:1em;
|
||||
color:#ffffff;
|
||||
margin:0px;
|
||||
float:left;
|
||||
margin-right:10px;
|
||||
}
|
||||
#main article section h2 a{
|
||||
text-decoration:none;
|
||||
color: #222222;
|
||||
cursor: pointer;
|
||||
}
|
||||
#main article header h1 a{
|
||||
text-decoration:none;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
}
|
||||
#main article section h2.articleTitle, .preferenceBloc h3{
|
||||
margin-bottom:5px;
|
||||
font-size:1.1em;
|
||||
}
|
||||
#main article section h3.articleDetails, .preferenceBloc h4{
|
||||
font-size:10px;
|
||||
font-weight:normal;
|
||||
color:#939393;
|
||||
margin:0px;
|
||||
}
|
||||
#main article section .articleDetails .readUnreadButton,
|
||||
#main article section .articleDetails .readUnreadButton:hover
|
||||
{
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#main article div.articleContent .enclosure{
|
||||
color:#F16529;
|
||||
display:block;
|
||||
font-size: 10px;
|
||||
}
|
||||
#main article div.articleContent .enclosure h1{
|
||||
color:#222222;
|
||||
margin:5px 0 0 0;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
#main article div.articleContent .enclosure a{
|
||||
|
||||
color:#F16529;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#main article div.articleContent .enclosure span{
|
||||
padding:5px 0 5px 0;
|
||||
color:#707070;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
|
||||
#main article section img{
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
#main article section embed,#main article section iframe{
|
||||
max-width: 100%;
|
||||
|
||||
}
|
||||
#main aside ul,#main aside ul li ul{
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
#main aside ul li ul li{
|
||||
list-style-type:none;
|
||||
padding:0 5px 0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#main aside ul li {
|
||||
list-style-type:none;
|
||||
}
|
||||
#main aside ul li h1 {
|
||||
font-size:1em;
|
||||
padding:0px;
|
||||
margin:3px;
|
||||
text-align:center;
|
||||
background-color:#666666;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.favorite:before{
|
||||
content: "✰ ";
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.favorite{
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
.importFrame{
|
||||
border:none;
|
||||
}
|
||||
|
||||
|
||||
.logo{
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAwCAYAAAB9sggoAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAB3ZJREFUeNrEWQlMFFcYZpdly3KWq1yGgmIqUA6L1tpIUVugNtGkBmtJGhOjFm2atonYVkQSNZF6kKImLSXUKFGBllgKKFCghKMKuICwqywEEJVzF+RmOZal36MzZBxnz4K85MvOm3fMN//73/f/b5ZnampqslRleHg4eGZmZr1KpeLPzs4+GRoaeujn59eBJrWusTxDiOFBC9e2trba+h2am5v7gsfjvclum5qaymtqaooNDQ1tQlW1JMRQt8LvGKNdBEK/Az6wULtarZ7A/B7ASpC0YUw13d/f/+2qVatScK1cTGJWQDwQDGLbyIPIzcHBwUQsV19HR0elWCzumZiYmLW2thb4+vo6+fv7R1pYWHzC5/M96Em6urqi0PYnJzlCTF+MjY0R7AY6gbmBgQE57u8FPFEPbmxsfAvXtppQU1MTDuLVZCzB6Oio4vDhw25oM2c/yxBSbwB/0ZPS8PDwOIj2bbCQPYPEK6b/FR4DpJjfuXPnPZB7QI+Hdb+mxvCYz+PrsXxWQAIuG4EwdvvmzZudhULhqxs2bBgkdZlMZo8lTcPDFRinhlWl7e3t0WRxgMmQkJAquVx+Dn44QfpjqT+gpjJjzsvXQepj/DwAvgeEXH2CgoJcpqenzfEgx97eXidnZ+cj2HlKSMR9OP9TgUDg6+Dg8DPafkJ3ETB79OjRTIz5m3KlFdRUAp3EQMgbyMflTcBDG3lPT8/X5ncRj6eGz4wcOHDgRGRkZAx23M76+vrdIFlA2kUi0b6GhoaPyAtmZ2crR0ZGblFWM+XiwmcREgEnqGX7UJ+d6u7u7kIryOrVqxVZWVmTlZWVM5hnbuvWrQ9TUlIOQmTLSQcXF5dIyvICyIkYxJ7gt5NrXj6D1A5q2eIpk+tV7OzsnKhLolNzwAgFoi3DcXFxXbDUd1jWDiybG9VXCELdQC82QDF1b445rwCEvPCbBOwwJNzgbdVw6vulpaX3aItxPYCoO/xLBquJQY4WQp6jo6MI9bGLFy9mUPdmniNGPeR9+IhBvOA/5bGxsbmQiSGG6HKWgICASZBQNjc3X6FuqbEpAvr6+tKTkpLGuYjxodz96enpvxlCqqCg4OaWLVvS7t69OwhL0BaSaVluC6xMBeKjhNSrq6tFiApKHx+fW1SXiRcsjXW3JuotkUga2OLJBejUQysrq31kjKWl5T68VAaCshS7LIWIMJc4KxSKFQzxNcPSOtL1U6dOWWLc28DngJCt/OvXrl37FQLriC5ily5d+oUKQ3tbWloKWe1DgDsHOT4hkZub64j2UIjvN21tbenPnj2T0GOxrNnos4aKEAuidg9xzi41NfXqlyja1rGkpITkUybr1q2zdXNzC2c1kw1wCIijdjqRnCAS7LEDg/BA73nHFghMnJycTBDQFwaePHlSip+NFNKYatt07Ngxd4SMisDAwBBNxODE874AjarV0MWecZ3PTBaec24GKSxtW3JychtVJS8+yxTYp0BDVFTUDSh4vyZimzZtmg8hZ8+eJY7MRS6TshZf392UkZFxi1GVcYWkOuRI0vPnz/9KdIprkoiIiI0MvdoFFNAvDuzFLi+bFy+V6l19SGHTyBMSEhqpqgLo0RQrZdCWZoSVAq6JvLy8AmH2UKICIPGIJIoAD3AFrtChDX70gz7EiouLiyYnJ9VsydGUwfrb2Ni8g1ASb29vv4LdCEeewWZJx04+BDITrHjrh58fuVIkjvx/HHPEYJWmqFtX6YOKJj+QwMRSZJfJcHYVR9ZrhnTns56enuzW1tadILMS8CWHEDRf14cUKVVVVaUMUveYpydtOT8JMbuuXbsWsX379t2LfbQjLxwWFnYEIY2On9fps4OuRJGcfqr2799f1N3d3bzYxBAtahikGpmkdGawZDwcUxodHZ2KjFO5mMQuXLhQwJYIQ4iRUlteXj6QmZl5Q58HIsx0Itzc19bn8ePHEsxHJ4jtwLgxxIjzlyFS/YPYKGY2wJqjhASyjSyElHPe3t4HISfxly9fztchqMXMVeHqI9DT8uSt7Pfs2XMVSzAolUof3b59uxUa1G/oEuIE1X369GkJfeYF5P+HGCliOKxNeHj4uK6Orq6uGr9J5OXl5WvzLWOI0WZ/na2T1FsrKMhx1vyUa7BSqRxG1ltNazHwZFGIQUB7oPR/4HINTQL3Rl/YLbW1nOJYUVFRAuFWafMtYy1GyJEcv0rrpAKBkCOMTSNbLWPcatE2B99kCYqZmZk5+15dXV0F4itt3XrC9aUTg3X47KNeYmJiEeOWzkiyJMTIp83ntKa9vTE/P1/O2InKZSEmEomsmfW0tLRCXYL6UogxC8nnSeLJSN+Hlo0YlnJBLnJycor0EdSXQgwnoPmPcOPj4wPHjx8XM/L5zmUlBh2bl4uysrISrnx+2YhBHngkf4uJiSllJQLLS4zoWE1NTRkjn68l32OXnZhQKLQ4c+ZMiTFOb3Ss1KcUFhYWIeu1pKoPYK1pQ+cw+i8bbQUZSDD5XkdVs+gMRNv/T/+LmAHFgfp0mgMMGDMBbwn/FnQwlhQp/wowAPxkPsdZ4yiuAAAAAElFTkSuQmCC) 0 center no-repeat;
|
||||
padding-left:60px;
|
||||
padding-top:15px;
|
||||
height:40px;
|
||||
font-size:3em;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.loginBloc{
|
||||
background-color: #222222;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
float: none;
|
||||
margin: 10px 0px 10px;
|
||||
padding: 5px;
|
||||
width: auto;
|
||||
}
|
||||
.loginBloc input{
|
||||
width:100px;
|
||||
border:none;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
margin-right:1%;
|
||||
|
||||
}
|
||||
|
||||
#rememberMe span{
|
||||
color:#ccc;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#rememberMe input{
|
||||
margin-left: 10px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.logo i{
|
||||
font-size:0.7em;
|
||||
}
|
||||
|
||||
#main aside ul li ul li:hover{
|
||||
background-color:#333333;
|
||||
}
|
||||
|
||||
.feedChip{
|
||||
margin-top:9px;
|
||||
float:left;
|
||||
width:10px;
|
||||
height:10px;
|
||||
border-left:10px solid;
|
||||
}
|
||||
|
||||
#main article section {
|
||||
|
||||
}
|
||||
|
||||
#main article section.eventRead .readUnreadButton {
|
||||
/*opacity:0.8;
|
||||
-moz-opacity : 0.8;
|
||||
-ms-filter: "alpha(opacity=80)";
|
||||
*/
|
||||
background-color: #222222;
|
||||
}
|
||||
|
||||
#main article section.eventRead,#main article section.eventHightLighted.eventRead{
|
||||
background-color: #EBEBEB
|
||||
}
|
||||
|
||||
#main article section.eventHightLighted{
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
#main article section.eventSelected,
|
||||
.settings article > section{
|
||||
box-shadow: 0 0 20px 0 #C2C2C2;
|
||||
border-top: 3px solid #F16529;
|
||||
}
|
||||
#feedTable{
|
||||
width:100%;
|
||||
}
|
||||
#feedTable tr td:first{
|
||||
width:70%;
|
||||
}
|
||||
|
||||
.addBloc{
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
#main.settings aside a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.settings article > section:not(:first-child){
|
||||
display:none;
|
||||
}
|
||||
.settings .feedsList {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.settings .feedListItem {
|
||||
clear: right;
|
||||
}
|
||||
.settings .feedTitle {
|
||||
display: inline-block;
|
||||
width:45%;
|
||||
word-wrap:break-word
|
||||
}
|
||||
.settings .feedFolder,
|
||||
.settings .feedVerbose,
|
||||
.settings .feedRename,
|
||||
.settings .feedDelete {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#main.settings .feedAction {
|
||||
width: 25%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#main.settings .feedFolder {
|
||||
width: 72%;
|
||||
}
|
||||
|
||||
#main.settings .feedVerbose {
|
||||
min-width: 1em;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.settings .feedButtons {
|
||||
float: right;
|
||||
width: 28%;
|
||||
}
|
||||
#main.settings .feedRename,
|
||||
#main.settings .feedDelete {
|
||||
min-width: 7em;
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
.pointer{
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
#main article section a,#main article a{
|
||||
color:#F16529;
|
||||
}
|
||||
|
||||
footer a,#main aside a{
|
||||
color:#FFFFFF;
|
||||
text-decoration:none;
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
#main aside a span{
|
||||
font-weight:bold;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
#main article section{
|
||||
border-bottom:1px dashed #cecece;
|
||||
padding:5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#main aside{
|
||||
color:#ffffff;
|
||||
padding:0px 1% 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#main article section a.underlink, #main article a.underlink,.underlink{
|
||||
font-size:9px;
|
||||
color:#222222;
|
||||
display:block;
|
||||
line-height: 9px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#footer-container footer p,#footer-container footer{
|
||||
color:#ffffff;
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
text-align:center;
|
||||
font-size:10px;
|
||||
}
|
||||
|
||||
#footer-container footer p a,#footer-container footer p a:visited{
|
||||
font-size:10px;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
#main article section a.button {
|
||||
color:#ffffff;
|
||||
font-size:10px;
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.pluginBloc li,.pluginBloc ul{
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
padding:0px;
|
||||
}
|
||||
.pluginBloc ul li{
|
||||
padding:5px 0 5px 0;
|
||||
border-bottom: 1px dotted #cecece;
|
||||
margin:0 0 5px 0;
|
||||
}
|
||||
.pluginBloc ul li ul li{
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
margin:0;
|
||||
}
|
||||
.pluginBloc ul li ul li h4,.pluginBloc ul li ul li code{
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.errorSync{
|
||||
background-color:#C94141;
|
||||
color:#ffffff;
|
||||
padding:5px;
|
||||
border-radius:5px;
|
||||
margin:10px 0px 10px 0px;
|
||||
box-shadow: 0 0 3px 0 #810000;
|
||||
}
|
||||
|
||||
.errorSync a{
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
.sync{
|
||||
padding-left:10px;
|
||||
}
|
||||
|
||||
.sync a{
|
||||
color:#f16529;
|
||||
}
|
||||
|
||||
/* ===============
|
||||
ALL: IE Fixes
|
||||
=============== */
|
||||
|
||||
.ie7 #title{ padding-top:20px; }
|
||||
|
||||
|
||||
/* ===== Primary Styles ========================================================
|
||||
Author:
|
||||
========================================================================== */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Media Queries
|
||||
========================================================================== */
|
||||
|
||||
@media only screen and (min-width: 480px) {
|
||||
|
||||
/* ====================
|
||||
INTERMEDIATE: Menu
|
||||
==================== */
|
||||
|
||||
|
||||
|
||||
nav a{
|
||||
float:left;
|
||||
width:20%;
|
||||
margin:0 1.7%;
|
||||
padding:15px 1%;
|
||||
margin-bottom:0;
|
||||
border-bottom: 5px solid #E44D26;
|
||||
}
|
||||
|
||||
nav a:hover{
|
||||
border-bottom: 5px solid #F7BC79;
|
||||
}
|
||||
|
||||
nav li:first-child a{ margin-left:0; }
|
||||
nav li:last-child a{ margin-right:0; }
|
||||
|
||||
/* ========================
|
||||
INTERMEDIATE: IE Fixes
|
||||
======================== */
|
||||
|
||||
nav ul li{
|
||||
display:inline;
|
||||
}
|
||||
.oldie nav a{
|
||||
margin:0 0.7%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.loginBloc{
|
||||
float: left;
|
||||
width: 40%;
|
||||
margin: 15px 20px 0;
|
||||
}
|
||||
|
||||
#main{
|
||||
padding:30px 0;
|
||||
}
|
||||
|
||||
/* ====================
|
||||
WIDE: CSS3 Effects
|
||||
==================== */
|
||||
|
||||
#header-container,
|
||||
#main aside{
|
||||
-webkit-box-shadow:0 5px 10px #aaa;
|
||||
-moz-box-shadow:0 5px 10px #aaa;
|
||||
box-shadow:0 5px 10px #aaa;
|
||||
}
|
||||
|
||||
/* ============
|
||||
WIDE: Menu
|
||||
============ */
|
||||
|
||||
#title{
|
||||
float:left;
|
||||
}
|
||||
|
||||
nav{
|
||||
float:right;
|
||||
width:38%;
|
||||
}
|
||||
|
||||
/* ============
|
||||
WIDE: Main
|
||||
============ */
|
||||
|
||||
#main article{
|
||||
float:left;
|
||||
width:67%;
|
||||
}
|
||||
|
||||
#main #menuBar{
|
||||
float:right;
|
||||
width:32%;
|
||||
}
|
||||
#main #menuBar aside{
|
||||
padding:5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1140px) {
|
||||
|
||||
/* ===============
|
||||
Maximal Width
|
||||
=============== */
|
||||
|
||||
.wrapper{
|
||||
width:1026px; /* 1140px - 10% for margins */
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
#main{
|
||||
padding:30px 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
Non-Semantic Helper Classes
|
||||
========================================================================== */
|
||||
|
||||
.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; }
|
||||
.ir br { display: none; }
|
||||
.hidden { display: none !important; visibility: hidden; }
|
||||
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
|
||||
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
|
||||
.invisible { visibility: hidden; }
|
||||
.clearfix:before, .clearfix:after { content: ""; display: table; }
|
||||
.clearfix:after { clear: both; }
|
||||
.clearfix { *zoom: 1; }
|
||||
|
||||
/* =============================================================================
|
||||
Print Styles
|
||||
========================================================================== */
|
||||
|
||||
@media print {
|
||||
* { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
|
||||
a, a:visited { text-decoration: underline; }
|
||||
a[href]:after { content: " (" attr(href) ")"; }
|
||||
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
|
||||
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
||||
thead { display: table-header-group; } /* h5bp.com/t */
|
||||
tr, img { page-break-inside: avoid; }
|
||||
img { max-width: 100% !important; }
|
||||
@page { margin: 0.5cm; }
|
||||
p, h2, h3 { orphans: 3; widows: 3; }
|
||||
h2, h3 { page-break-after: avoid; }
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
Tools
|
||||
========================================================================== */
|
||||
.left{
|
||||
float:left;
|
||||
}
|
||||
.right{
|
||||
float:right;
|
||||
}
|
||||
.clear{
|
||||
clear:both;
|
||||
}
|
||||
.hidden{
|
||||
display:none;
|
||||
}
|
||||
.nochip{
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
article #loader{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
Help panel
|
||||
========================================================================== */
|
||||
#helpPanel {
|
||||
background: #333;
|
||||
opacity: 0.9;
|
||||
filter:alpha(opacity=90); /* For IE8 and earlier */
|
||||
color: #fff;
|
||||
padding: 20px;
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 500px;
|
||||
height: 21em;
|
||||
margin-top: -200px; /* moitié de la hauteur */
|
||||
margin-left: -250px; /* moitié de la largeur */
|
||||
z-Index: 1;
|
||||
display: none;
|
||||
}
|
||||
#helpPanel strong {
|
||||
color: #ff0;
|
||||
}
|
BIN
sources/templates/marigolds/favicon.png
Executable file
BIN
sources/templates/marigolds/favicon.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 828 B |
24
sources/templates/marigolds/footer.html
Executable file
24
sources/templates/marigolds/footer.html
Executable file
|
@ -0,0 +1,24 @@
|
|||
<!--
|
||||
@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_AGREGATOR_LAUNCHED_IN',array($executionTime,'<a target="_blank" 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>
|
55
sources/templates/marigolds/header.html
Executable file
55
sources/templates/marigolds/header.html
Executable file
|
@ -0,0 +1,55 @@
|
|||
<!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 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"}
|
||||
<form action="action.php?action=login" method="POST">
|
||||
<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">
|
208
sources/templates/marigolds/index.html
Executable file
208
sources/templates/marigolds/index.html
Executable file
|
@ -0,0 +1,208 @@
|
|||
{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_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;">↕</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&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&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&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&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&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&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&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&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']])"}
|
||||
<li>
|
||||
{function="Plugin::callHook("menu_pre_feed_link", array(&$value))"} <a href="index.php?action=selectedFeed&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&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 -->
|
||||
<li class="hidefeed" style="display:none;">
|
||||
{function="Plugin::callHook("menu_pre_feed_link", array(&$value))"} <a href="index.php?action=selectedFeed&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&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']])"}
|
||||
<li>
|
||||
{else} <!-- On affiche même ceux qui non pas d'article non lus -->
|
||||
<li class="hidefeed">
|
||||
{/if}
|
||||
{function="Plugin::callHook("menu_pre_feed_link", array(&$value))"} <a href="index.php?action=selectedFeed&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&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' || ($action=='selectedFeedNonLu')"}
|
||||
<!-- AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER -->
|
||||
|
||||
|
||||
<h1 class="articleSection"><a target="_blank" href="{$currentFeed->getWebSite()}">{$currentFeed->getName()}</a></h1>
|
||||
<div class="clear"></div>
|
||||
{$currentFeed->getDescription()}
|
||||
{function="_t('SEE_THE')"}
|
||||
<a href="index.php?action=selectedFeedNonLu&feed={$_['feed']}&page={$page}">{function="ucfirst(_t('UNREAD'))"}</a> |
|
||||
<a href="index.php?action=selectedFeed&feed={$_['feed']}&page={$page}&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"}
|
8
sources/templates/marigolds/js/libs/jqueryAndModernizr.min.js
vendored
Executable file
8
sources/templates/marigolds/js/libs/jqueryAndModernizr.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
645
sources/templates/marigolds/js/script.js
Executable file
645
sources/templates/marigolds/js/script.js
Executable file
|
@ -0,0 +1,645 @@
|
|||
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['space'] = 32;
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
// Page settings
|
||||
if($('.settings').length){
|
||||
|
||||
// Gestion affichage partiel ou complet en fonction de affichage du contenu
|
||||
if($("input[name='articleDisplayContent']").length){
|
||||
$("input[name='articleDisplayContent']").click(function(){
|
||||
toggleArticleView();
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
});
|
||||
|
||||
$(window).scroll(function(){
|
||||
scrollInfini();
|
||||
});
|
||||
|
||||
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())
|
||||
{
|
||||
// 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').prev(':visible'),true);
|
||||
}
|
||||
function targetNextEvent(){
|
||||
|
||||
targetThisEvent($('.eventSelected').next(':visible'),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').next(),true);
|
||||
});
|
||||
}
|
||||
|
||||
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');
|
||||
if($('.favorite',target).html()=='Favoriser'){
|
||||
addFavorite($('.favorite',target),id);
|
||||
}else{
|
||||
removeFavorite($('.favorite',target),id);
|
||||
}
|
||||
// on débloque les touches le plus tard possible afin de passer derrière l'appel ajax
|
||||
}
|
||||
|
||||
/* Fonctions de séléctions fin */
|
||||
|
||||
function toggleFolder(element,folder){
|
||||
feedBloc = $('ul',$(element).parent().parent());
|
||||
|
||||
open = 0;
|
||||
if(feedBloc.css('display')=='none') open = 1;
|
||||
feedBloc.slideToggle(200);
|
||||
$(element).html((!open?_t('UNFOLD'):_t('FOLD')));
|
||||
$.ajax({
|
||||
url: "./action.php?action=changeFolderState",
|
||||
data:{id:folder,isopen:open}
|
||||
});
|
||||
}
|
||||
|
||||
function addFavorite(element,id){
|
||||
var activeScreen = $('#pageTop').html();
|
||||
$.ajax({
|
||||
url: "./action.php?action=addFavorite",
|
||||
data:{id:id},
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
$(element).attr('onclick','removeFavorite(this,'+id+');').html(_t('UNFAVORIZE'));
|
||||
// on compte combien d'article ont été remis en favoris sur la pages favoris (scroll infini)
|
||||
if (activeScreen=='favorites') {
|
||||
$(window).data('nblus', $(window).data('nblus')-1);
|
||||
$('#nbarticle').html(parseInt($('#nbarticle').html()) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeFavorite(element,id){
|
||||
var activeScreen = $('#pageTop').html();
|
||||
$.ajax({
|
||||
url: "./action.php?action=removeFavorite",
|
||||
data:{id:id},
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
$(element).attr('onclick','addFavorite(this,'+id+');').html(_t('FAVORIZE'));
|
||||
// on compte combien d'article ont été remis en favoris sur la pages favoris (scroll infini)
|
||||
if (activeScreen=='favorites') {
|
||||
$(window).data('nblus', $(window).data('nblus')+1);
|
||||
$('#nbarticle').html(parseInt($('#nbarticle').html()) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renameFolder(element,folder){
|
||||
var folderLine = $(element).parent();
|
||||
var folderNameCase = $('span',folderLine);
|
||||
var value = folderNameCase.html();
|
||||
$(element).html('Enregistrer');
|
||||
$(element).attr('style','background-color:#0C87C9;');
|
||||
$(element).attr('onclick','saveRenameFolder(this,'+folder+')');
|
||||
folderNameCase.replaceWith('<span><input type="text" name="folderName" value="'+value+'"/></span>');
|
||||
}
|
||||
|
||||
|
||||
function saveRenameFolder(element,folder){
|
||||
var folderLine = $(element).parent();
|
||||
var folderNameCase = $('span',folderLine);
|
||||
var value = $('input',folderNameCase).val();
|
||||
$(element).html(_t('RENAME'));
|
||||
$(element).attr('style','background-color:#F16529;');
|
||||
$(element).attr('onclick','renameFolder(this,'+folder+')');
|
||||
folderNameCase.replaceWith('<span>'+value+'</span>');
|
||||
$.ajax({
|
||||
url: "./action.php?action=renameFolder",
|
||||
data:{id:folder,name:value}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function renameFeed(element,feed){
|
||||
var feedLine = $(element).parent().parent();
|
||||
var feedNameCase = feedLine.children('.js-feedTitle').children('a:nth-child(1)');
|
||||
var feedNameValue = feedNameCase.html();
|
||||
var feedUrlCase = feedLine.children('.js-feedTitle').children('a:nth-child(2)');
|
||||
var feedUrlValue = feedUrlCase.attr('href');
|
||||
var url = feedNameCase.attr('href');
|
||||
$(element).html(_t('SAVE'));
|
||||
$(element).attr('style','background-color:#0C87C9;');
|
||||
$(element).attr('onclick','saveRenameFeed(this,'+feed+',"'+url+'")');
|
||||
feedNameCase.replaceWith('<input type="text" name="feedName" value="'+feedNameValue+'" size="25" />');
|
||||
feedUrlCase.replaceWith('<input type="text" name="feedUrl" value="'+feedUrlValue+'" size="25" />');
|
||||
}
|
||||
|
||||
function saveRenameFeed(element,feed,url){
|
||||
var feedLine = $(element).parent().parent();
|
||||
var feedNameCase = feedLine.children('.js-feedTitle:first').children('input[name="feedName"]');
|
||||
var feedNameValue = feedNameCase.val();
|
||||
var feedUrlCase = feedLine.children('.js-feedTitle:first').children('input[name="feedUrl"]');
|
||||
var feedUrlValue = feedUrlCase.val();
|
||||
$(element).html('Renommer');
|
||||
$(element).attr('style','background-color:#F16529;');
|
||||
$(element).attr('onclick','renameFeed(this,'+feed+')');
|
||||
feedNameCase.replaceWith('<a href="'+url+'">'+feedNameValue+'</a>');
|
||||
feedUrlCase.replaceWith('<a class="underlink" href="'+feedUrlValue+'">'+feedUrlValue+'</a>');
|
||||
$.ajax({
|
||||
url: "./action.php?action=renameFeed",
|
||||
data:{id:feed,name:feedNameValue,url:feedUrlValue}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function changeFeedFolder(element,id){
|
||||
var value = $(element).val();
|
||||
window.location = "./action.php?action=changeFeedFolder&feed="+id+"&folder="+value;
|
||||
}
|
||||
|
||||
|
||||
function readThis(element,id,from,callback){
|
||||
var activeScreen = $('#pageTop').html();
|
||||
var parent = $(element).parent().parent();
|
||||
var nextEvent = $('#'+id).next();
|
||||
//sur les éléments non lus
|
||||
if(!parent.hasClass('eventRead')){
|
||||
$.ajax({
|
||||
url: "./action.php?action=readContent",
|
||||
data:{id:id},
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
switch (activeScreen){
|
||||
case '':
|
||||
// cas de la page d'accueil
|
||||
parent.addClass('eventRead');
|
||||
parent.fadeOut(200,function(){
|
||||
if(callback){
|
||||
callback();
|
||||
}else{
|
||||
targetThisEvent(nextEvent,true);
|
||||
}
|
||||
// on simule un scroll si tous les events sont cachés
|
||||
if($('article section:last').attr('style')=='display: none;') {
|
||||
$(window).scrollTop($(document).height());
|
||||
}
|
||||
});
|
||||
// on compte combien d'article ont été lus afin de les soustraires de la requête pour le scroll infini
|
||||
$(window).data('nblus', $(window).data('nblus')+1);
|
||||
// on diminue le nombre d'article en haut de page
|
||||
$('#nbarticle').html(parseInt($('#nbarticle').html()) - 1)
|
||||
break;
|
||||
case 'selectedFolder':
|
||||
case 'selectedFeedNonLu':
|
||||
parent.addClass('eventRead');
|
||||
if(callback){
|
||||
callback();
|
||||
}else{
|
||||
targetThisEvent(nextEvent,true);
|
||||
}
|
||||
// on compte combien d'article ont été lus afin de les soustraires de la requête pour le scroll infini
|
||||
$(window).data('nblus', $(window).data('nblus')+1);
|
||||
break;
|
||||
default:
|
||||
// autres cas : favoris, selectedFeed ...
|
||||
parent.addClass('eventRead');
|
||||
if(callback){
|
||||
callback();
|
||||
}else{
|
||||
targetThisEvent(nextEvent,true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}else{ // sur les éléments lus
|
||||
// si ce n'est pas un clic sur le titre de l'event
|
||||
if(from!='title'){
|
||||
$.ajax({
|
||||
url: "./action.php?action=unreadContent",
|
||||
data:{id:id},
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
parent.removeClass('eventRead');
|
||||
// on compte combien d'article ont été remis à non lus
|
||||
if ((activeScreen=='') || (activeScreen=='selectedFolder')|| (activeScreen=='selectedFeedNonLu'))
|
||||
$(window).data('nblus', $(window).data('nblus')-1);
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function unReadThis(element,id,from){
|
||||
var activeScreen = $('#pageTop').html();
|
||||
var parent = $(element).parent().parent();
|
||||
if(parent.hasClass('eventRead')){
|
||||
if(from!='title'){
|
||||
$.ajax({
|
||||
url: "./action.php?action=unreadContent",
|
||||
data:{id:id},
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
parent.removeClass('eventRead');
|
||||
// on compte combien d'article ont été remis à non lus
|
||||
if ((activeScreen=='') || (activeScreen=='selectedFolder')|| (activeScreen=='selectedFeedNonLu'))
|
||||
$(window).data('nblus', $(window).data('nblus')-1);
|
||||
// on augmente le nombre d'article en haut de page
|
||||
if (activeScreen=='') $('#nbarticle').html(parseInt($('#nbarticle').html()) + 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//synchronisation manuelle lancée depuis le boutton du menu
|
||||
function synchronize(code){
|
||||
if(code!=''){
|
||||
$('article').prepend('<section>'+
|
||||
'<iframe class="importFrame" src="action.php?action=synchronize&format=html&code='+code+'" name="idFrameSynchro" id="idFrameSynchro" width="100%" height="300" ></iframe>'+
|
||||
'</section>');
|
||||
}else{
|
||||
alert(_t('YOU_MUST_BE_CONNECTED_FEED'));
|
||||
}
|
||||
}
|
||||
|
||||
// Active ou desactive inputs type affichage des events
|
||||
function toggleArticleView(){
|
||||
var element = $("input[name=articleView]");
|
||||
element.prop("disabled",!element.prop("disabled"));
|
||||
}
|
||||
|
||||
// Disparition block et affichage block clique
|
||||
function toggleBlocks(target){
|
||||
target=target.substring(1);
|
||||
$('#main article > section').hide();$('.'+target).fadeToggle(200);
|
||||
}
|
||||
|
||||
// affiche ou cache les feeds n'ayant pas d'article non lus.
|
||||
function toggleUnreadFeedFolder(button,action){
|
||||
$.ajax({
|
||||
url: "./action.php?action=displayOnlyUnreadFeedFolder&displayOnlyUnreadFeedFolder="+action,
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
//Afficher ou cacher les feeds
|
||||
if(action){
|
||||
$('.hidefeed').hide();
|
||||
}else{
|
||||
$('.hidefeed').show();
|
||||
}
|
||||
//changement de l'évènement onclick pour faire l'inverse lors du prochain clic
|
||||
$(button).attr('onclick','toggleUnreadFeedFolder(this,'+!action+');');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buttonAction(target,id){
|
||||
// Check unreadEvent
|
||||
if($('#pageTop').html()){
|
||||
var from=true;
|
||||
}else{
|
||||
var from='';
|
||||
}
|
||||
readThis(target,id,from);
|
||||
}
|
||||
|
||||
|
||||
// permet de récupérer les variables passée en get dans l'URL et des les parser
|
||||
function getUrlVars()
|
||||
{
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for(var i = 0; i < hashes.length; i++)
|
||||
{
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
if (hash[1]){
|
||||
rehash = hash[1].split('#');
|
||||
vars[hash[0]] = rehash[0];
|
||||
} else {
|
||||
vars[hash[0]] = '';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
// affiche ou cache les feeds n'ayant pas d'article non lus.
|
||||
function toggleFeedVerbose(button,action,idFeed){
|
||||
$.ajax({
|
||||
url: "./action.php?action=displayFeedIsVerbose&displayFeedIsVerbose="+action+"&idFeed="+idFeed,
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
//changement de l'évènement onclick pour faire l'inverse lors du prochain clic
|
||||
var reverseaction = 0
|
||||
if (action==0) { reverseaction = 1 }
|
||||
$(button).attr('onclick','toggleFeedVerbose(this,'+reverseaction+', '+idFeed+');');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Bouton permettant l'affichage des options d'affichage et de non affichage des flux souhaités en page d'accueil
|
||||
function toggleOptionFeedVerbose(button,action){
|
||||
$.ajax({
|
||||
url: "./action.php?action=optionFeedIsVerbose&optionFeedIsVerbose="+action,
|
||||
success:function(msg){
|
||||
if(msg.status == 'noconnect') {
|
||||
alert(msg.texte)
|
||||
} else {
|
||||
if( console && console.log && msg!="" ) console.log(msg);
|
||||
//changement de l'évènement onclick pour faire l'inverse lors du prochain clic
|
||||
var reverseaction = 0
|
||||
if (action==0) { reverseaction = 1 }
|
||||
$(button).attr('onclick','toggleOptionFeedVerbose(this,'+reverseaction+');');
|
||||
//Changement du statut des cases à cocher sur les feed (afficher ou cacher)
|
||||
if (action==1){
|
||||
$('.feedVerbose').hide();
|
||||
}else{
|
||||
$('.feedVerbose').show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
318
sources/templates/marigolds/settings.html
Executable file
318
sources/templates/marigolds/settings.html
Executable file
|
@ -0,0 +1,318 @@
|
|||
{include="header"}
|
||||
|
||||
<!--
|
||||
@nom: settings
|
||||
@auteur: Idleman (idleman@idleman.fr)
|
||||
@description: Page de gestion de toutes les préférences/configurations administrateur
|
||||
-->
|
||||
|
||||
{if="($configurationManager->get('articleDisplayAnonymous')=='1') || ($myUser!=false)"}
|
||||
|
||||
|
||||
<div id="main" class="wrapper clearfix settings">
|
||||
<div id="menuBar">
|
||||
<aside>
|
||||
<h3>{function="_t('FEED_OPTION')"}</h3>
|
||||
<ul>
|
||||
<li><a class="toggle" href="#manageBloc">{function="_t('FEED_MANAGING')"}</a></li>
|
||||
<li><a class="toggle" href="#synchronizeBloc">{function="_t('MANUAL_FEED_UPDATE')"}</a></li>
|
||||
<li><a class="toggle" href="#preferenceBloc">{function="_t('PREFERENCES')"}</a></li>
|
||||
<li><a class="toggle" href="#importBloc">{function="_t('IMPORT')"}</a></li>
|
||||
<li><a class="toggle" href="#exportBloc">{function="_t('EXPORT')"}</a></li>
|
||||
<li><a class="toggle" href="#bookBloc">{function="_t('BOOKMARKLET')"}</a></li>
|
||||
<li><a class="toggle" href="#pluginBloc">{function="_t('AVAILABLES_PLUGINS')"}</a></li>
|
||||
<li class="pointer" onclick="if(confirm('{function="_t('CONFIRM_TRASH_EVENTS')"}')){window.location='action.php?action=purge';}">{function="_t('TRASH_EVENTS')"}</li>
|
||||
</ul>
|
||||
<h3>{function="_t('PLUGINS_INSTALLED')"}</h3>
|
||||
<ul>
|
||||
{function="Plugin::callHook("setting_post_link", array(&$myUser))"}
|
||||
</ul>
|
||||
</aside>
|
||||
</div>
|
||||
<article>
|
||||
|
||||
|
||||
<section class="manageBloc">
|
||||
|
||||
<h2>{function="_t('FEED_MANAGING')"} :</h2>
|
||||
|
||||
<form action="action.php?action=addFeed" method="POST">
|
||||
<section class="addBloc">
|
||||
<h3>{function="_t('ADD_FEED')"}</h3>
|
||||
<p>{function="_t('FEED_RSS_LINK')"} : <input type="text" name="newUrl" placeholder="http://monflux.com/rss"/>
|
||||
<select name="newUrlCategory">
|
||||
{loop="$folders"}
|
||||
<option {if="$value->getId()==1"}selected="selected"{/if} value="{$value->getId()}">{$value->getName()}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
<button>{function="_t('ADD')"}</button></p>
|
||||
|
||||
</section>
|
||||
</form>
|
||||
|
||||
<section class="addBloc">
|
||||
<h3>{function="_t('ADD_FOLDER')"}</h3>
|
||||
|
||||
<form method="POST" action="action.php?action=addFolder">
|
||||
{function="_t('NEW_FOLDER')"} <input type="text" name="newFolder"> <button>{function="_t('ADD')"}</button>
|
||||
</form>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="addBloc">
|
||||
<h3>{function="_t('FEED_OPTION')"}</h3>
|
||||
<span>{function="_t('FEED_OPTION_ISVERBOSE')"}</span>
|
||||
{if="$optionFeedIsVerbose==0"}
|
||||
<input class="" onclick="toggleOptionFeedVerbose(this,1)" type="checkbox" checked>
|
||||
{else}
|
||||
<input class="" onclick="toggleOptionFeedVerbose(this,0)" type="checkbox">
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<ul class="clear nochip">
|
||||
{$feedsForFolder=""}
|
||||
{loop="$folders"}
|
||||
|
||||
{$feedsForFolder=$value->getFeeds()}
|
||||
|
||||
<li>{if="$value->getId()==1"}<a id="defaultFolder"></a>{/if}
|
||||
<h1 class="folder left" ><span>{$value->getName()}</span> ({function="count($feedsForFolder)"})
|
||||
|
||||
<button onclick="renameFolder(this,{$value->getId()})">{function="_t('RENAME')"}</button>
|
||||
{if="$value->getId()!='1'"}
|
||||
<button onclick="if(confirm('{function="_t('CONFIRM_DELETE_FOLDER')"}'))window.location='action.php?action=removeFolder&id={$value->getId()}'">{function="_t('DELETE')"}</button>
|
||||
{/if}
|
||||
|
||||
<div class="clear"></div>
|
||||
</h1>
|
||||
<div class="clear"></div>
|
||||
<ul class="feedsList">
|
||||
{if="count($feeds)!=0"}
|
||||
{loop="$feedsForFolder"}
|
||||
<li class="feedListItem">
|
||||
<span class="feedTitle js-feedTitle">
|
||||
<a href="index.php?action=selectedFeed&feed={$value2->getId();}">{function="Functions::truncate($value2->getName(),40)"}</a><a href="{$value2->getUrl()}" class="underlink">{$value2->getUrl()}</a>
|
||||
</span>
|
||||
<div class="feedButtons">
|
||||
<button class="feedRename" onclick="renameFeed(this,{$value2->getId()})">{function="_t('RENAME')"}</button>
|
||||
<button class="feedDelete" onclick="if(confirm('{function="_t('CONFIRM_DELETE_FEED')"}')){window.location='action.php?action=removeFeed&id={$value2->getId()}';}">{function="_t('DELETE')"}</button>
|
||||
</div>
|
||||
<div class="feedAction"">
|
||||
<select class="feedFolder" onchange="changeFeedFolder(this,{$value2->getId()});">
|
||||
{loop="$folders"}
|
||||
<option {if="$value2->getFolder()==$value3->getId()"}selected="selected"{/if} value="{$value3->getId()}">{$value3->getName()}</option>
|
||||
{/loop}
|
||||
</select>
|
||||
{if="$optionFeedIsVerbose==0"}
|
||||
{if="$value2->getIsverbose()==0"}
|
||||
<input class="feedVerbose" onclick="toggleFeedVerbose(this,{$value2->getIsverbose()},{$value2->getId()})" type="checkbox" title="{function="_t('HIDE_FEED_IS_VERBOSE')"}">
|
||||
{else}
|
||||
<input class="feedVerbose" onclick="toggleFeedVerbose(this,{$value2->getIsverbose()},{$value2->getId()})" type="checkbox" title="{function="_t('HIDE_FEED_IS_VERBOSE')"}" checked>
|
||||
{/if}
|
||||
{else}
|
||||
{if="$value2->getIsverbose()==0"}
|
||||
<input class="feedVerbose" style="display: none;" onclick="toggleFeedVerbose(this,{$value2->getIsverbose()},{$value2->getId()})" type="checkbox" title="{function="_t('HIDE_FEED_IS_VERBOSE')"}">
|
||||
{else}
|
||||
<input class="feedVerbose" style="display: none;" onclick="toggleFeedVerbose(this,{$value2->getIsverbose()},{$value2->getId()})" type="checkbox" title="{function="_t('HIDE_FEED_IS_VERBOSE')"}" checked>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</li>
|
||||
{/loop}
|
||||
{/if}
|
||||
</ul>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="synchronizeBloc">
|
||||
<h2>{function="_t('FEED_SYNCHRONISATION')"} :</h2>
|
||||
<iframe class="importFrame" src="action.php?action=synchronizeForm" name="idFrameSynchro" id="idFrameSynchro" width="100%" height="300" ></iframe>
|
||||
</section>
|
||||
|
||||
{if="(isset($myUser)) && ($myUser!=false)"}
|
||||
<section class="preferenceBloc">
|
||||
<h2>{function="_t('PREFERENCES')"} :</h2>
|
||||
<form method="POST" action="action.php?action=updateConfiguration">
|
||||
<section>
|
||||
<h3>{function="_t('GENERALITY')"}</h3>
|
||||
<p><label for="root">{function="_t('PROJECT_ROOT')"} :</label> <input type="text" id="root" name="root" value="{$configurationManager->get('root')}"></p>
|
||||
<h4>{function="_t('LET_SLASH_AT_END')"}</h4>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>{function="_t('USER')"}</h3>
|
||||
<p><label for="login">{function="_t('LOGIN')"} :</label> <input type="text" id="login" name="login" value="{$myUser->getLogin()}"></p>
|
||||
<p><label for="password">{function="_t('PASSWORD')"} :</label> <input type="text" id="password" name="password" autocomplete="off" value="" placeholder="{function="_t('INSTALL_DISPLAY_CLEAR')"}"></p>
|
||||
<h4>{function="_t('LET_EMPTY_IF_NO_PASS_CHANGE')"}</h4>
|
||||
<h4>{function="_t('HOWTO_RESET_PASSWORD')"}</h4>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>{function="_t('SYNCHRONISATION')"}</h3>
|
||||
<p><input type="radio" {if="$synchronisationType=='auto'"} checked="checked" {/if} value="auto" id="synchronisationTypeComplete" name="synchronisationType"> <label for="synchronisationTypeComplete"><strong>
|
||||
{function="_t('AUTOMATIC_FULL')"} :</strong></label> {function="_t('AUTOMATIC_FULL_DESC')"}</p>
|
||||
<p><input type="radio" {if=" $synchronisationType=='graduate'"} checked="checked" {/if} value="graduate" id="synchronisationTypeGraduated" name="synchronisationType"> <label for="synchronisationTypeGraduated"><strong>{function="_t('AUTOMATIC_GRADUATE')"} :</strong></label> {function="_t('AUTOMATIC_GRADUATE_DESC')"}</p>
|
||||
|
||||
<p><strong>{function="_t('SYNCHRONISATION_CODE')"} :</strong>
|
||||
{$synchronisationCode}
|
||||
</p>
|
||||
<p><strong>{function="_t('SYNCHRONISATION_OPTION')"}</strong>
|
||||
<fieldset>
|
||||
<legend>{function="_t('ENABLE_CACHE')"}</legend>
|
||||
<input type="radio" {if="$synchronisationEnableCache"} checked="checked" {/if} value="1" id="synchronisationEnableCacheYes" name="synchronisationEnableCache" /><label for="synchronisationEnableCacheYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="!$synchronisationEnableCache"} checked="checked" {/if} value="0" id="synchronisationEnableCacheNo" name="synchronisationEnableCache" /><label for="synchronisationEnableCacheNo">{function="_t('NO')"}</label>
|
||||
<p>{function="_t('ENABLE_CACHE_DESC')"}</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('FORCE_INTEGRATION')"}</legend>
|
||||
<input type="radio" {if="$synchronisationForceFeed"} checked="checked" {/if} value="1" id="synchronisationForceFeedYes" name="synchronisationForceFeed" /><label for="synchronisationForceFeedYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="!$synchronisationForceFeed"} checked="checked" {/if} value="0" id="synchronisationForceFeedNo" name="synchronisationForceFeed" /><label for="synchronisationForceFeedNo">{function="_t('NO')"}</label>
|
||||
<p>{function="_t('FORCE_INTEGRATION_DESC')"}</p>
|
||||
</fieldset>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
{if="$myUser!=false"}
|
||||
<h3>{function="_t('PREFERENCES')"}</h3>
|
||||
<fieldset>
|
||||
<legend>{function="_t('ALLOW_ANONYMOUS_READ')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayAnonymous=='1'"} checked="checked" {/if} value="1" id="articleDisplayAnonymousYes" name="articleDisplayAnonymous" /><label for="articleDisplayAnonymousYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="$articleDisplayAnonymous=='0'"} checked="checked" {/if} value="0" id="articleDisplayAnonymousNo" name="articleDisplayAnonymous" /><label for="articleDisplayAnonymousNo">{function="_t('NO')"}</label>
|
||||
<h4>{function="_t('ALLOW_ANONYMOUS_READ_DESC')"}</h4>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><label for="articlePerPages">{function="_t('EVENT_NUMBER_PER_PAGES')"}</label></legend>
|
||||
<input type="text" value="{$configurationManager->get('articlePerPages')}" id="articlePerPages" name="articlePerPages" size="4" />
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SORT_BY_RECENT_EVENT_HOME')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayHomeSort"} checked="checked" {/if} value="1" id="articleDisplayHomeSortYes" name="articleDisplayHomeSort" /><label for="articleDisplayHomeSortYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="!$articleDisplayHomeSort"} checked="checked" {/if} value="0" id="articleDisplayHomeSortNo" name="articleDisplayHomeSort" /><label for="articleDisplayHomeSortNo">{function="_t('NO')"}</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SORT_BY_RECENT_EVENT_FOLDER')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayFolderSort"} checked="checked" {/if} value="1" id="articleDisplayFolderSortYes" name="articleDisplayFolderSort" /><label for="articleDisplayFolderSortYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="!$articleDisplayFolderSort"} checked="checked" {/if} value="0" id="articleDisplayFolderSorttNo" name="articleDisplayFolderSort" /><label for="articleDisplayFolderSortNo">{function="_t('NO')"}</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SHOW_EVENT_LINK')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayLink=='1'"} checked="checked" {/if}value="1" id="articleDisplayLinkYes" name="articleDisplayLink" /><label for="articleDisplayLinkYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="$articleDisplayLink=='0'"} checked="checked" {/if} value="0" id="articleDisplayLinkNo" name="articleDisplayLink" /><label for="articleDisplayLinkNo">{function="_t('NO')"}</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SHOW_EVENT_DATE')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayDate=='1'"} checked="checked" {/if} value="1" id="articleDisplayDateYes" name="articleDisplayDate" /><label for="articleDisplayDateYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="$articleDisplayDate=='0'"} checked="checked" {/if} value="0" id="articleDisplayDateNo" name="articleDisplayDate" /><label for="articleDisplayDateNo">{function="_t('NO')"}</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SHOW_EVENT_AUTHOR')"}</legend>
|
||||
<input type="radio" {if="$articleDisplayAuthor=='1'"} checked="checked" {/if} value="1" id="articleDisplayAuthorYes" name="articleDisplayAuthor" /><label for="articleDisplayAuthorYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" {if="$articleDisplayAuthor=='0'"} checked="checked" {/if} value="0" id="articleDisplayAuthorNo" name="articleDisplayAuthor" /><label for="articleDisplayAuthorNo">{function="_t('NO')"}</label>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('SHOW_EVENT_CONTENT')"}</legend>
|
||||
<input type="radio" onchange="$('.articleView').slideToggle(200);" {if="$articleDisplayContent=='1'"} checked="checked" {/if} value="1" id="articleDisplayContentYes" name="articleDisplayContent" /><label for="articleDisplayContentYes">{function="_t('YES')"}</label>
|
||||
<input type="radio" onchange="$('.articleView').slideToggle(200);" {if="$articleDisplayContent=='0'"} checked="checked" {/if} value="0" id="articleDisplayContentNo" name="articleDisplayContent" /><label for="articleDisplayContentNo">{function="_t('NO')"}</label>
|
||||
<div class="articleView"{$articleDisplayContent==0 ? 'style="display: none;"':''}>
|
||||
<input type="radio" {if="$articleView=='partial'"} checked="checked" {/if} value="partial" id="articleViewPartial" name="articleView"{if="$articleDisplayContent=='0'"} disabled="disabled"{/if} /><label for="articleViewPartial">{function="_t('PARTIAL')"}</label>
|
||||
<input type="radio" {if="$articleView=='complete'"} checked="checked" {/if} value="complete" id="articleViewComplete" name="articleView"{if="$articleDisplayContent=='0'"} disabled="disabled"{/if} /><label for="articleViewComplete">{function="_t('FULL')"}</label>
|
||||
</div>
|
||||
<h4>{function="_t('SHOW_PARTIAL_CONTENT_DESC')"}</h4>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{function="_t('KEEP_LAST_X_EVENTS_FEED',array('<input type="text" value="'.$configurationManager->get('feedMaxEvents').'" name="feedMaxEvents" size="4" />'))"}</legend>
|
||||
<h4>{function="_t('KEEP_LAST_X_EVENTS_FEED_DESC')"}</h4>
|
||||
</fieldset>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<button name="installButton">{function="_t('SAVE')"}</button>
|
||||
</form>
|
||||
{else}
|
||||
<p>{function="_t('YOU_MUST_BE_CONNECTED_BOOKMARK')"}</p>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
|
||||
<section class="importBloc">
|
||||
<h2>{function="_t('IMPORT_FEED_OPML_FORMAT')"}</h2>
|
||||
<iframe class="importFrame" src="action.php?action=importForm" name="idFrame" id="idFrame" width="100%" height="300" ></iframe>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="exportBloc">
|
||||
<form action="action.php?action=exportFeed" method="POST">
|
||||
<h2>{function="_t('EXPORT_FEED_OPML_FORMAT')"}</h2>
|
||||
<p>{function="_t('OPML_FILE')"} : <button name="exportButton">{function="_t('EXPORT')"}</button></p>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="bookBloc">
|
||||
<h2>{function="_t('USE_BOOKMARK')"} :</h2>
|
||||
{if="$myUser!=false"}
|
||||
<a class="button" href="javascript:document.location='{$configurationManager->get('root')}action.php?action=login&newUrl='+escape(document.location)+'&usr={function="$myUser->getToken()"}'">+ {function="_t('ADD_TO_LEED')"}</a>
|
||||
<p>{function="_t('USE_BOOKMARK_DESC')"}</p>
|
||||
{else}
|
||||
<p>{function="_t('YOU_MUST_BE_CONNECTED_BOOKMARK')"}</p>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section class="pluginBloc">
|
||||
<h2>{function="_t('PLUGINS')"} :</h2>
|
||||
<p>{function="_t('CAN_DOWNLOAD_PLUGINS')"} : <a href="https://github.com/ldleman/Leed-market/"> Leed Market</a>.</p>
|
||||
<h3>{function="_t('AVAILABLE_PLUGIN_LIST')"} :</h3>
|
||||
{if="$myUser!=false"}
|
||||
<ul class="pluginList">
|
||||
{if="count($plugins)==0"}
|
||||
{function="_t('NO_INSTALLED_PLUGINS')"}
|
||||
|
||||
{else}
|
||||
{loop="$plugins"}
|
||||
<li>
|
||||
<ul>
|
||||
<li><h4>{function="_t('NAME')"}: </h4>{$value->getName()}</li>
|
||||
<li><h4>{function="_t('AUTHOR')"}: </h4><a href="mailto:{$value->getMail()}">{$value->getAuthor()}</a></li>
|
||||
<li><h4>{function="_t('LICENCE')"}: </h4>{$value->getLicence()}</li>
|
||||
<li><h4>{function="_t('VERSION')"}: </h4><code>{$value->getVersion()}</code></li>
|
||||
<li><h4>{function="_t('SITE')"}: </h4><a href="{$value->getLink()}">{$value->getLink()}</a></li>
|
||||
<li>{$value->getDescription()}</li>
|
||||
<li><a href="action.php?action=changePluginState&plugin={$value->getUid()}&state={$value->getState()}" class="button">{$value->getState()=="0"?_t('ENABLE'):_t('DISABLE')}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{/loop}
|
||||
{/if}
|
||||
</ul>
|
||||
|
||||
{else}
|
||||
<p>{function="_t('YOU_MUST_BE_CONNECTED_PLUGIN')"}</p>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
{function="Plugin::callHook("setting_post_section", array(&$myUser))"}
|
||||
</article>
|
||||
|
||||
|
||||
</div> <!-- #main -->
|
||||
|
||||
{else}
|
||||
<div id="main" class="wrapper clearfix">
|
||||
<article>
|
||||
<h3>{function="_t('YOU_MUST_BE_CONNECTED_FEED')"}</h3>
|
||||
<p>{function="_t('IF_ADMIN_THEN_CONFIG')"}</p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
{include="footer"}
|
23
sources/update-1.5.sql
Executable file
23
sources/update-1.5.sql
Executable file
|
@ -0,0 +1,23 @@
|
|||
/* #############
|
||||
### MISE À JOUR Base de données de Leed pour fonctionnement en v1.5
|
||||
|
||||
Conseils :
|
||||
- Avant d'effectuer la mise à jour, sauvegardez votre BDD et exportez vos flux en OPML.
|
||||
- Attention : "leed_" est à remplacer par votre préfix de table.
|
||||
- Ce fichier est à supprimer après installation.
|
||||
|
||||
Description :
|
||||
- Les requêtes suivantes sont a exécuter sur votre Base de données Leed avec phpMyAdmin par exemple
|
||||
|
||||
############### */
|
||||
|
||||
-- Mise à jour index Table des Event
|
||||
ALTER TABLE `leed_event` ADD KEY `indexfeed` (`feed`);
|
||||
ALTER TABLE `leed_event` ADD KEY `indexunread` (`unread`);
|
||||
ALTER TABLE `leed_event` ADD KEY `indexfavorite` (`favorite`);
|
||||
|
||||
-- Mise à jour index Table des Feed
|
||||
ALTER TABLE `leed_feed` ADD KEY `indexfolder` (`folder`);
|
||||
|
||||
-- Mise à jour table Event pour la synchronisation des flux (OBLIGATOIRE)
|
||||
ALTER TABLE `leed_event` ADD `syncId` INT UNSIGNED NOT NULL;
|
85
sources/update-r93.php
Executable file
85
sources/update-r93.php
Executable file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
@set_time_limit(0);
|
||||
|
||||
/**
|
||||
* met à jour la BDD de la rev92 à la rev 93
|
||||
* Leed doit déjà être installé
|
||||
* auteur : alefburzmali
|
||||
*/
|
||||
|
||||
ob_start();
|
||||
require 'constant.php';
|
||||
|
||||
// connexion
|
||||
$mysql = new MySQLi(MYSQL_HOST,MYSQL_LOGIN,MYSQL_MDP,MYSQL_BDD);
|
||||
|
||||
$tables = array(
|
||||
'c' => MYSQL_PREFIX.'configuration',
|
||||
'e' => MYSQL_PREFIX.'event',
|
||||
'f' => MYSQL_PREFIX.'feed',
|
||||
'd' => MYSQL_PREFIX.'folder',
|
||||
'u' => MYSQL_PREFIX.'user',
|
||||
);
|
||||
|
||||
// on convertit toutes les tables
|
||||
foreach ($tables as $tb)
|
||||
{
|
||||
echo '<br>conversion de la structure de la table '.$tb.' ... ';
|
||||
ob_flush(); flush();
|
||||
if (!$mysql->query('ALTER TABLE '.$tb.' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci, ENGINE=InnoDB'))
|
||||
{
|
||||
echo 'erreur !<br>';
|
||||
print_r($mysql->error_list);
|
||||
ob_flush(); flush();
|
||||
die(1);
|
||||
}
|
||||
echo 'ok';
|
||||
}
|
||||
|
||||
// on passe la connexion en utf-8 pour traiter les données
|
||||
$mysql->query('SET NAMES utf8');
|
||||
|
||||
// maintenant on va récupérer toutes les tables pour faire html_entity_decode
|
||||
function convert($table, $champs)
|
||||
{
|
||||
global $mysql;
|
||||
echo '<br>conversion des données de la table '.$table.' ... ';
|
||||
ob_flush(); flush();
|
||||
|
||||
$res = $mysql->query('SELECT * FROM '.$table);
|
||||
if ($res)
|
||||
{
|
||||
while ($row = $res->fetch_assoc())
|
||||
{
|
||||
$sql = 'UPDATE '.$table.' SET ';
|
||||
$first = true;
|
||||
foreach ($champs as $c)
|
||||
{
|
||||
$row[$c] = html_entity_decode($row[$c]);
|
||||
$sql .= ($first?'':', '). $c .'="'.$mysql->real_escape_string($row[$c]).'"';
|
||||
$first = false;
|
||||
}
|
||||
$sql .= ' WHERE id = '.$row['id'];
|
||||
if (!$mysql->query($sql))
|
||||
{
|
||||
echo 'erreur champ '.$row['id'].'<br>';
|
||||
print_r($mysql->error_list);
|
||||
|
||||
echo '<br>on continue ... ';
|
||||
ob_flush(); flush();
|
||||
}
|
||||
}
|
||||
echo 'ok';
|
||||
$res->free();
|
||||
}
|
||||
}
|
||||
|
||||
// evenements
|
||||
convert($tables['e'], array('title','creator','content','description'));
|
||||
// feed
|
||||
convert($tables['f'], array('name','description'));
|
||||
// folder
|
||||
convert($tables['d'], array('name'));
|
||||
|
||||
echo '<br>Conversion terminée';
|
19
sources/updates/00001-Update-20140213.sql
Executable file
19
sources/updates/00001-Update-20140213.sql
Executable file
|
@ -0,0 +1,19 @@
|
|||
--######################################################################################################
|
||||
--#####
|
||||
--##### MISE À JOUR Base de données de Leed
|
||||
--##### Date : 13/02/2014
|
||||
--#####
|
||||
--##### Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
|
||||
--#####
|
||||
--##### Feature(s) :
|
||||
--##### - Option pour cacher les flux souhaités sur la page d'accueil
|
||||
--#####
|
||||
--######################################################################################################
|
||||
|
||||
-- Mise à jour table FOLDER (Obligatoire)
|
||||
ALTER TABLE `##MYSQL_PREFIX##feed` DROP `isverbose`;
|
||||
ALTER TABLE `##MYSQL_PREFIX##feed` ADD `isverbose` INT(1) NOT NULL;
|
||||
|
||||
-- évolution pour les flux RSS défini verbeux qu'il faut ou ne faut pas afficher sur la page d'accueil.
|
||||
DELETE FROM `##MYSQL_PREFIX##configuration` WHERE `key` = 'optionFeedIsVerbose';
|
||||
INSERT INTO `##MYSQL_PREFIX##configuration` (`key`,`value`) VALUES ('optionFeedIsVerbose',1);
|
Loading…
Add table
Reference in a new issue