Browse Source

git-svn-id: http://projet.idleman.fr/leed.svn@1 cbb609ad-8cd9-463b-aa97-3ec7c4f0f680

Valentin CARRUESCO 9 years ago
commit
04ba2bbed6

+ 536 - 0
.htaccess

@@ -0,0 +1,536 @@
+# Apache configuration file
+# httpd.apache.org/docs/2.2/mod/quickreference.html
+
+# Note .htaccess files are an overhead, this logic should be in your Apache config if possible
+# httpd.apache.org/docs/2.2/howto/htaccess.html
+
+# Techniques in here adapted from all over, including:
+#   Kroc Camen: camendesign.com/.htaccess
+#   perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/
+#   Sample .htaccess file of CMS MODx: modxcms.com
+
+
+###
+### If you run a webserver other than Apache, consider:
+### github.com/h5bp/server-configs
+###
+
+
+
+# ----------------------------------------------------------------------
+# Better website experience for IE users
+# ----------------------------------------------------------------------
+
+# Force the latest IE version, in various cases when it may fall back to IE7 mode
+#  github.com/rails/rails/commit/123eb25#commitcomment-118920
+# Use ChromeFrame if it's installed for a better experience for the poor IE folk
+
+<IfModule mod_headers.c>
+  Header set X-UA-Compatible "IE=Edge,chrome=1"
+  # mod_headers can't match by content-type, but we don't want to send this header on *everything*...
+  <FilesMatch "\.(js|css|gif|png|jpe?g|pdf|xml|oga|ogg|m4a|ogv|mp4|m4v|webm|svg|svgz|eot|ttf|otf|woff|ico|webp|appcache|manifest|htc|crx|oex|xpi|safariextz|vcf)$" >
+    Header unset X-UA-Compatible
+  </FilesMatch>
+</IfModule>
+
+
+# ----------------------------------------------------------------------
+# Cross-domain AJAX requests
+# ----------------------------------------------------------------------
+
+# Serve cross-domain Ajax requests, disabled by default.
+# enable-cors.org
+# code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
+
+#  <IfModule mod_headers.c>
+#    Header set Access-Control-Allow-Origin "*"
+#  </IfModule>
+
+
+# ----------------------------------------------------------------------
+# CORS-enabled images (@crossorigin)
+# ----------------------------------------------------------------------
+
+# Send CORS headers if browsers request them; enabled by default for images.
+# developer.mozilla.org/en/CORS_Enabled_Image
+# blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
+# hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
+# wiki.mozilla.org/Security/Reviews/crossoriginAttribute
+
+<IfModule mod_setenvif.c>
+  <IfModule mod_headers.c>
+    # mod_headers, y u no match by Content-Type?!
+    <FilesMatch "\.(gif|png|jpe?g|svg|svgz|ico|webp)$">
+      SetEnvIf Origin ":" IS_CORS
+      Header set Access-Control-Allow-Origin "*" env=IS_CORS
+    </FilesMatch>
+  </IfModule>
+</IfModule>
+
+
+# ----------------------------------------------------------------------
+# Webfont access
+# ----------------------------------------------------------------------
+
+# Allow access from all domains for webfonts.
+# Alternatively you could only whitelist your
+# subdomains like "subdomain.example.com".
+
+<IfModule mod_headers.c>
+  <FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css)$">
+    Header set Access-Control-Allow-Origin "*"
+  </FilesMatch>
+</IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Proper MIME type for all files
+# ----------------------------------------------------------------------
+
+
+# JavaScript
+#   Normalize to standard type (it's sniffed in IE anyways)
+#   tools.ietf.org/html/rfc4329#section-7.2
+AddType application/javascript         js
+
+# Audio
+AddType audio/ogg                      oga ogg
+AddType audio/mp4                      m4a
+
+# Video
+AddType video/ogg                      ogv
+AddType video/mp4                      mp4 m4v
+AddType video/webm                     webm
+
+# SVG
+#   Required for svg webfonts on iPad
+#   twitter.com/FontSquirrel/status/14855840545
+AddType     image/svg+xml              svg svgz
+AddEncoding gzip                       svgz
+
+# Webfonts
+AddType application/vnd.ms-fontobject  eot
+AddType application/x-font-ttf         ttf ttc
+AddType font/opentype                  otf
+AddType application/x-font-woff        woff
+
+# Assorted types
+AddType image/x-icon                        ico
+AddType image/webp                          webp
+AddType text/cache-manifest                 appcache manifest
+AddType text/x-component                    htc
+AddType application/x-chrome-extension      crx
+AddType application/x-opera-extension       oex
+AddType application/x-xpinstall             xpi
+AddType application/octet-stream            safariextz
+AddType application/x-web-app-manifest+json webapp
+AddType text/x-vcard                        vcf
+
+
+
+# ----------------------------------------------------------------------
+# Allow concatenation from within specific js and css files
+# ----------------------------------------------------------------------
+
+# e.g. Inside of script.combined.js you could have
+#   <!--#include file="libs/jquery-1.5.0.min.js" -->
+#   <!--#include file="plugins/jquery.idletimer.js" -->
+# and they would be included into this single file.
+
+# This is not in use in the boilerplate as it stands. You may
+# choose to name your files in this way for this advantage or
+# concatenate and minify them manually.
+# Disabled by default.
+
+#<FilesMatch "\.combined\.js$">
+#  Options +Includes
+#  AddOutputFilterByType INCLUDES application/javascript application/json
+#  SetOutputFilter INCLUDES
+#</FilesMatch>
+#<FilesMatch "\.combined\.css$">
+#  Options +Includes
+#  AddOutputFilterByType INCLUDES text/css
+#  SetOutputFilter INCLUDES
+#</FilesMatch>
+
+
+# ----------------------------------------------------------------------
+# Gzip compression
+# ----------------------------------------------------------------------
+
+<IfModule mod_deflate.c>
+
+  # Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
+  <IfModule mod_setenvif.c>
+    <IfModule mod_headers.c>
+      SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
+      RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
+    </IfModule>
+  </IfModule>
+
+  # HTML, TXT, CSS, JavaScript, JSON, XML, HTC:
+  <IfModule filter_module>
+    FilterDeclare   COMPRESS
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/html
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/css
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/plain
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/x-component
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/javascript
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/json
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/xhtml+xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/rss+xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/atom+xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/vnd.ms-fontobject
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $image/svg+xml
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $image/x-icon
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $application/x-font-ttf
+    FilterProvider  COMPRESS  DEFLATE resp=Content-Type $font/opentype
+    FilterChain     COMPRESS
+    FilterProtocol  COMPRESS  DEFLATE change=yes;byteranges=no
+  </IfModule>
+
+  <IfModule !mod_filter.c>
+    # Legacy versions of Apache
+    AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
+    AddOutputFilterByType DEFLATE application/javascript
+    AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
+    AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml application/atom+xml
+    AddOutputFilterByType DEFLATE image/x-icon image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype
+  </IfModule>
+
+</IfModule>
+
+
+# ----------------------------------------------------------------------
+# Expires headers (for better cache control)
+# ----------------------------------------------------------------------
+
+# These are pretty far-future expires headers.
+# They assume you control versioning with cachebusting query params like
+#   <script src="application.js?20100608">
+# Additionally, consider that outdated proxies may miscache
+#   www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
+
+# If you don't use filenames to version, lower the CSS  and JS to something like
+#   "access plus 1 week" or so.
+
+<IfModule mod_expires.c>
+  ExpiresActive on
+
+# Perhaps better to whitelist expires rules? Perhaps.
+  ExpiresDefault                          "access plus 1 month"
+
+# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5)
+  ExpiresByType text/cache-manifest       "access plus 0 seconds"
+
+# Your document html
+  ExpiresByType text/html                 "access plus 0 seconds"
+
+# Data
+  ExpiresByType text/xml                  "access plus 0 seconds"
+  ExpiresByType application/xml           "access plus 0 seconds"
+  ExpiresByType application/json          "access plus 0 seconds"
+
+# Feed
+  ExpiresByType application/rss+xml       "access plus 1 hour"
+  ExpiresByType application/atom+xml      "access plus 1 hour"
+
+# Favicon (cannot be renamed)
+  ExpiresByType image/x-icon              "access plus 1 week"
+
+# Media: images, video, audio
+  ExpiresByType image/gif                 "access plus 1 month"
+  ExpiresByType image/png                 "access plus 1 month"
+  ExpiresByType image/jpg                 "access plus 1 month"
+  ExpiresByType image/jpeg                "access plus 1 month"
+  ExpiresByType video/ogg                 "access plus 1 month"
+  ExpiresByType audio/ogg                 "access plus 1 month"
+  ExpiresByType video/mp4                 "access plus 1 month"
+  ExpiresByType video/webm                "access plus 1 month"
+
+# HTC files  (css3pie)
+  ExpiresByType text/x-component          "access plus 1 month"
+
+# Webfonts
+  ExpiresByType application/x-font-ttf    "access plus 1 month"
+  ExpiresByType font/opentype             "access plus 1 month"
+  ExpiresByType application/x-font-woff   "access plus 1 month"
+  ExpiresByType image/svg+xml             "access plus 1 month"
+  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
+
+# CSS and JavaScript
+  ExpiresByType text/css                  "access plus 1 year"
+  ExpiresByType application/javascript    "access plus 1 year"
+
+</IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# ETag removal
+# ----------------------------------------------------------------------
+
+# FileETag None is not enough for every server.
+<IfModule mod_headers.c>
+  Header unset ETag
+</IfModule>
+
+# Since we're sending far-future expires, we don't need ETags for
+# static content.
+#   developer.yahoo.com/performance/rules.html#etags
+FileETag None
+
+
+
+# ----------------------------------------------------------------------
+# Stop screen flicker in IE on CSS rollovers
+# ----------------------------------------------------------------------
+
+# The following directives stop screen flicker in IE on CSS rollovers - in
+# combination with the "ExpiresByType" rules for images (see above). If
+# needed, un-comment the following rules.
+
+# BrowserMatch "MSIE" brokenvary=1
+# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
+# BrowserMatch "Opera" !brokenvary
+# SetEnvIf brokenvary 1 force-no-vary
+
+
+
+# ----------------------------------------------------------------------
+# Cookie setting from iframes
+# ----------------------------------------------------------------------
+
+# Allow cookies to be set from iframes (for IE only)
+# If needed, uncomment and specify a path or regex in the Location directive
+
+# <IfModule mod_headers.c>
+#   <Location />
+#     Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
+#   </Location>
+# </IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Start rewrite engine
+# ----------------------------------------------------------------------
+
+# Turning on the rewrite engine is necessary for the following rules and features.
+# FollowSymLinks must be enabled for this to work.
+
+<IfModule mod_rewrite.c>
+  Options +FollowSymlinks
+  RewriteEngine On
+</IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Suppress or force the "www." at the beginning of URLs
+# ----------------------------------------------------------------------
+
+# The same content should never be available under two different URLs - especially not with and
+# without "www." at the beginning, since this can cause SEO problems (duplicate content).
+# That's why you should choose one of the alternatives and redirect the other one.
+
+# By default option 1 (no "www.") is activated. Remember: Shorter URLs are sexier.
+# no-www.org/faq.php?q=class_b
+
+# If you rather want to use option 2, just comment out all option 1 lines
+# and uncomment option 2.
+# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!
+
+# ----------------------------------------------------------------------
+
+# Option 1:
+# Rewrite "www.example.com -> example.com"
+
+<IfModule mod_rewrite.c>
+  RewriteCond %{HTTPS} !=on
+  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
+  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
+</IfModule>
+
+# ----------------------------------------------------------------------
+
+# Option 2:
+# To rewrite "example.com -> www.example.com" uncomment the following lines.
+# Be aware that the following rule might not be a good idea if you
+# use "real" subdomains for certain parts of your website.
+
+# <IfModule mod_rewrite.c>
+#   RewriteCond %{HTTPS} !=on
+#   RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
+#   RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
+# </IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Built-in filename-based cache busting
+# ----------------------------------------------------------------------
+
+# If you're not using the build script to manage your filename version revving,
+# you might want to consider enabling this, which will route requests for
+# /css/style.20110203.css to /css/style.css
+
+# To understand why this is important and a better idea than all.css?v1231,
+# read: github.com/h5bp/html5-boilerplate/wiki/Version-Control-with-Cachebusting
+
+# Uncomment to enable.
+# <IfModule mod_rewrite.c>
+#   RewriteCond %{REQUEST_FILENAME} !-f
+#   RewriteCond %{REQUEST_FILENAME} !-d
+#   RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
+# </IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Prevent SSL cert warnings
+# ----------------------------------------------------------------------
+
+# Rewrite secure requests properly to prevent SSL cert warnings, e.g. prevent
+# https://www.example.com when your cert only allows https://secure.example.com
+# Uncomment the following lines to use this feature.
+
+# <IfModule mod_rewrite.c>
+#   RewriteCond %{SERVER_PORT} !^443
+#   RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L]
+# </IfModule>
+
+
+
+# ----------------------------------------------------------------------
+# Prevent 404 errors for non-existing redirected folders
+# ----------------------------------------------------------------------
+
+# without -MultiViews, Apache will give a 404 for a rewrite if a folder of the same name does not exist
+#   e.g. /blog/hello : webmasterworld.com/apache/3808792.htm
+
+Options -MultiViews
+
+
+
+# ----------------------------------------------------------------------
+# Custom 404 page
+# ----------------------------------------------------------------------
+
+# You can add custom pages to handle 500 or 403 pretty easily, if you like.
+ErrorDocument 404 /404.html
+
+
+
+# ----------------------------------------------------------------------
+# UTF-8 encoding
+# ----------------------------------------------------------------------
+
+# Use UTF-8 encoding for anything served text/plain or text/html
+AddDefaultCharset utf-8
+
+# Force UTF-8 for a number of file formats
+AddCharset utf-8 .css .js .xml .json .rss .atom
+
+
+
+# ----------------------------------------------------------------------
+# A little more security
+# ----------------------------------------------------------------------
+
+
+# Do we want to advertise the exact version number of Apache we're running?
+# Probably not.
+## This can only be enabled if used in httpd.conf - It will not work in .htaccess
+# ServerTokens Prod
+
+
+# "-Indexes" will have Apache block users from browsing folders without a default document
+# Usually you should leave this activated, because you shouldn't allow everybody to surf through
+# every folder on your server (which includes rather private places like CMS system folders).
+<IfModule mod_autoindex.c>
+  Options -Indexes
+</IfModule>
+
+
+# Block access to "hidden" directories whose names begin with a period. This
+# includes directories used by version control systems such as Subversion or Git.
+<IfModule mod_rewrite.c>
+  RewriteCond %{SCRIPT_FILENAME} -d
+  RewriteCond %{SCRIPT_FILENAME} -f
+  RewriteRule "(^|/)\." - [F]
+</IfModule>
+
+
+# Block access to backup and source files
+# This files may be left by some text/html editors and
+# pose a great security danger, when someone can access them
+<FilesMatch "(\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$">
+  Order allow,deny
+  Deny from all
+  Satisfy All
+</FilesMatch>
+
+
+# If your server is not already configured as such, the following directive
+# should be uncommented in order to set PHP's register_globals option to OFF.
+# This closes a major security hole that is abused by most XSS (cross-site
+# scripting) attacks. For more information: http://php.net/register_globals
+#
+# IF REGISTER_GLOBALS DIRECTIVE CAUSES 500 INTERNAL SERVER ERRORS :
+#
+# Your server does not allow PHP directives to be set via .htaccess. In that
+# case you must make this change in your php.ini file instead. If you are
+# using a commercial web host, contact the administrators for assistance in
+# doing this. Not all servers allow local php.ini files, and they should
+# include all PHP configurations (not just this one), or you will effectively
+# reset everything to PHP defaults. Consult www.php.net for more detailed
+# information about setting PHP directives.
+
+# php_flag register_globals Off
+
+# Rename session cookie to something else, than PHPSESSID
+# php_value session.name sid
+
+# Do not show you are using PHP
+# Note: Move this line to php.ini since it won't work in .htaccess
+# php_flag expose_php Off
+
+# Level of log detail - log all errors
+# php_value error_reporting -1
+
+# Write errors to log file
+# php_flag log_errors On
+
+# Do not display errors in browser (production - Off, development - On)
+# php_flag display_errors Off
+
+# Do not display startup errors (production - Off, development - On)
+# php_flag display_startup_errors Off
+
+# Format errors in plain text
+# Note: Leave this setting 'On' for xdebug's var_dump() output
+# php_flag html_errors Off
+
+# Show multiple occurrence of error
+# php_flag ignore_repeated_errors Off
+
+# Show same errors from different sources
+# php_flag ignore_repeated_source Off
+
+# Size limit for error messages
+# php_value log_errors_max_len 1024
+
+# Don't precede error with string (doesn't accept empty string, use whitespace if you need)
+# php_value error_prepend_string " "
+
+# Don't prepend to error (doesn't accept empty string, use whitespace if you need)
+# php_value error_append_string " "
+
+# Increase cookie security
+<IfModule php5_module>
+  php_value session.cookie_httponly true
+</IfModule>

+ 44 - 0
404.html

@@ -0,0 +1,44 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>Page Not Found :(</title>
+  <style>
+    ::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
+    ::selection { background: #fe57a1; color: #fff; text-shadow: none; }
+    html { padding: 30px 10px; font-size: 20px; line-height: 1.4; color: #737373; background: #f0f0f0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
+    html, input { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
+    body { max-width: 500px; _width: 500px; padding: 30px 20px 50px; border: 1px solid #b3b3b3; border-radius: 4px; margin: 0 auto; box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff; background: #fcfcfc; }
+    h1 { margin: 0 10px; font-size: 50px; text-align: center; }
+    h1 span { color: #bbb; }
+    h3 { margin: 1.5em 0 0.5em; }
+    p { margin: 1em 0; }
+    ul { padding: 0 0 0 40px; margin: 1em 0; }
+    .container { max-width: 380px; _width: 380px; margin: 0 auto; }
+    /* google search */
+    #goog-fixurl ul { list-style: none; padding: 0; margin: 0; }
+    #goog-fixurl form { margin: 0; }
+    #goog-wm-qt, #goog-wm-sb { border: 1px solid #bbb; font-size: 16px; line-height: normal; vertical-align: top; color: #444; border-radius: 2px; }
+    #goog-wm-qt { width: 220px; height: 20px; padding: 5px; margin: 5px 10px 0 0; box-shadow: inset 0 1px 1px #ccc; }
+    #goog-wm-sb { display: inline-block; height: 32px; padding: 0 10px; margin: 5px 0 0; white-space: nowrap; cursor: pointer; background-color: #f5f5f5; background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1); background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1); background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1); background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1); -webkit-appearance: none; -moz-appearance: none; appearance: none; *overflow: visible; *display: inline; *zoom: 1; }
+    #goog-wm-sb:hover, #goog-wm-sb:focus { border-color: #aaa; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); background-color: #f8f8f8; }
+    #goog-wm-qt:focus, #goog-wm-sb:focus { border-color: #105cb6; outline: 0; color: #222; }
+    input::-moz-focus-inner { padding: 0; border: 0; }
+  </style>
+</head>
+<body>
+  <div class="container">
+    <h1>Not found <span>:(</span></h1>
+    <p>Sorry, but the page you were trying to view does not exist.</p>
+    <p>It looks like this was the result of either:</p>
+    <ul>
+      <li>a mistyped address</li>
+      <li>an out-of-date link</li>
+    </ul>
+    <script>
+      var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;
+    </script>
+    <script src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
+  </div>
+</body>
+</html>

+ 59 - 0
Configuration.class.php

@@ -0,0 +1,59 @@
+<?php
+class Configuration extends SQLiteEntity{
+
+	protected $id,$key,$value;
+	protected $TABLE_NAME = 'configuration';
+	protected $CLASS_NAME = 'Configuration';
+	protected $object_fields = 
+	array(
+		'id'=>'key',
+		'key'=>'longstring',
+		'value'=>'longstring'
+	);
+
+	function __construct(){
+		parent::__construct();
+	}
+
+
+	public function get($key){
+		$configurationManager = new Configuration();
+		$config = $configurationManager->load(array('key'=>$key));
+		return (is_object($config)?$config->getValue():'');
+	}
+
+	public function put($key,$value){
+		$configurationManager = new Configuration();
+		$config = $configurationManager->load(array('key'=>$key));
+		$config = (!$config?new Configuration():$config);
+		$config->setKey($key);
+		$config->setValue($value);
+		$config->save();
+	}
+	
+	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;
+	}
+
+
+
+
+}
+
+?>

+ 122 - 0
Event.class.php

@@ -0,0 +1,122 @@
+<?php
+
+class Event extends SQLiteEntity{
+
+	protected $id,$title,$guid,$content,$description,$pudate,$link,$feed,$category,$creator,$unread;
+	protected $TABLE_NAME = 'event';
+	protected $CLASS_NAME = 'Event';
+	protected $object_fields = 
+	array(
+		'id'=>'key',
+		'guid'=>'longstring',
+		'title'=>'string',
+		'creator'=>'string',
+		'content'=>'longstring',
+		'description'=>'longstring',
+		'unread'=>'integer',
+		'feed'=>'integer',
+		'unread'=>'integer',
+		'pubdate'=>'string'
+	);
+
+	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 getCreator(){
+		return $this->creator;
+	}
+
+	function setCreator($creator){
+		$this->creator = $creator;
+	}
+
+	function getCategory(){
+		return $this->category;
+	}
+
+	function setCategory($category){
+		$this->category = $category;
+	}
+
+	function getDescription(){
+		return utf8_encode($this->description);
+	}
+
+	function setDescription($description){
+		$this->description = $description;
+	}
+
+	function getPubdate(){
+		return $this->pubdate;
+	}
+
+	function setPubdate($pubdate){
+		$this->pubdate = date('d/m/Y H:i:s',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){
+		$this->content = $content;
+	}
+
+
+	function getGuid(){
+		return $this->guid;
+	}
+
+	function setGuid($guid){
+		$this->guid = $guid;
+	}
+
+	function getUnread(){
+		return $this->unread;
+	}
+
+	function setUnread($unread){
+		$this->unread = $unread;
+	}
+	function setFeed($feed){
+		$this->feed = $feed;
+	}
+	function getFeed(){
+		return $this->feed;
+	}
+
+}
+
+?>

+ 158 - 0
Feed.class.php

@@ -0,0 +1,158 @@
+<?php
+class Feed extends SQLiteEntity{
+
+	protected $id,$name,$url,$unread=0,$events=array(),$description,$website,$folder;
+	protected $TABLE_NAME = 'feed';
+	protected $CLASS_NAME = 'Feed';
+	protected $object_fields = 
+	array(
+		'id'=>'key',
+		'name'=>'string',
+		'description'=>'longstring',
+		'website'=>'longstring',
+		'url'=>'longstring',
+		'unread'=>'integer',
+		'folder'=>'integer'
+	);
+
+	function __construct($name=null,$url=null){
+		$this->name = $name;
+		$this->url = $url;
+		parent::__construct();
+	}
+
+	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 parse(){
+		$xml = @simplexml_load_file($this->url,"SimpleXMLElement",LIBXML_NOCDATA);
+		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'));
+			$eventManager = new Event();
+
+			
+
+			foreach($xml->xpath('//item') as $item){
+				$alreadyParsed = $eventManager->load(array('guid'=>$item->guid));
+
+				if(!$alreadyParsed){
+					$event = new Event($item->guid,$item->title);
+					$namespaces = $item->getNameSpaces(true);
+					if(isset($namespaces['dc'])){ 
+						$dc = $item->children($namespaces['dc']);
+						$event->setCreator($dc->creator);
+						$event->setPubdate($dc->date);
+
+						if($event->getPubdate()=='')
+						$event->setPubdate($dc->pubDate);
+
+					}
+
+
+					if(trim($event->getPubdate()==''))
+						$event->setPubdate($item->pubDate);
+
+					if(trim($event->getPubdate()==''))
+						$event->setPubdate($item->date);
+
+					if(trim($event->getCreator()==''))
+						$event->setCreator($item->creator);
+					
+				
+				
+
+					$event->setContent($item->children($namespaces['content']));
+					$event->setLink($item->link);
+					$event->setCategory($item->category);
+					$event->setDescription(utf8_decode($item->description));
+					$event->setFeed($this->id);
+					$event->setUnread(1);
+					$event->save();
+
+				}
+
+			}
+			
+		}else{
+			$this->name = 'Flux invalide';
+			$this->description = 'Impossible de se connecter au flux demand&eacute, peut &ecirc;tre est il en maintenance?';
+		}
+
+	}
+
+	
+
+
+	function getDescription(){
+		return stripslashes($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 (isset($this->name)?$this->name:$this->url);
+	}
+
+	function setName($name){
+		$this->name = $name;
+	}
+
+	function getUnread(){
+		return $this->unread;
+	}
+
+	function getEvents($start=0,$limit=10000,$order){
+		$eventManager = new Event();
+		$events = $eventManager->loadAll(array('feed'=>$this->getId()),$order,$start.','.$limit);
+		return $events;
+	}
+
+	function countUnreadEvents(){
+		$result = 0;
+		$eventManager = new Event();
+		$result = $eventManager->rowCount(array('feed'=>$this->getId(),'unread'=>'1'));
+		return $result;
+	}
+
+
+	function getFolder(){
+		return $this->folder;
+	}
+
+	function setFolder($folder){
+		$this->folder = $folder;
+	}
+
+
+}
+
+?>

+ 57 - 0
Folder.class.php

@@ -0,0 +1,57 @@
+<?php
+class Folder extends SQLiteEntity{
+
+	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 __construct(){
+		parent::__construct();
+	}
+
+	function getFeeds(){
+		$feedManager = new Feed();
+
+		return $feedManager->loadAll(array('folder'=>$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;
+	}
+
+
+
+}
+
+?>

+ 324 - 0
Functions.class.php

@@ -0,0 +1,324 @@
+<?php
+
+/*
+ @nom: function
+ @auteur: Valentin CARRUESCO (valentin.carruesco@sys1.fr)
+ @date de création: 10/10/2011 à 21:10
+ @description: Classe de stockage des fonctions utiles (toutes disponibles en static)
+ */
+
+class Functions
+{
+	private $id;
+	public $debug=0;
+	const CRYPTKEY = 'zr_e65$^vg41^948e*586"';
+	/**
+	 * 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 = htmlentities($var, ENT_QUOTES, "UTF-8");
+		if($level<1)$var = mysql_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){
+		$msg = utf8_encode(html_entity_decode($msg));
+		if(strlen($msg)>$limit){
+			$nb=$limit-3 ;
+			$fin='...' ;
+		}else{
+			$nb=strlen($msg);
+			$fin='';
+		}
+		return 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('&#039;','-',$name);
+		$name = str_replace('\'','-',$name);
+		$name = str_replace(',','-',$name);
+		$name = str_replace(':','-',$name);
+		$name = str_replace('&agrave;','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]);
+	}
+
+	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('&lt;br/&gt;','<br/>',$str);
+		$str = str_replace('&amp;','&',$str);
+		return $str;
+	}
+
+	public static function createFile($filePath,$content){
+		$fichier = fopen($filePath,"w+");
+		$fwriteResult = fwrite($fichier,$content);
+		fclose($fichier);
+	}
+
+	public static function crypt($string,$key=Functions::CRYPTKEY){
+		$key = sha1($key);
+		$return = '';
+		for ($i = 0; $i<strlen($string); $i++) {
+			$kc = substr($key, ($i%strlen($key)) - 1, 1);
+			$return .= chr(ord($string{$i})+ord($kc));
+		}
+		return base64_encode($return);
+	}
+
+	public static function decrypt($string,$key=Functions::CRYPTKEY){
+		$key = sha1($key);
+		$return = '';
+		$string = base64_decode($string);
+		for ($i = 0; $i<strlen($string); $i++) {
+			$kc = substr($key, ($i%strlen($key)) - 1, 1);
+			$return .= chr(ord($string{$i})-ord($kc));
+		}
+		return $return;
+	}
+
+
+	public static function hexaValue($string){
+		
+		$alphabet = array_flip (array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'));
+		$val = 0;
+		$hexVal = 0;
+		for($i=0;$i<strlen($string);$i++){
+			$letter = substr($string,$i,1);
+			if($letter == 'a' || $letter == 'b' || $letter == 'c' || $letter == 'd' || $letter == 'e' || $letter == 'f'  ){
+				$val .=$letter;
+			}
+			$val .= $alphabet[$letter];
+		}
+
+		return '#'.substr($val,0,6);
+	}
+	
+	public 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;
+	}
+	
+}
+?>

BIN
Logo Leed.psd


+ 35 - 0
README

@@ -0,0 +1,35 @@
+Application : Leed (Light Feed)
+Version : 1.0 Alpha
+Auteur : Valentin CARRUESCO aka Idleman (idleman@idleman.fr)
+Dépot SVN : http://hades.idleman.fr/leed
+Licence : CC by-nc-nd (http://creativecommons.org/licenses/by-nc-nd/2.0/fr/) Nb : les traveaux dérivé peuvent être autorisés avec accord de l'auteur
+
+==================
+== PRESENTATION ==
+==================
+
+	Leed (contraction de Light Feed) est un agrégatteur RSS libre et minimaliste qui permet la consultation de flux RSS de manière rapide et non intrusive.
+
+	Toutes les tâches de traitements de flux sont effectuées de manière invisible par une tâche synchronisée (Cron),ainsi, l'utilisateur ne subis pas les lenteures dues à la récupération et au traitement de chacun des flux suivis.
+
+	A noter que Leed est compatible toutes résolutions, sur pc, tablettes et smartphone et fonctionne sous tous les navigateurs.
+
+	Le script est également compatible avec les fichiers d'exports/imports OPML ce qui rend la migration de tous les agrégateurs réspectant le standard OPML simple et rapide.
+
+==================
+== INSTALLATION ==
+==================
+
+	1. Récuperez le projet sur le dépot SVN de la version courante : http://hades.idleman.fr/leed
+	2. Placez le projet dans votre repertoire web et appliquer une permission chmod 777 sur le dossier et son contenu
+	3. Depuis votre navigateur, accedez a la page d'installation install.php (ex : http://votre.domaine.fr/leed/install.php) et suivez le instructions.
+	4. Une fois l'installation terminée, supprimez le fichier install.php par mesure de sécurité
+	5. 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 ex : 
+
+	0 * * * * wget -q -O /var/www/leed/logsCron http://127.0.0.1/leed/action.php?action=synchronize
+
+	Pour mettre a 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'executer).
+	6. Le script est installé, merci d'vaoir choisis Leed, l'agrégatteur RSS libre et svelte :p.
+
+
+

+ 331 - 0
SQLiteEntity.class.php

@@ -0,0 +1,331 @@
+<?php
+
+/*
+	@nom: SQLiteEntity
+	@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 SQLite, mais il est possible de redefinir ses codes SQL pour l'adapter à un autre SGBD sans affecter 
+	 le reste du code du projet.
+
+*/
+
+class SQLiteEntity extends SQLite3
+{
+	
+	private $debug = false;
+	
+
+
+
+	function __construct(){
+		$this->open('database.db');
+	}
+
+	function __destruct(){
+		 $this->close();
+	}
+
+	function sgbdType($type){
+		$return = false;
+		switch($type){
+			case 'string':
+			case 'timestamp':
+			case 'date':
+				$return = 'VARCHAR(255)';
+			break;
+			case 'longstring':
+				$return = 'longtext';
+			break;
+			case 'key':
+				$return = 'INTEGER NOT NULL PRIMARY KEY';
+			break;
+			case 'object':
+			case 'integer':
+				$return = 'bigint(20)';
+			break;
+			case 'boolean':
+				$return = 'INT(1)';
+			break;
+			default;
+				$return = 'TEXT';
+			break;
+		}
+		return $return ;
+	}
+	
+
+	public function closeDatabase(){
+		$this->close();
+	}
+
+
+	// GESTION SQL
+
+
+
+	/**
+	* 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 `'.$this->TABLE_NAME.'` (';
+
+		$end = end(array_keys($this->object_fields));
+		foreach($this->object_fields as $field=>$type){
+			$query .='`'.$field.'`  '. $this->sgbdType($type).'  NOT NULL';
+			if($field != $end)$query .=',';
+		}
+
+		$query .= ');';
+		if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query;
+		if(!$this->exec($query)) echo $this->lastErrorMsg();
+	}
+
+	/**
+	* 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 `'.$this->TABLE_NAME.'`';
+			$query .= ' SET ';
+
+			$end = end(array_keys($this->object_fields));
+			foreach($this->object_fields as $field=>$type){
+				$id = eval('return $this->'.$field.';');
+				$query .= '`'.$field.'`="'.$id.'"';
+				if($field != $end)$query .=',';
+			}
+
+			$query .= ' WHERE `id`="'.$this->id.'";';
+		}else{
+			$query = 'INSERT INTO `'.$this->TABLE_NAME.'`(';
+			$end = end(array_keys($this->object_fields));
+			foreach($this->object_fields as $field=>$type){
+				if($type!='key'){
+					$query .='`'.$field.'`';
+					if($field != $end)$query .=',';
+				}
+			}
+			$query .=')VALUES(';
+			$end = end(array_keys($this->object_fields));
+			foreach($this->object_fields as $field=>$type){
+				if($type!='key'){
+					$query .='"'.eval('return htmlentities($this->'.$field.');').'"';
+					if($field != $end)$query .=',';
+				}
+			}
+
+			$query .=');';
+		}
+		if($this->debug)echo '<i>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>';
+		if(!$this->exec($query)) echo $this->lastErrorMsg().'</i>';
+		$this->id =  (!isset($this->id)?$this->lastInsertRowID():$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=null,$operation='=',$debug='false'){
+		$query = 'UPDATE `'.$this->TABLE_NAME.'` SET ';
+		$end = end(array_keys($columns));
+		foreach ($columns as $column=>$value){
+			$query .= '`'.$column.'`="'.$value.'" ';
+			if($column != $end)$query .=',';
+		}
+
+		if($columns2!=null){
+			$query .=' WHERE '; 
+			$end = end(array_keys($columns2));
+			foreach ($columns2 as $column=>$value){
+				$query .= '`'.$column.'`'.$operation.'"'.$value.'" ';
+				if($column != $end)$query .='AND ';
+			}
+		}
+
+		if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>';
+		if(!$this->exec($query)) echo $this->lastErrorMsg();
+	}
+
+	/**
+	* 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'){
+		eval('$results = '.$this->CLASS_NAME.'::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'){
+		$objects = array();
+		$whereClause = '';
+	
+			if(sizeof($columns)!=0){
+			$whereClause .= ' WHERE ';
+				$start = reset(array_keys($columns));
+				foreach($columns as $column=>$value){
+					if($column != $start)$whereClause .= ' AND ';
+					$whereClause .= '`'.$column.'`'.$operation.'"'.$value.'"';
+				}
+			}
+			$query = 'SELECT * FROM `'.$this->TABLE_NAME.'` '.$whereClause.' ';
+			if($order!=null) $query .='ORDER BY `'.$order.'` ';
+			if($limit!=null) $query .='LIMIT '.$limit.' ';
+			$query .=';';
+			if($this->debug) echo '<br>'.__METHOD__.' : Requete --> '.$query.'<br>';
+			
+
+			$execQuery = $this->query($query);
+
+			if(!$execQuery) echo $this->lastErrorMsg();
+
+			while($queryReturn = $execQuery->fetchArray() ){
+
+				$object = eval(' return new '.$this->CLASS_NAME.'();');
+				foreach($this->object_fields as $field=>$type){
+
+					eval('$object->'.$field .'= html_entity_decode(\''. addslashes($queryReturn[$field]).'\');');
+				}
+				$objects[] = $object;
+				unset($object);
+			}
+			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'){
+		eval('$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 ';
+			$start = reset(array_keys($columns));
+			foreach($columns as $column=>$value){
+					if($column != $start)$whereClause .= ' AND ';
+					$whereClause .= '`'.$column.'`="'.$value.'"';
+			}
+		}
+		$query = 'SELECT COUNT(id) FROM '.$this->TABLE_NAME.$whereClause;
+		//echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>';
+		$execQuery = $this->querySingle($query);
+		//echo $this->lastErrorMsg();
+		return (!$execQuery?0:$execQuery);
+	}	
+	
+	/**
+	* Méthode de supression d'elements 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 = '';
+
+			$start = reset(array_keys($columns));
+			foreach($columns as $column=>$value){
+				if($column != $start)$whereClause .= ' AND ';
+				$whereClause .= '`'.$column.'`'.$operation.'"'.$value.'"';
+			}
+			$query = 'DELETE FROM `'.$this->TABLE_NAME.'` WHERE '.$whereClause.' ;';
+			if($this->debug)echo '<hr>'.$this->CLASS_NAME.' ('.__METHOD__ .') : Requete --> '.$query.'<br>';
+			if(!$this->exec($query)) echo $this->lastErrorMsg();
+	}
+	
+
+	// 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;
+	}
+
+}
+?>

+ 62 - 0
User.class.php

@@ -0,0 +1,62 @@
+<?php
+class User extends SQLiteEntity{
+
+	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 exist($login,$password){
+		$userManager = new User();
+		return $userManager->load(array('login'=>$login,'password'=>User::encrypt($password)));
+	}
+
+	function existAuthToken($auth){
+		$result = false;
+		$userManager = new User();
+		$users = $userManager->populate('id');
+		foreach($users as $user){
+		
+			if(sha1($user->getPassword().$user->getLogin())==$auth) $result = $user;
+		}
+		return $result;
+	}
+	
+	function getId(){
+		return $this->id;
+	}
+
+	function getLogin(){
+		return $this->login;
+	}
+
+	function setLogin($login){
+		$this->login = $login;
+	}
+
+	function getPassword(){
+		return $this->password;
+	}
+
+	function setPassword($password){
+		$this->password = User::encrypt($password);
+	}
+
+	static function encrypt($password){
+		return sha1($password);
+	}
+
+
+}
+
+?>

+ 204 - 0
action.php

@@ -0,0 +1,204 @@
+<?php
+
+require_once("common.php");
+
+
+
+//Execution du code en fonction de l'action
+switch ($_['action']){
+
+	case 'synchronize':
+		$feeds = $feedManager->populate('name');
+			echo '------------------------------------------------------------------'."\n";
+			echo '-------------- Synchronisation du '.date('d/m/Y').' --------------'."\n";
+			echo '------------------------------------------------------------------'."\n";
+			echo count($feeds).' Flux a synchroniser...'."\n";
+		foreach ($feeds as $feed) {
+			$feed->parse();
+			echo date('H:i:s').' - Flux '.$feed->getName().' : OK'."\n";;
+		}
+	break;
+
+	case 'readAll':
+		if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+		$feed = (isset($_['feed'])?array('feed'=>$_['feed']):null);
+		$eventManager->change(array('unread'=>'0'),$feed);
+		header('location: ./index.php');
+
+	break;
+
+	case 'updateConfiguration':
+		if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+
+			//Ajout des préférences et reglages
+			$configurationManager->put('root',$_['root']);
+			//$configurationManager->put('view',$_['view']);
+			$configurationManager->put('articleView',$_['articleView']);
+
+			$configurationManager->put('articlePerPages',$_['articlePerPages']);
+			$configurationManager->put('articleDisplayLink',$_['articleDisplayLink']);
+			$configurationManager->put('articleDisplayDate',$_['articleDisplayDate']);
+			$configurationManager->put('articleDisplayAuthor',$_['articleDisplayAuthor']);
+			//Création du dossier de base
+			$folder =$folderManager->load(array('id'=>1));
+			$folder->setName($_['category']);
+			$folder->save();
+	
+		header('location: ./addFeed.php');
+	break;
+
+	case 'exportFeed':
+				/*********************/
+			/** Export **/
+			/*********************/
+			if(isset($_POST['exportButton'])){
+				$feeds = $feedManager->populate('name');
+				$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('D, d M Y H:i:s').'+0000</dateCreated>
+		</head>
+		<body>
+			<outline text="Leed" title="Leed" icon="">'."\n";
+				foreach($feeds as $feed){
+					$xmlStream .= '				<outline xmlUrl="'.$feed->getUrl().'" htmlUrl="'.$feed->getWebsite().'" text="'.$feed->getDescription().'" title="'.$feed->getName().'" description="'.$feed->getDescription().'" />'."\n";
+				}
+				$xmlStream .= '			</outline>
+		</body>
+	</opml>';
+
+
+				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 'changeFolderState':
+		if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+		$folderManager->change(array('isopen'=>$_['isopen']),array('id'=>$_['id']));
+	break;
+
+	case 'importFeed':
+
+				if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+				if(isset($_POST['importButton'])){
+				set_time_limit (360);
+				$xml = simplexml_load_file($_FILES['newImport']['tmp_name']);
+				$level = $xml->xpath('body//outline');
+				foreach($level as $item){
+					$level2 = $item->outline;
+					foreach($level2 as $item2){
+						$newFeed = new Feed();
+						$newFeed->setName($item2[0]['title']);
+
+						$folder = $folderManager->load(array('name'=>$item['title']));
+						$folder = (!$folder?new Folder():$folder);
+						$folder->setName($item['title']);
+						$folder->setParent(-1);
+						$folder->setIsopen(0);
+						$folder->save();
+						$newFeed->setFolder($folder->getId());
+
+						$newFeed->setUrl($item2[0]['xmlUrl']);
+						$newFeed->setDescription($item2[0]['description']);
+						$newFeed->setWebsite($item2[0]['htmlUrl']);
+						$newFeed->save();
+						$newFeed->parse();
+					}
+				}
+				header('location: ./addFeed.php');
+			}
+	break;
+
+	
+	case 'addFeed':
+			if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+			if(isset($_['newUrl'])){
+				$newFeed = new Feed();
+				$newFeed->setUrl($_['newUrl']);
+				$newFeed->getInfos();
+				$newFeed->setFolder(1);
+				$newFeed->save();
+				$newFeed->parse();
+				header('location: ./addFeed.php');
+			}
+	break;
+
+	case 'removeFeed':
+		/**************************/
+		/** Supression d'une url **/
+		/**************************/
+		if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+		if(isset($_GET['id'])){
+			$feedManager->delete(array('id'=>$_GET['id']));
+			header('location: ./addFeed.php');
+		}
+	break;
+
+	case 'readContent':
+		$event = $eventManager->load(array('id'=>$_GET['id']));
+		$event->setUnread(0);
+		$event->save();
+		header('location: '.$event->getGuid());
+	break;
+	
+	case 'login':
+		if(isset($_['usr'])){
+			$user = $userManager->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{
+				$user = $userManager->exist($_['login'],$_['password']);
+			if($user==false){
+				exit("erreur identification : le compte est inexistant");
+			}else{
+				$_SESSION['currentUser'] = serialize($user);
+			}
+			header('location: ./index.php');	
+		}
+		
+
+	
+	break;
+
+	
+	case 'logout':
+		$_SESSION = array();
+		session_unset();
+		session_destroy();
+		header('location: ./index.php');
+	break;
+	
+	default:
+		exit('0');
+	break;
+}
+
+
+?>

+ 105 - 0
addFeed.php

@@ -0,0 +1,105 @@
+<?php require_once('header.php'); ?>
+
+
+
+		<div id="main" class="wrapper clearfix">
+
+			<?php
+
+			
+	
+			$feeds = $feedManager->populate('name'); 
+			?>
+
+			<aside>
+				<h3>Options des flux</h3>
+				<ul>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #manageBloc').fadeToggle(200);">Gestion des flux</li>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #preferenceBloc,#main #preferenceBloc section').fadeToggle(200);">Pr&eacute;f&eacute;rences</li>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #addBloc').fadeToggle(200);">Ajout d'un flux</li>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #importBloc').fadeToggle(200);">Import</li>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #exportBloc').fadeToggle(200);">Export</li>
+						<li class="pointer" onclick="$('#main section').hide();$('#main #bookBloc').fadeToggle(200);">Bookmarklet</li>
+						
+				</ul>
+			</aside>
+			
+			<article>
+				<header>
+					<h1>Gestion</h1>
+					<p>Cette section permet la gestion des parametrages de leed: configurations, flux RSS suivis, ajout depuis une url, import, export, supression...</p>
+				
+				</header>
+				
+
+				<section id="preferenceBloc">
+					<form method="POST" action="action.php?action=updateConfiguration">
+					<h2>Pr&eacute;f&eacute;rences :</h2>
+					<section>
+						<h2>G&eacute;n&eacute;ral</h2>
+						<p>Racine du projet : <input type="text" name="root" value="<?php echo str_replace(basename(__FILE__),'','http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>"></p>
+						<h3>Laissez bien un "/" en fin de chaine ex : http://monsite.com/leed/</h3>
+					</section>
+
+					<section>
+					<h2>Pr&eacute;ferences</h2>
+					<!--<p>Vue des flux: <input type="radio" value="list" name="view">Liste <input type="radio" value="mosaic" name="view">Mosaique</p>
+					<h3>Mosaic : affichage par bloc, style netvives, liste: affichage en liste style rssLounge</h3>-->
+					<p>Affichage des articles: <input type="radio" checked="checked" value="partial" name="articleView">Partiel <input type="radio" value="complete" name="articleView">Complet</p>
+					<h3>Nb: si vous choissisez un affichage partiel des articles, un click sur ces derniers menera à l'article sur le blog de l'auteur.</h3>
+					<p>Nombre d'articles par pages: <input type="text" value="5" name="articlePerPages"></p>
+					<p>Affichage du lien direct de l'article: <input type="radio" checked="checked" value="1" name="articleDisplayLink">Oui <input type="radio" value="0" name="articleDisplayLink">Non</p>
+					<p>Affichage de la date de l'article: <input type="radio" checked="checked" value="1" name="articleDisplayDate">Oui <input type="radio" value="0" name="articleDisplayDate">Non</p>
+					<p>Affichage de l'auteur de l'article: <input type="radio" checked="checked" value="1" name="articleDisplayAuthor">Oui <input type="radio" value="0" name="articleDisplayAuthor">Non</p>
+					<p>Cat&eacute;gorie par defaut: <input type="text" value="General" name="category"></p>
+					
+					</section>
+					<button name="installButton">Enregistrer</button>
+					</form>
+				</section>
+
+				<section id="manageBloc">
+					<h2><?php echo count($feeds);?> RSS suivis :</h2>
+					<table id="feedTable">
+						<?php foreach($feeds as $feed){?>
+						<tr><td><?php echo '<a href="'.$feed->getUrl().'">'.$feed->getName().'</a>'; ?></td><td><button onclick="window.location='action.php?action=removeFeed&id=<?php echo $feed->getId() ?>'">Supprimer</button></td></tr>
+						<tr><td colspan="2"><p><?php echo $feed->getDescription(); ?></p></td></tr>
+						<?php } ?>
+					</table>
+				</section>
+				
+				<section id="bookBloc">
+					<h2>Utiliser le bookmarklet :</h2>
+					<p>Vous pouvez ajout le bookmaklet ci dessus a votre naviguateur pour vous inscrire plus rapidemment au flux :</p>
+					<?php if($myUser!=false){ ?>
+					<a class="button" href='javascript:document.location="<?php echo $configurationManager->get('root'); ?>action.php?action=login&newUrl="+escape(document.location)+"&usr=<?php echo sha1($myUser->getPassword().$myUser->getLogin()); ?>"; '>+ Ajouter à Leed</a>
+					<?php  }else{  ?>
+					<p>Vous devez &eacute;tre connect&eacute; pour voir le bookmarklet.</p>
+					<?php } ?>
+				</section>
+				
+				<form action="action.php?action=addFeed" method="POST">
+				<section id="addBloc">
+					<h2>Ajouter depuis une URL</h2>
+					<p>Lien du flux RSS : <input type="text" name="newUrl" placeholder="http://monflux.com/rss"/><button>Ajouter</button></p>
+				</section>
+				</form>
+				<form action="action.php?action=importFeed" method="POST" enctype="multipart/form-data">
+				<section id="importBloc">
+					<h2>Importer les flux au format opml</h2>
+					<p>Fichier OPML : <input name="newImport" type="file"/><button name="importButton">Importer</button></p>
+					<p>Nb : L'importation peux prendre un certain temps, laissez votre navigateur tourner et allez vous prendre un caf&eacute; :).</p>
+				</section>
+				</form>
+				<form action="action.php?action=exportFeed" method="POST">
+				<section id="exportBloc">
+					<h2>Exporter les flux au format opml</h2>
+					<p>Fichier OPML : <button name="exportButton">Exporter</button></p>
+				</section>
+				</form>
+			</article>
+			
+			
+		</div> <!-- #main -->
+
+<?php require_once('footer.php'); ?>

BIN
apple-touch-icon-114x114-precomposed.png


BIN
apple-touch-icon-57x57-precomposed.png


BIN
apple-touch-icon-72x72-precomposed.png


BIN
apple-touch-icon-precomposed.png


BIN
apple-touch-icon.png


+ 28 - 0
common.php

@@ -0,0 +1,28 @@
+<?php 
+session_start();
+
+require_once('SQLiteEntity.class.php');
+require_once('Feed.class.php');
+require_once('Event.class.php');
+require_once('Functions.class.php');
+require_once('User.class.php');
+require_once('Folder.class.php');
+require_once('Configuration.class.php');
+
+$myUser = (isset($_SESSION['currentUser'])?unserialize($_SESSION['currentUser']):false);
+
+
+$feedManager = new Feed();
+$eventManager = new Event();
+$userManager = new User();
+$folderManager = new Folder();
+$configurationManager = new Configuration();
+//Récuperation et sécurisation de toutes les variables POST et GET
+$_ = array();
+foreach($_POST as $key=>$val){
+$_[$key]=Functions::secure($val);
+}
+foreach($_GET as $key=>$val){
+$_[$key]=Functions::secure($val);
+}
+?>

+ 456 - 0
css/style.css

@@ -0,0 +1,456 @@
+/* =============================================================================
+   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: 0; margin: 0; padding: 0; }
+label { cursor: pointer; }
+legend { border: 0; *margin-left: -7px; padding: 0; 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; 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:90%;
+	margin:0 5%;
+}
+
+/* ===================
+    ALL: Orange Theme
+   =================== */
+
+#header-container{ border-bottom: 5px solid #e44d26; }
+#footer-container{ 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:white; }
+
+::-moz-selection { background: #f16529; color: #fff; text-shadow: none; }
+::selection      { background: #f16529; color: #fff; text-shadow: none; }
+
+/* ==============
+    MOBILE: Menu
+   ============== */
+
+nav a{
+	display:block;
+	margin-bottom:10px;
+	padding:15px 0;
+
+	background:#e44d26;
+	color:white;
+
+	text-align:center;
+	text-decoration:none;
+	font-weight:bold;
+}
+
+nav a:hover, nav a:visited{
+	color:white;
+}
+
+nav a:hover, nav a:visited{
+	color:white;
+}
+
+header a,header a:hover{
+	text-decoration:none;
+	color:white;
+}
+
+/* ==============
+    MOBILE: Main
+   ============== */
+
+#main{
+	padding:30px 0;
+}
+
+#main button, .loginBloc button,.button{
+	background-color:#f16529;
+	border:0px;
+	color:#ffffff;
+	padding:3px 8px 3px 8px;
+	font-size:10px;
+	font-weight:bold;
+	-moz-border-radius: 30px;
+	-webkit-border-radius: 30px;
+	border-radius: 30px;
+}
+
+
+
+.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{
+	margin-top:10px;
+}
+
+#main article header h1{
+	font-size:2em;
+	margin:0px;
+}
+#main article header h1 a,#main article section h2 a{
+	text-decoration:none;
+	color: #222222;
+	cursor: pointer;
+}
+#main article section h2{
+	margin-bottom:5px;
+}
+#main article section h3{
+	font-size:10px;
+	font-weight:normal;
+	color:#939393;
+	margin:0px;
+}
+
+#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:14px;
+	padding:0px;
+	margin:3px;
+	text-align:center;
+	background-color:#666666;
+	cursor: pointer;
+}
+
+
+.logo{
+	background:url('../logo.png') no-repeat 0px center;
+	padding-left:60px;
+	padding-top:20px;
+	height:53px;
+	font-size:4em;
+	margin:0;
+}
+
+.loginBloc{
+	margin:29px 20px 0px 20px;
+	float:left;
+	width:40%;
+}
+.loginBloc input{
+	width:100px;
+	border:none;
+	-moz-border-radius: 2px;
+	-webkit-border-radius: 2px;
+	border-radius: 2px;
+	margin-right:1%;
+}
+
+.logo i{
+	font-size:0.7em;
+}
+
+#main aside ul li ul li:hover{
+	background-color:#333333;
+}
+
+#main article section.eventRead{
+	opacity:0.3;
+}
+
+#feedTable{
+	width:100%;
+}
+#feedTable tr td:first{
+	width:70%;
+}
+
+#addBloc,#exportBloc,#importBloc,#bookBloc,#preferenceBloc{
+	display:none;
+}
+.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;
+}
+
+#main aside{
+	color:white;
+	padding:0px 2% 10px;
+}
+
+#footer-container footer{
+	color:white;
+	padding:5px 0;
+}
+
+#main article section a.button {
+	color:#ffffff;
+	font-size:10px;
+	font-weight:bold;
+	text-decoration:none;
+}
+
+/* ===============
+    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:27%;
+		margin:0 1.7%;
+		padding:25px 2%;
+		margin-bottom:0;
+	}
+	
+	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) {
+
+/* ====================
+    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:57%;
+	}
+		
+	#main aside{
+		float:right;
+		width:28%;
+	}
+}
+
+@media only screen and (min-width: 1140px) {
+
+/* ===============
+    Maximal Width
+   =============== */
+
+	.wrapper{
+		width:1026px; /* 1140px - 10% for margins */
+		margin:0 auto;
+	}
+}
+
+/* =============================================================================
+   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;
+}
+.clear{
+	clear:both;
+}
+.hidden{
+	display:none;
+}

BIN
favicon.ico


+ 15 - 0
footer.php

@@ -0,0 +1,15 @@
+
+	</div> <!-- #main-container -->
+
+	<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>
+
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
+<script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js"><\/script>')</script>
+
+<script src="js/script.js"></script>
+</body>
+</html>

+ 49 - 0
header.php

@@ -0,0 +1,49 @@
+<?php 
+require_once('common.php');
+
+?>
+
+<!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></title>
+	<meta name="description" content="">
+	<meta name="author" content="">
+
+	<meta name="viewport" content="width=device-width">
+
+	<link rel="stylesheet" href="css/style.css">
+
+	<script src="js/libs/modernizr-2.5.3-respond-1.1.0.min.js"></script>
+</head>
+<body>
+	<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">
+			<?php if(!$myUser){ ?>
+			<form action="action.php?action=login" method="POST">
+					<input type="text" class="miniInput" name="login" placeholder="Identifiant"/> <input type="password" class="miniInput" name="password" placeholder="Mot de passe"/> <button>GO!!</button>
+			</form>
+			<?php }else{ ?>
+				<span>Identifi&eacute; avec <span><?php echo $myUser->getLogin(); ?></span></span><button onclick="window.location='action.php?action=logout'">D&eacute;connexion</button>
+			<?php } ?>
+			</div>
+			<nav>
+				<ul>
+					<li><a href="index.php">Accueil</a></li>
+					<li><a href="addFeed.php">+ Flux</a></li>
+					<li><a href="http://blog.idleman.fr">A propos</a></li>
+				</ul>
+			</nav>
+		</header>
+	</div>
+
+
+	<div id="main-container">

+ 43 - 0
humans.txt

@@ -0,0 +1,43 @@
+/* the humans responsible & colophon */
+/* humanstxt.org */
+
+
+/* TEAM */
+  <your title>: <your name>
+  Site:
+  Twitter:
+  Location:
+
+/* THANKS */
+  Names (& URL):
+
+/* SITE */
+  Standards: HTML5, CSS3
+  Components: Modernizr, jQuery
+  Software:
+
+
+
+                               -o/-
+                               +oo//-
+                              :ooo+//:
+                             -ooooo///-
+                             /oooooo//:
+                            :ooooooo+//-
+                           -+oooooooo///-
+           -://////////////+oooooooooo++////////////::
+            :+ooooooooooooooooooooooooooooooooooooo+:::-
+              -/+ooooooooooooooooooooooooooooooo+/::////:-
+                -:+oooooooooooooooooooooooooooo/::///////:-
+                  --/+ooooooooooooooooooooo+::://////:-
+                     -:+ooooooooooooooooo+:://////:--
+                       /ooooooooooooooooo+//////:-
+                      -ooooooooooooooooooo////-
+                      /ooooooooo+oooooooooo//:
+                     :ooooooo+/::/+oooooooo+//-
+                    -oooooo/::///////+oooooo///-
+                    /ooo+::://////:---:/+oooo//:
+                   -o+/::///////:-      -:/+o+//-
+                   :-:///////:-            -:/://
+                     -////:-                 --//:
+                       --                       -:

+ 86 - 0
index.php

@@ -0,0 +1,86 @@
+<?php require_once('header.php'); ?>
+<?php
+//$feeds = $feedManager->populate('name');
+$folders = $folderManager->populate('name');
+$currentFeed = false;
+
+
+
+
+if(isset($_GET['action'])){
+	switch($_GET['action']){
+		case 'readFeed':
+		$currentFeed = $feedManager->getById($_GET['feed']);
+		break;
+
+	}
+}
+
+?>
+		<div id="main" class="wrapper clearfix">
+			<aside>
+				<h3 class="left">Flux</h3> <button style="margin: 20px 10px;" onclick="if(confirm('Tout marquer comme lu pour tous les flux?'))window.location='action.php?action=readAll'">Tout marquer comme lu</button>
+				
+				<ul class="clear">
+					<?php foreach($folders as $folder){  
+						$feeds = $folder->getFeeds();
+						?>
+					<li  ><h1 class="folder" onclick="toggleFolder(this,<?php echo $folder->getId(); ?>);"><?php echo $folder->getName().' ('.count($feeds).')'; ?></h1>
+						<ul <?php if(!$folder->getIsopen()){ ?>style="display:none;"<?php } ?>  style="margin:0">
+							<?php if (count($feeds)!=0 ) {foreach($feeds as $feed){ ?>
+								<li><a href="index.php?action=readFeed&feed=<?php echo $feed->getId();?>" alt="<?php echo $feed->getUrl(); ?>" title="<?php echo $feed->getUrl(); ?>"><?php echo $feed->getName(); ?> <?php $unread = $feed->countUnreadEvents(); if($unread!=0){ ?></a>  <button style="margin-left:10px;" onclick="if(confirm('Tout marquer comme lu pour ce flux?'))window.location='action.php?action=readAll&feed=<?php echo $feed->getId(); ?>'"><span alt="marquer comme lu" title="marquer comme lu"><?php echo $unread; ?></span></button><?php } ?> </li>
+							<?php }} ?>
+						</ul>
+					</li>
+					<?php } ?>
+				</ul>
+
+			</aside>
+			<?php if($currentFeed !=false){
+
+				$articleView = $configurationManager->get('articleView');
+				$articlePerPages = $configurationManager->get('articlePerPages');
+				$articleDisplayLink = $configurationManager->get('articleDisplayLink');
+				$articleDisplayDate = $configurationManager->get('articleDisplayDate');
+				$articleDisplayAuthor = $configurationManager->get('articleDisplayAuthor');
+
+				$numberOfFeed = $eventManager->rowCount(array('feed'=>$currentFeed->getId()));
+				$page = (isset($_['page'])?$_['page']:1);
+				$pages = round($numberOfFeed/$articlePerPages); 
+				$startArticle = ($page-1)*$articlePerPages;
+				
+				$events = $currentFeed->getEvents($startArticle,$articlePerPages,'id');
+
+
+
+			 ?>
+
+			<article>
+				<header>
+					<h1><a target="_blank" href="<?php echo $currentFeed->getWebSite(); ?>"><?php echo $currentFeed->getName(); ?></a></h1>
+					<p><?php echo $currentFeed->getDescription(); ?></p>
+				
+				</header>
+				<?php  
+
+				foreach($events as $event){
+				 ?>
+				<section <?php if(!$event->getUnread()){ ?>class="eventRead"<?php } ?> >
+					<h2><a onclick="$(this).parent().parent().addClass('eventRead');" target="_blank" href="action.php?action=readContent&id=<?php echo $event->getId(); ?>" alt="Voir l'article sur le blog" title="Voir l'article sur le blog"><?php echo $event->getTitle(); ?></a></h2>
+					<h3><?php if ($articleDisplayAuthor){ ?>Par <?php echo $event->getCreator(); } if ($articleDisplayLink){ ?> le <?php echo $event->getPubDate(); } if ($articleDisplayLink){ ?>- <a href="<?php echo $event->getGuid(); ?>" traget="_blank">Lien direct vers l'article</a><?php } ?>
+					</h3>
+					<p><?php if ($articleView=='partial'){echo $event->getDescription();}else{echo $event->getContent();} ?></p>
+
+					<!--<a href="index.php?action=readFeedEvent&feed=<?php echo $feed->getId(); ?>&event=<?php echo $event->getId(); ?>">Lire la suite</a>-->
+				</section>
+				<?php } ?>
+
+				<p>Page <?php echo $page; ?>/<?php echo $pages; ?> : <?php for($i=1;$i<$pages+1;$i++){ ?> <a href="index.php?action=readFeed&feed=<?php echo $currentFeed->getId(); ?>&page=<?php echo $i; ?>"><?php echo $i; ?></a> | <?php } ?> </p>
+			</article>
+			<?php } ?>
+			
+			
+			
+		</div> <!-- #main -->
+
+<?php require_once('footer.php'); ?>

+ 188 - 0
install.php

@@ -0,0 +1,188 @@
+<?php require_once('common.php'); ?>
+
+
+<!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></title>
+	<meta name="description" content="">
+	<meta name="author" content="">
+
+	<meta name="viewport" content="width=device-width">
+
+	<link rel="stylesheet" href="css/style.css">
+
+	<script src="js/libs/modernizr-2.5.3-respond-1.1.0.min.js"></script>
+</head>
+<body>
+	<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>
+
+
+	<div id="main-container">
+
+<div id="main" class="wrapper clearfix">
+
+
+
+			<?php
+if(isset($_['installButton'])){
+	//Création de la base et des tables
+	$feedManager->create();
+	$eventManager->create();
+	$userManager->create();
+	$folderManager->create();
+	$configurationManager->create();
+	//Ajout de l'administrateur
+	$admin = new User();
+	$admin->setLogin($_['login']);
+	$admin->setPassword($_['password']);
+	$admin->save();
+	//Identification de l'utilisateur en session
+	$_SESSION['currentUser'] = serialize($admin);
+	//Ajout des préférences et reglages
+	$configurationManager->put('root',$_['root']);
+	//$configurationManager->put('view',$_['view']);
+	$configurationManager->put('articleView',$_['articleView']);
+
+	$configurationManager->put('articlePerPages',$_['articlePerPages']);
+	$configurationManager->put('articleDisplayLink',$_['articleDisplayLink']);
+	$configurationManager->put('articleDisplayDate',$_['articleDisplayDate']);
+	$configurationManager->put('articleDisplayAuthor',$_['articleDisplayAuthor']);
+	//Création du dossier de base
+	$folder = new Folder();
+	$folder->setName($_['category']);
+	$folder->setParent(-1);
+	$folder->setIsopen(1);
+	$folder->save();
+	
+
+?>
+
+	 <article style="width:100%;">
+				<header>
+					<h1>Installation de Leed termin&eacute;e</h1>
+					<p>L'installation de Leed est termin&eacute;e, n'oubliez pas de mettre en place le CRON adapt&eacute; pour que vos flux se mettent &agrave; jour, exemple :</p>
+
+					<code>sudo crontab -e</code>
+					<p>Dans le fichier qui s'ouvre ajoutez la ligne :</p>
+					<code>0 * * * * wget -q -O /var/www/leed/logsCron http://127.0.0.1/leed/action.php?action=synchronize</code>
+					<p>Quittez et sauvegardez le fichier.</p>
+					<p>Cet exemple mettra &agrave; jour vos flux toutes les heures et ajoutera le rapport de mise a jour sous le nom "logsCron" dans votre dossier leed</p>
+	 				<p>N'oubliez pas de supprimer la page install.php par mesure de s&eacute;curit&eacute;</p>
+	 				<p>Cliquez <a style="color:#F16529;" href="index.php">ici</a> pour acceder au script</p>
+	 <?php
+}else{
+?>
+
+			<aside>
+				<h3 class="left">Verifications</h3> 
+				<ul class="clear" style="margin:0">
+
+						<?php 
+
+						if(!is_writable('./')){
+							$test['Erreur'][]='Ecriture impossible dans le repertoire Leed, veuillez ajouter les permissions en ecriture sur tous le dossier (sudo chmod 777 -R /var/www/leed/)';
+						}else{
+							$test['Succ&egrave;s'][]='Permissions sur le dossier courant : OK';
+						}
+
+						if (!@function_exists('file_get_contents')){
+							 $test['Erreur'][] = 'La fonction requise "file_get_contents" est inaccessible sur votre serveur, verifiez votre version de PHP.';
+						}else{
+							 $test['Succ&egrave;s'][] = 'Fonction requise "file_get_contents" : OK';	
+						}
+						if (!@function_exists('file_put_contents')){
+							 $test['Erreur'][] = 'La fonction requise "file_put_contents" est inaccessible sur votre serveur, verifiez votre version de PHP.';
+						}else{
+							 $test['Succ&egrave;s'][] = 'Fonction requise "file_put_contents" : OK';	
+						}
+						if (@version_compare(PHP_VERSION, '4.3.0') <= 0){
+						 $test['Erreur'][] = 'Votre version de PHP ('.PHP_VERSION.') est trop ancienne, il est possible que certaines fonctionalitees du script comportent des disfonctionnements.';
+						}else{
+						 $test['Succ&egrave;s'][] = 'Compabilit&eacute; de version PHP ('.PHP_VERSION.') : OK';	
+						}
+
+						if (!@extension_loaded('sqlite3')){
+						 $test['Erreur'][] = 'L\'Extension Sqlite3 n\'est pas activ&eacute;e sur votre serveur, merci de bien vouloir l\'installer';
+						}else{
+						 $test['Succ&egrave;s'][] = 'Extension Sqlite3 : OK';	
+						}
+
+						foreach($test as $type=>$messages){
+						?>
+						<li style="font-size:10px;color:#ffffff;background-color:<?php echo ($type=='Erreur'?'#F16529':'#008000'); ?>"><?php echo $type; ?> :<ul><?php foreach($messages as $message){?><li style="border:1px solid #212121"><?php echo $message; ?></li><?php } ?></ul></li><li>&nbsp;</li>
+						<?php } ?>
+				</ul>
+			</aside>
+
+	<?php  if(!isset($test['Erreur'])){ ?>		
+	<form action="install.php" method="POST">
+			<article>
+				<header>
+					<h1>Installation de Leed</h1>
+					<p>Merci de prendre quelques instants pour v&eacute;rifier les infos ci dessous :</p>
+				
+				</header>
+			
+				<section>
+					<h2>G&eacute;n&eacute;ral</h2>
+					<p>Racine du projet : <input type="text" name="root" value="<?php echo str_replace(basename(__FILE__),'','http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); ?>"></p>
+					<h3>Laissez bien un "/" en fin de chaine ex : http://monsite.com/leed/</h3>
+				</section>
+
+				<section>
+					<h2>Administrateur</h2>
+					<p>Identifiant de l'administrateur: <input type="text" name="login" placeholder="Identifiant"></p>
+					<p>Mot de passe de l'administrateur: <input type="text" name="password" placeholder="Mot de passe"></p>
+					<h3>Si vous perdez vos identifiants admin, supprimez le fichier database.db pour reinitialiser le script (nb: l'ensemble des donn&eacute;es seront perdues)</h3>
+				</section>