Browse Source

Merge branch 'master' of https://github.com/ldleman/hackpoint

Conflicts:
	action.php
	class/Type.class.php
	component.php
	constant.php
	function.php
Idleman 7 years ago
parent
commit
6b442a5350
20 changed files with 1155 additions and 953 deletions
  1. 23 0
      README.md
  2. 3 1
      account.php
  3. 49 42
      class/Action.class.php
  4. 138 139
      class/Configuration.class.php
  5. 44 35
      class/Database.class.php
  6. 37 32
      class/Dictionnary.class.php
  7. 527 437
      class/Entity.class.php
  8. 31 30
      class/Log.class.php
  9. 28 28
      class/Part.class.php
  10. 27 27
      class/Resource.class.php
  11. 19 23
      class/ResourcePart.class.php
  12. 27 27
      class/Sketch.class.php
  13. 51 46
      class/User.class.php
  14. 22 24
      common.php
  15. 37 3
      css/main.css
  16. 4 2
      footer.php
  17. 8 5
      header.php
  18. 1 1
      index.php
  19. 37 28
      install.php
  20. 42 23
      sketch.php

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
+# Hackpoint
+Hackpoint est un projet PHP/sqlite gratuit permettant la gestion de projets éléctroniques/codes 
+ou tout autre type de projets devant être sauvegardé/partagés.
+
+## Pré-requis
+- Serveur HTTP (Apache2 conseillé)
+- PHP5
+- SQLITE3
+- EXTENSION PHP-GD
+
+
+## Installation
+### En ligne de commande
+- Installez les pré-requis ``sudo apt-get install git apache2 php5 php5-sqlite php-gd``
+- Clonez le dépot hackpoint ``git clone https://github.com/ldleman/hackpoint.git /var/www/html/hackpoint``
+- Réglez les permissions ``sudo chown -r www-data:www-data /var/www/html/hackpoint``
+- Depuis un navigateur, lancez le script, le programme est installé.
+
+### Manuelle
+- Assurez vous que votre serveur comprends bien les prérequis sqlite et DG
+- Téléchargez le zip de l'application et décompressez le dans votre répertoire /www
+- Autorisez l'écriture sur les répertoires /data et /upload
+- Depuis un navigateur, lancez le script, le programme est installé.

+ 3 - 1
account.php

@@ -1,6 +1,8 @@
 <?php require_once __DIR__.DIRECTORY_SEPARATOR.'header.php'; ?>
 
-	<?php if(!$myUser->connected()) header('location: index.php'); ?>
+	<?php if (!$myUser->connected()) {
+    header('location: index.php');
+} ?>
 
 		<div class="jumbotron">
 			<div class="jumbotron-contents">

+ 49 - 42
class/Action.class.php

@@ -1,44 +1,51 @@
 <?php
 
-	/**
-	* Execute an action (request which no need html view response: ajax,json etc...) and manage automatically
-	* access rights, exceptions and json response.
-	* @author valentin carruesco
-	* @category Core
-	* @license cc by nc sa
-	*/
-	
-	class Action{
-
-		/**
-		* Execute an action 
-		* #### Example
-		* ```php
-		* Action::write(function($_,&$response){ 
-		*	$response['custom'] = 'hello world!'; 
-		* },array('user'=>'u','plugin'=>'d')); //User must have user update right and delete plugin right to perform this action
-		* ```
-		* @param function action/code to execute
-		* @param array Array wich contain right to execute action
-		* @return print json response
-		*/
-
-		public static function write($f,$p=array()){
-			global $myUser,$_,$conf;
-			header('content-type:application/json');
-			$response = array('errors' => array());
-			set_error_handler(function($level,$error,$file,$line){ throw new Exception($error." \r\n\r\n  ".$file." - L ".$line."");});
-			try{
-				foreach ($p as $section => $right) {
-					if(!$myUser->can($section,$right)) throw new Exception('Vous ne disposez pas des droits suffisants pour effectuer cette action');
-				}
-				$f($_,$response);
-				if(!isset($response['errors'])) $response['errors'] = array();
-			}catch(Exception $e){
-				$response['errors'][] = $e->getMessage();
-			}
-			echo json_encode($response);
-			restore_error_handler();
-		}
-	}
-?>
+/**
+ * Execute an action (request which no need html view response: ajax,json etc...) and manage automatically
+ * access rights, exceptions and json response.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license cc by nc sa
+ */
+class Action
+{
+    /**
+     * Execute an action 
+     * #### Example
+     * ```php
+     * Action::write(function($_,&$response){ 
+     *	$response['custom'] = 'hello world!'; 
+     * },array('user'=>'u','plugin'=>'d')); //User must have user update right and delete plugin right to perform this action
+     * ```.
+     *
+     * @param function action/code to execute
+     * @param array Array wich contain right to execute action
+     *
+     * @return print json response
+     */
+    public static function write($f, $p = array())
+    {
+        global $myUser,$_,$conf;
+        header('content-type:application/json');
+        $response = array('errors' => array());
+        set_error_handler(function ($level, $error, $file, $line) { throw new Exception($error." \r\n\r\n  ".$file.' - L '.$line.'');});
+        try {
+            foreach ($p as $section => $right) {
+                if (!$myUser->can($section, $right)) {
+                    throw new Exception('Vous ne disposez pas des droits suffisants pour effectuer cette action');
+                }
+            }
+            $f($_, $response);
+            if (!isset($response['errors'])) {
+                $response['errors'] = array();
+            }
+        } catch (Exception $e) {
+            $response['errors'][] = $e->getMessage();
+        }
+        echo json_encode($response);
+        restore_error_handler();
+    }
+}

+ 138 - 139
class/Configuration.class.php

@@ -1,143 +1,142 @@
 <?php
 
 /**
-* Manage application and plugins configurations with key/value pair
-* 
-* **nb:** It's possible to specify namespace in order to distinct global configuration to plugin custom configuration
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
-
-class Configuration extends Entity{
-
-	protected $id,$key,$value,$confTab;
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'key'=>'longstring',
-		'value'=>'longstring'
-	);
-
-
-
-	/**
-	* Get all configurations from database OR session if it was yet loaded
-	* This function is called at start of program and global var '$conf' is filled with response, so use global $conf instead of call this function.
-	* #### Example
-	* ```php
-	* $confs = Configuration::getAll();
-	* var_dump($confs);
-	* ```
-	* @return array Array of configurations
-	*/
-
-	public function getAll(){
-		
-		if(!isset($_SESSION['configuration'])){
-	
-		$configurationManager = new Configuration();
-		$configs = $configurationManager->populate();
-		$confTab = array();
-
-		foreach($configs as $config){
-			$this->confTab[$config->getKey()] = Functions::decrypt($config->getValue());
-		}
-
-		$_SESSION['configuration'] = serialize($this->confTab);
-		
-		}else{
-			$this->confTab = unserialize($_SESSION['configuration']);
-
-		}
-		
-	}
-
-
-	/**
-	* Get configuration value from it key
-	* #### Example
-	* ```php
-	* global $conf; // global var, contain configurations
-	* echo $conf->get('myConfigKey'); // print myConfigKey value
-	* ```
-	* @param string configuration key
-	* @param string configuration namespace (default is 'conf')
-	* @return string valeur de la configuration
-	*/
-	public function get($key){
-
-		return (isset($this->confTab[$key])?$this->confTab[$key]:'');
-	}
-
-	/**
-	* Update or insert configuration value in database with specified key
-	* #### Example
-	* ```php
-	* global $conf; // global var, contain configurations
-	* echo $conf->put('myNewConfigKey','hello!'); //create configuration myNewConfigKey with value 'hello!'
-	* echo $conf->put('myNewConfigKey','hello 2!'); //update configuration myNewConfigKey with value 'hello2!'
-	* ```
-	* @param string configuration key
-	* @param string configuration value
-	* @param string configuration namespace (default is 'conf')
-	*/
-	public function put($key,$value){
-		$secured_value = Functions::crypt($value);
-		$configurationManager = new Configuration();
-		if (isset($this->confTab[$key])){
-			$configurationManager->change(array('value'=>$secured_value),array('key'=>$key));
-		} else {
-			$configurationManager->add($key,$secured_value);	
-		}
-		$this->confTab[$key] = $value;
-		unset($_SESSION['configuration']);
-	}
-
-	/**
-	* Remove configuration value in database with specified key
-	* #### Example
-	* ```php
-	* global $conf; // global var, contain configurations
-	* echo $conf->remove('myNewConfigKey'); //delete myNewConfigKey from 'conf' default namespace 
-	* echo $conf->remove('myNewConfigKey','myCustomPluginConfig'); //delete myNewConfigKey from 'myCustomPluginConfig' namespace
-	* ```
-	* @param string configuration key
-	* @param string configuration namespace (default is 'conf')
-	*/
-	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;
-	}
-
-
-
-
+ * Manage application and plugins configurations with key/value pair.
+ * 
+ * **nb:** It's possible to specify namespace in order to distinct global configuration to plugin custom configuration
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Configuration extends Entity
+{
+    protected $id,$key,$value,$confTab;
+    protected $fields =
+    array(
+        'id' => 'key',
+        'key' => 'longstring',
+        'value' => 'longstring',
+    );
+
+    /**
+     * Get all configurations from database OR session if it was yet loaded
+     * This function is called at start of program and global var '$conf' is filled with response, so use global $conf instead of call this function.
+     * #### Example
+     * ```php
+     * $confs = Configuration::getAll();
+     * var_dump($confs);
+     * ```.
+     *
+     * @return array Array of configurations
+     */
+    public function getAll()
+    {
+        if (!isset($_SESSION['configuration'])) {
+            $configurationManager = new self();
+            $configs = $configurationManager->populate();
+            $confTab = array();
+
+            foreach ($configs as $config) {
+                $this->confTab[$config->getKey()] = Functions::decrypt($config->getValue());
+            }
+
+            $_SESSION['configuration'] = serialize($this->confTab);
+        } else {
+            $this->confTab = unserialize($_SESSION['configuration']);
+        }
+    }
+
+    /**
+     * Get configuration value from it key
+     * #### Example
+     * ```php
+     * global $conf; // global var, contain configurations
+     * echo $conf->get('myConfigKey'); // print myConfigKey value
+     * ```.
+     *
+     * @param string configuration key
+     * @param string configuration namespace (default is 'conf')
+     *
+     * @return string valeur de la configuration
+     */
+    public function get($key)
+    {
+        return isset($this->confTab[$key]) ? $this->confTab[$key] : '';
+    }
+
+    /**
+     * Update or insert configuration value in database with specified key
+     * #### Example
+     * ```php
+     * global $conf; // global var, contain configurations
+     * echo $conf->put('myNewConfigKey','hello!'); //create configuration myNewConfigKey with value 'hello!'
+     * echo $conf->put('myNewConfigKey','hello 2!'); //update configuration myNewConfigKey with value 'hello2!'
+     * ```.
+     *
+     * @param string configuration key
+     * @param string configuration value
+     * @param string configuration namespace (default is 'conf')
+     */
+    public function put($key, $value)
+    {
+        $secured_value = Functions::crypt($value);
+        $configurationManager = new self();
+        if (isset($this->confTab[$key])) {
+            $configurationManager->change(array('value' => $secured_value), array('key' => $key));
+        } else {
+            $configurationManager->add($key, $secured_value);
+        }
+        $this->confTab[$key] = $value;
+        unset($_SESSION['configuration']);
+    }
+
+    /**
+     * Remove configuration value in database with specified key
+     * #### Example
+     * ```php
+     * global $conf; // global var, contain configurations
+     * echo $conf->remove('myNewConfigKey'); //delete myNewConfigKey from 'conf' default namespace 
+     * echo $conf->remove('myNewConfigKey','myCustomPluginConfig'); //delete myNewConfigKey from 'myCustomPluginConfig' namespace
+     * ```.
+     *
+     * @param string configuration key
+     * @param string configuration namespace (default is 'conf')
+     */
+    public function add($key, $value)
+    {
+        $config = new self();
+        $config->setKey($key);
+        $config->setValue($value);
+        $config->save();
+        $this->confTab[$key] = $value;
+        unset($_SESSION['configuration']);
+    }
+
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+    public function setKey($key)
+    {
+        $this->key = $key;
+    }
+
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    public function setValue($value)
+    {
+        $this->value = $value;
+    }
 }
-
-?>

+ 44 - 35
class/Database.class.php

@@ -1,42 +1,51 @@
 <?php
 
 /**
-* PDO Connector for database connexion.
-* @author v.carruesco
-* @category Core
-* @license copyright
-*/
+ * PDO Connector for database connexion.
+ *
+ * @author v.carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
 class Database
 {
-	public $connection = null;
-	public static $instance = null;
-	private function __construct(){
-		$this->connect();
-	}
+    public $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 <pdo> $instance
-	*/
-	public static function instance(){
-		if (Database::$instance === null) {
-			Database::$instance = new self(); 
-		}
-		return Database::$instance->connection;
-	}
-	
-	public function connect(){
-		try {
-			$this->connection = new PDO(BASE_CONNECTION_STRING, BASE_LOGIN, BASE_PASSWORD);
-			$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-			
-		} catch ( Exception $e ) {
-		  echo "Connection à la base impossible : ", $e->getMessage();
-		  die();
-		}
-	}
+    /**
+     * Methode de recuperation unique de l'instance.
+     *
+     * @author Valentin CARRUESCO
+     *
+     * @category Singleton
+     *
+     * @param <Aucun>
+     *
+     * @return <pdo> $instance
+     */
+    public static function instance()
+    {
+        if (self::$instance === null) {
+            self::$instance = new self();
+        }
+
+        return self::$instance->connection;
+    }
+
+    public function connect()
+    {
+        try {
+            $this->connection = new PDO(BASE_CONNECTION_STRING, BASE_LOGIN, BASE_PASSWORD);
+            $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+        } catch (Exception $e) {
+            echo 'Connection à la base impossible : ', $e->getMessage();
+            die();
+        }
+    }
 }
-?>

+ 37 - 32
class/Dictionnary.class.php

@@ -1,42 +1,50 @@
 <?php
 /**
-* Manage application and plugins lists with key/value pair
+* Manage application and plugins lists with key/value pair.
 * 
 * @author valentin carruesco
+*
 * @category Core
+*
 * @license copyright
 */
+class Dictionnary extends Entity
+{
+    public $id,$slug,$label,$parent,$state;
+    protected $fields =
+    array(
+        'id' => 'key',
+        'slug' => 'string',
+        'label' => 'longstring',
+        'parent' => 'int',
+        'state' => 'int',
+    );
 
-class Dictionnary extends Entity {
-	public $id,$slug,$label,$parent,$state;
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'slug'=>'string',
-		'label'=>'longstring',
-		'parent'=>'int',
-		'state'=>'int'
-	);
+    public function __construct()
+    {
+        parent::__construct();
+    }
 
-	function __construct(){
-		parent::__construct();
-	}
+    public static function childs($slug, $sort = 'label ASC')
+    {
+        $obj = new self();
+        $childs = array();
+        $parent = $obj->load(array('slug' => $slug));
+        if (!$parent) {
+            return $childs;
+        }
+        foreach ($obj->loadAll(array('parent' => $parent->id), $sort) as $child) {
+            $childs[$child->id] = $child;
+        }
 
-	public static function childs($slug,$sort='label ASC'){
-		$obj = new self();
-		$childs = array();
-		$parent = $obj->load(array('slug'=>$slug));
-		if(!$parent) return $childs;
-		foreach($obj->loadAll(array('parent'=>$parent->id),$sort) as $child)
-			$childs[$child->id] = $child;
-		
-		return $childs;
-	}
+        return $childs;
+    }
 
-	public static function table($slug){
-		$obj = new self();
-		$parent = $obj->load(array('slug'=>$slug));
-		echo '<div class="table_list_'.$slug.'" data-list="'.$parent->id.'">
+    public static function table($slug)
+    {
+        $obj = new self();
+        $parent = $obj->load(array('slug' => $slug));
+        echo '<div class="table_list_'.$slug.'" data-list="'.$parent->id.'">
 					<label for="config_application_table"></label>
 					<table id="" class="table table-striped table-bordered table-hover">
 						<thead>
@@ -59,8 +67,5 @@ class Dictionnary extends Entity {
 						</tr>
 					</tbody></table>
 				</div>';
-	}
-
+    }
 }
-
-?>

+ 527 - 437
class/Entity.class.php

@@ -1,440 +1,530 @@
 <?php
-require_once(dirname(__FILE__).'/../constant.php');
+
+require_once dirname(__FILE__).'/../constant.php';
 
 /**
-	Classe mère 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.
-	@author: v.carruesco
-	@version 2
-**/
-
-
-	class Entity
-	{
-
-		public $debug = false,$pdo = null;
-		public static $lastError = '';
-		public static $lastQuery = '';
-
-
-		function __construct(){
-			$this->connect();
-		}
-
-		function connect(){
-			$this->pdo = Database::instance();
-			if(!isset($this->TABLE_NAME)) $this->TABLE_NAME = strtolower(get_called_class());
-		}
-
-		public function __toString(){
-			foreach($this->toArray() as $key=>$value){
-				echo $key.' : '.$value.','.PHP_EOL;
-			}
-        	
-    	}
-
-		public static function debug(){
-			return array(self::$lastQuery,self::$lastError);
-		}
-
-    	public function __sleep()
-		{
-		    return array_keys($this->toArray());
-		}
-
-		public function __wakeup()
-		{
-		    $this->connect();
-		}
-
-		function toArray(){
-			$fields = array();
-			foreach($this->fields as $field=>$type)
-				$fields[$field]= $this->$field;
-			return $fields;
-		}
-		function fromArray($array){
-			foreach($array as $field=>$value)
-				$this->$field = $value;
-		}
-
-		function sgbdType($type){
-			$types = array();
-			$types['string'] = $types['timestamp'] = $types['date'] = 'VARCHAR(255)';
-			$types['longstring'] = 'TEXT';
-			$types['key'] = 'INTEGER NOT NULL PRIMARY KEY';
-			$types['object'] = $types['integer'] = 'bigint(20)';
-			$types['boolean'] = 'INTEGER(1)';
-			$types['blob'] = ' BLOB';
-			$types['default'] = 'TEXT';
-			return isset($types[$type]) ? $types[$type] : $types['default'];
-		}
-
-
-		public function closeDatabase(){
-		//$this->close();
-		}
-
-		public static function tableName(){
-			$class = get_called_class();
-			$instance = new $class();
-			return ENTITY_PREFIX.$instance->TABLE_NAME;
-		}
-
-
-		// GESTION SQL
-
-		/**
-		* Verifie l'existence de la table en base de donnée
-		* @author Valentin CARRUESCO
-		* @category manipulation SQL
-		* @param <String> créé la table si elle n'existe pas
-		* @return true si la table existe, false dans le cas contraire
-		*/
-		public static function checkTable($autocreate = false){
-			$class = get_called_class();
-			$instance = new $class();
-			$query = 'SELECT count(*) as numRows FROM sqlite_master WHERE type="table" AND name=?';  
-			$statement = $instance->customQuery($query,array($instance->tableName()));
-
-			if($statement!=false){
-				$statement = $statement->fetchArray();
-				if($statement['numRows']==1){
-					$return = true;
-				}
-			}
-			if($autocreate && !$return) self::create();
-			return $return;
-		}
-		
-		public static function install($classDirectory){
-
-			foreach(glob($classDirectory.DIRECTORY_SEPARATOR.'*.class.php') as $file){
-				$infos = explode('.',basename($file));
-				$class = array_shift($infos);
-				if (!class_exists($class) || !method_exists ($class , 'create') || $class==get_class()) continue;
-				$class::create();
-			}
-		}
-	
-
-		/**
-		* Methode de creation de l'entité
-		* @author Valentin CARRUESCO
-		* @category manipulation SQL
-		* @return Aucun retour
-		*/
-		public static function create(){
-			$class = get_called_class();
-			$instance = new $class();
-			$query = 'CREATE TABLE IF NOT EXISTS `'.ENTITY_PREFIX.$instance->TABLE_NAME.'` (';
-
-				foreach($instance->fields as $field=>$type)
-					$query .='`'.$field.'`  '. $instance->sgbdType($type).' ,';
-
-				$query = substr($query,0,strlen($query)-1);
-				$query .= ');';
-			$instance->customExecute($query);
-		}
-
-		public static function drop(){
-			$class = get_called_class();
-			$instance = new $class();
-			$query = 'DROP TABLE `'.$instance->tableName().'`;';
-			$instance->customExecute($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(){
-			$data = array();
-			if(isset($this->id) && $this->id>0){
-				$query = 'UPDATE `'.ENTITY_PREFIX.$this->TABLE_NAME.'` SET ';
-				foreach($this->fields as $field=>$type){
-					$value = $this->{$field};
-					$query .= '`'.$field.'`=?,';
-					$data[] = $value;
-				}
-				$query = substr($query,0,strlen($query)-1);
-				$data[] = $this->id;
-				$query .= ' WHERE `id`=?;';
-			}else{
-				$query = 'INSERT INTO `'.$this->tableName().'`(';
-					foreach($this->fields as $field=>$type){
-						if($type!='key')
-							$query .='`'.$field.'`,';
-					}
-					$query = substr($query,0,strlen($query)-1);
-					$query .=')VALUES(';
-					
-					foreach($this->fields as $field=>$type){
-						if($type=='key') continue;
-						$query .='?,';
-						$data[] = $this->{$field};
-					}
-					$query = substr($query,0,strlen($query)-1);
-
-					$query .=');';
-				}
-				$this->customExecute($query,$data);
-				
-				$this->id =  (!isset($this->id) || !(is_numeric($this->id))?$this->pdo->lastInsertId():$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
-		* @return Aucun retour
-		*/
-		public static function change($columns,$columns2=null,$operation='='){
-			$class = get_called_class();
-			$instance = new $class();
-			$data = array();
-			$query = 'UPDATE `'.$instance->tableName().'` SET ';
-
-			foreach ($columns as $column=>$value){
-				$query .= '`'.$column.'`=?,';
-				$data[] = $value;
-			}
-			$query = substr($query,0,strlen($query)-1);
-			if($columns2!=null){
-				$query .=' WHERE '; 
-				
-				foreach ($columns2 as $column=>$value){
-					$query .= '`'.$column.'`'.$operation.'?,';
-					$data[] = $value;
-				}
-				$query = substr($query,0,strlen($query)-1);
-			}
-			$instance->customExecute($query,$data);
-		}
-
-		/**
-		* 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
-		* @return <Array<Entity>> $Entity
-		*/
-		public static function populate($order=null,$limit=null){
-			$results = self::loadAll(array(),$order,$limit,'=');
-			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
-		* @return <Array<Entity>> $Entity
-		*/
-		public static function loadAll($columns=array(),$order=null,$limit=null,$operation="=",$selColumn='*'){
-			$objects = array();
-			$whereClause = '';
-			$data = array();
-			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.'?';
-					$data[] = $value;
-				}
-			}
-
-			$class = get_called_class();
-			$instance = new $class();
-			$query = 'SELECT '.$selColumn.' FROM `'.$instance->tableName().'` '.$whereClause.' ';
-			
-			if($order!=null) $query .='ORDER BY '.$order.' ';
-			if($limit!=null) $query .='LIMIT '.$limit.' ';
-			$query .=';';
-			return $instance->customQuery($query,$data,true);
-		}
-
-		public static function loadAllOnlyColumn($selColumn,$columns,$order=null,$limit=null,$operation="="){
-			$objects = self::loadAll($columns,$order,$limit,$operation,$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
-		* @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
-		*/
-		public static function load($columns,$operation='='){
-			$objects = self::loadAll($columns,null,'1',$operation);
-			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
-		* @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
-		*/
-		public static function getById($id,$operation='='){
-			return self::load(array('id'=>$id),$operation);
-		}
-
-		/**
-		* Methode de comptage des éléments de l'entité
-		* @author Valentin CARRUESCO
-		* @category manipulation SQL
-		* @return<Integer> nombre de ligne dans l'entité'
-		*/
-		public static function rowCount($columns=null)
-		{
-			$class = get_called_class();
-			$instance = new $class();
-			$whereClause ='';
-			$data = array();
-			if($columns!=null){
-				$whereClause = ' WHERE ';
-				$i=false;
-				foreach($columns as $column=>$value){
-					if($i){$whereClause .=' AND ';}else{$i=true;}
-					$whereClause .= '`'.$column.'`=?';
-					$data[] = $value;
-				}
-			}
-			$query = 'SELECT COUNT(id) resultNumber FROM '.$instance->tableName().$whereClause;
-			
-			$execQuery = $instance->customQuery($query,$data);
-			$row = $execQuery->fetch();
-
-			return $row['resultNumber'];
-		}	
-
-		/**
-		* Methode de définition de l'éxistence d'un moins un des éléments spécifiés en base
-		* @author Valentin CARRUESCO
-		* @category manipulation SQL
-		* @return<boolean> existe (true) ou non (false)
-		*/
-		public static function exist($columns=null)
-		{
-			$result = self::rowCount($columns);
-
-			return ($result!=0);
-		}	
-
-		public static function deleteById($id){
-			
-			self::delete(array('id'=>$id));
-		}
-		/**
-		* 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
-		* @return Aucun retour
-		*/
-		public static function delete($columns,$operation='=',$limit=null){
-			
-			$class = get_called_class();
-			$instance = new $class();
-			$whereClause = '';
-			$i=false;
-			$data = array();
-			foreach($columns as $column=>$value){
-				if($i){$whereClause .=' AND ';}else{$i=true;}
-				$whereClause .= '`'.$column.'`'.$operation.'?';
-				$data[]=$value; 
-			}
-			$query = 'DELETE FROM `'.ENTITY_PREFIX.$instance->TABLE_NAME.'` WHERE '.$whereClause.' '.(isset($limit)?'LIMIT '.$limit:'').';';
-			$instance->customExecute($query,$data);
-		}
-		
-		public function customExecute($query,$data = array()){
-			self::$lastQuery = $query;
-			$stm = $this->pdo->prepare($query);
-			try{
-				$stm->execute($data);
-			}catch(Exception $e){
-				self::$lastError = $this->pdo->errorInfo();
-				throw new Exception($e->getMessage());
-			}
-			
-		}
-
-		public static function staticQuery($query,$data = array(),$fill = false){
-			$class = get_called_class();
-			$instance = new $class();
-			return $instance->customQuery($query,$data,$fill);
-		}
-
-		public function customQuery($query,$data = array(),$fill = false){
-			self::$lastQuery = $query;
-			
-			$results = $this->pdo->prepare($query);
-			
-			$results->execute($data);
-			
-			if(!$results){
-				self::$lastError = $this->pdo->errorInfo();
-				return false;
-			}else{
-
-				if(!$fill)	return $results;
-
-				$class = get_class($this);
-				$objects = array();
-				while($queryReturn = $results->fetch() ){
-					$object = new $class();
-					foreach($this->fields as $field=>$type){
-						if(isset($queryReturn[$field]))
-							$object->{$field} =  $queryReturn[$field];
-					}
-					$objects[] = $object;
-					unset($object);
-				}
-				
-				return $objects == null?array()  : $objects;
-			}
-		}
-
-
-		public function __get($name)
-		{
-				$pos = strpos($name,'_object');
-				if($pos!==false){
-					$field = strtolower(substr($name,0,$pos));
-					if(array_key_exists($field,$this->fields)){
-						$class = ucfirst($field);
-						return $class::getById($this->{$field});
-					}
-				}
-				throw new Exception("Attribut ".get_class($this)."->$name non existant");
-		}
-	}
-?>
+ @version 2
+ **/
+class Entity
+{
+    public $debug = false,$pdo = null;
+    public static $lastError = '';
+    public static $lastQuery = '';
+
+    public function __construct()
+    {
+        $this->connect();
+    }
+
+    public function connect()
+    {
+        $this->pdo = Database::instance();
+        if (!isset($this->TABLE_NAME)) {
+            $this->TABLE_NAME = strtolower(get_called_class());
+        }
+    }
+
+    public function __toString()
+    {
+        foreach ($this->toArray() as $key => $value) {
+            echo $key.' : '.$value.','.PHP_EOL;
+        }
+    }
+
+    public static function debug()
+    {
+        return array(self::$lastQuery, self::$lastError);
+    }
+
+    public function __sleep()
+    {
+        return array_keys($this->toArray());
+    }
+
+    public function __wakeup()
+    {
+        $this->connect();
+    }
+
+    public function toArray()
+    {
+        $fields = array();
+        foreach ($this->fields as $field => $type) {
+            $fields[$field] = $this->$field;
+        }
+
+        return $fields;
+    }
+
+    public function fromArray($array)
+    {
+        foreach ($array as $field => $value) {
+            $this->$field = $value;
+        }
+    }
+
+    public function sgbdType($type)
+    {
+        $types = array();
+        $types['string'] = $types['timestamp'] = $types['date'] = 'VARCHAR(255)';
+        $types['longstring'] = 'TEXT';
+        $types['key'] = 'INTEGER NOT NULL PRIMARY KEY';
+        $types['object'] = $types['integer'] = 'bigint(20)';
+        $types['boolean'] = 'INTEGER(1)';
+        $types['blob'] = ' BLOB';
+        $types['default'] = 'TEXT';
+
+        return isset($types[$type]) ? $types[$type] : $types['default'];
+    }
+
+    public function closeDatabase()
+    {
+        //$this->close();
+    }
+
+    public static function tableName()
+    {
+        $class = get_called_class();
+        $instance = new $class();
+
+        return ENTITY_PREFIX.$instance->TABLE_NAME;
+    }
+
+        // GESTION SQL
+
+        /**
+         * Verifie l'existence de la table en base de donnée.
+         *
+         * @author Valentin CARRUESCO
+         *
+         * @category manipulation SQL
+         *
+         * @param <String> créé la table si elle n'existe pas
+         *
+         * @return true si la table existe, false dans le cas contraire
+         */
+        public static function checkTable($autocreate = false)
+        {
+            $class = get_called_class();
+            $instance = new $class();
+            $query = 'SELECT count(*) as numRows FROM sqlite_master WHERE type="table" AND name=?';
+            $statement = $instance->customQuery($query, array($instance->tableName()));
+
+            if ($statement != false) {
+                $statement = $statement->fetchArray();
+                if ($statement['numRows'] == 1) {
+                    $return = true;
+                }
+            }
+            if ($autocreate && !$return) {
+                self::create();
+            }
+
+            return $return;
+        }
+
+    public static function install($classDirectory)
+    {
+        foreach (glob($classDirectory.DIRECTORY_SEPARATOR.'*.class.php') as $file) {
+            $infos = explode('.', basename($file));
+            $class = array_shift($infos);
+            if (!class_exists($class) || !method_exists($class, 'create') || $class == get_class()) {
+                continue;
+            }
+            $class::create();
+        }
+    }
+
+        /**
+         * Methode de creation de l'entité.
+         *
+         * @author Valentin CARRUESCO
+         *
+         * @category manipulation SQL
+         *
+         * @return Aucun retour
+         */
+        public static function create()
+        {
+            $class = get_called_class();
+            $instance = new $class();
+            $query = 'CREATE TABLE IF NOT EXISTS `'.ENTITY_PREFIX.$instance->TABLE_NAME.'` (';
+
+            foreach ($instance->fields as $field => $type) {
+                $query .= '`'.$field.'`  '.$instance->sgbdType($type).' ,';
+            }
+
+            $query = substr($query, 0, strlen($query) - 1);
+            $query .= ');';
+            $instance->customExecute($query);
+        }
+
+    public static function drop()
+    {
+        $class = get_called_class();
+        $instance = new $class();
+        $query = 'DROP TABLE `'.$instance->tableName().'`;';
+        $instance->customExecute($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()
+    {
+        $data = array();
+        if (isset($this->id) && $this->id > 0) {
+            $query = 'UPDATE `'.ENTITY_PREFIX.$this->TABLE_NAME.'` SET ';
+            foreach ($this->fields as $field => $type) {
+                $value = $this->{$field};
+                $query .= '`'.$field.'`=?,';
+                $data[] = $value;
+            }
+            $query = substr($query, 0, strlen($query) - 1);
+            $data[] = $this->id;
+            $query .= ' WHERE `id`=?;';
+        } else {
+            $query = 'INSERT INTO `'.$this->tableName().'`(';
+            foreach ($this->fields as $field => $type) {
+                if ($type != 'key') {
+                    $query .= '`'.$field.'`,';
+                }
+            }
+            $query = substr($query, 0, strlen($query) - 1);
+            $query .= ')VALUES(';
+
+            foreach ($this->fields as $field => $type) {
+                if ($type == 'key') {
+                    continue;
+                }
+                $query .= '?,';
+                $data[] = $this->{$field};
+            }
+            $query = substr($query, 0, strlen($query) - 1);
+
+            $query .= ');';
+        }
+        $this->customExecute($query, $data);
+
+        $this->id = (!isset($this->id) || !(is_numeric($this->id)) ? $this->pdo->lastInsertId() : $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
+     *
+     * @return Aucun retour
+     */
+    public static function change($columns, $columns2 = null, $operation = '=')
+    {
+        $class = get_called_class();
+        $instance = new $class();
+        $data = array();
+        $query = 'UPDATE `'.$instance->tableName().'` SET ';
+
+        foreach ($columns as $column => $value) {
+            $query .= '`'.$column.'`=?,';
+            $data[] = $value;
+        }
+        $query = substr($query, 0, strlen($query) - 1);
+        if ($columns2 != null) {
+            $query .= ' WHERE ';
+
+            foreach ($columns2 as $column => $value) {
+                $query .= '`'.$column.'`'.$operation.'?,';
+                $data[] = $value;
+            }
+            $query = substr($query, 0, strlen($query) - 1);
+        }
+        $instance->customExecute($query, $data);
+    }
+
+    /**
+     * 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
+     *
+     * @return <Array<Entity>> $Entity
+     */
+    public static function populate($order = null, $limit = null)
+    {
+        $results = self::loadAll(array(), $order, $limit, '=');
+
+        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
+     *
+     * @return <Array<Entity>> $Entity
+     */
+    public static function loadAll($columns = array(), $order = null, $limit = null, $operation = '=', $selColumn = '*')
+    {
+        $objects = array();
+        $whereClause = '';
+        $data = array();
+        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.'?';
+                $data[] = $value;
+            }
+        }
+
+        $class = get_called_class();
+        $instance = new $class();
+        $query = 'SELECT '.$selColumn.' FROM `'.$instance->tableName().'` '.$whereClause.' ';
+
+        if ($order != null) {
+            $query .= 'ORDER BY '.$order.' ';
+        }
+        if ($limit != null) {
+            $query .= 'LIMIT '.$limit.' ';
+        }
+        $query .= ';';
+
+        return $instance->customQuery($query, $data, true);
+    }
+
+    public static function loadAllOnlyColumn($selColumn, $columns, $order = null, $limit = null, $operation = '=')
+    {
+        $objects = self::loadAll($columns, $order, $limit, $operation, $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
+     *
+     * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
+     */
+    public static function load($columns, $operation = '=')
+    {
+        $objects = self::loadAll($columns, null, '1', $operation);
+        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
+     *
+     * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
+     */
+    public static function getById($id, $operation = '=')
+    {
+        return self::load(array('id' => $id), $operation);
+    }
+
+    /**
+     * Methode de comptage des éléments de l'entité.
+     *
+     * @author Valentin CARRUESCO
+     *
+     * @category manipulation SQL
+     * @return<Integer> nombre de ligne dans l'entité'
+     */
+    public static function rowCount($columns = null)
+    {
+        $class = get_called_class();
+        $instance = new $class();
+        $whereClause = '';
+        $data = array();
+        if ($columns != null) {
+            $whereClause = ' WHERE ';
+            $i = false;
+            foreach ($columns as $column => $value) {
+                if ($i) {
+                    $whereClause .= ' AND ';
+                } else {
+                    $i = true;
+                }
+                $whereClause .= '`'.$column.'`=?';
+                $data[] = $value;
+            }
+        }
+        $query = 'SELECT COUNT(id) resultNumber FROM '.$instance->tableName().$whereClause;
+
+        $execQuery = $instance->customQuery($query, $data);
+        $row = $execQuery->fetch();
+
+        return $row['resultNumber'];
+    }
+
+        /**
+         * Methode de définition de l'éxistence d'un moins un des éléments spécifiés en base.
+         *
+         * @author Valentin CARRUESCO
+         *
+         * @category manipulation SQL
+         * @return<boolean> existe (true) ou non (false)
+         */
+        public static function exist($columns = null)
+        {
+            $result = self::rowCount($columns);
+
+            return $result != 0;
+        }
+
+    public static function deleteById($id)
+    {
+        self::delete(array('id' => $id));
+    }
+        /**
+         * 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
+         *
+         * @return Aucun retour
+         */
+        public static function delete($columns, $operation = '=', $limit = null)
+        {
+            $class = get_called_class();
+            $instance = new $class();
+            $whereClause = '';
+            $i = false;
+            $data = array();
+            foreach ($columns as $column => $value) {
+                if ($i) {
+                    $whereClause .= ' AND ';
+                } else {
+                    $i = true;
+                }
+                $whereClause .= '`'.$column.'`'.$operation.'?';
+                $data[] = $value;
+            }
+            $query = 'DELETE FROM `'.ENTITY_PREFIX.$instance->TABLE_NAME.'` WHERE '.$whereClause.' '.(isset($limit) ? 'LIMIT '.$limit : '').';';
+            $instance->customExecute($query, $data);
+        }
+
+    public function customExecute($query, $data = array())
+    {
+        self::$lastQuery = $query;
+        $stm = $this->pdo->prepare($query);
+        try {
+            $stm->execute($data);
+        } catch (Exception $e) {
+            self::$lastError = $this->pdo->errorInfo();
+            throw new Exception($e->getMessage());
+        }
+    }
+
+    public static function staticQuery($query, $data = array(), $fill = false)
+    {
+        $class = get_called_class();
+        $instance = new $class();
+
+        return $instance->customQuery($query, $data, $fill);
+    }
+
+    public function customQuery($query, $data = array(), $fill = false)
+    {
+        self::$lastQuery = $query;
+
+        $results = $this->pdo->prepare($query);
+
+        $results->execute($data);
+
+        if (!$results) {
+            self::$lastError = $this->pdo->errorInfo();
+
+            return false;
+        } else {
+            if (!$fill) {
+                return $results;
+            }
+
+            $class = get_class($this);
+            $objects = array();
+            while ($queryReturn = $results->fetch()) {
+                $object = new $class();
+                foreach ($this->fields as $field => $type) {
+                    if (isset($queryReturn[$field])) {
+                        $object->{$field} = $queryReturn[$field];
+                    }
+                }
+                $objects[] = $object;
+                unset($object);
+            }
+
+            return $objects == null ? array()  : $objects;
+        }
+    }
+
+    public function __get($name)
+    {
+        $pos = strpos($name, '_object');
+        if ($pos !== false) {
+            $field = strtolower(substr($name, 0, $pos));
+            if (array_key_exists($field, $this->fields)) {
+                $class = ucfirst($field);
+
+                return $class::getById($this->{$field});
+            }
+        }
+        throw new Exception('Attribut '.get_class($this)."->$name non existant");
+    }
+}

+ 31 - 30
class/Log.class.php

@@ -1,35 +1,36 @@
 <?php
 
 /**
-* Log selected action in database with ip, datetime and optional logged user
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
-
-class Log extends Entity{
-
-	public $id,$label,$user,$date,$ip;
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'label'=>'longstring',
-		'user'=>'string',
-		'date'=>'string',
-		'ip'=>'string',
-	);
-
-
-	public static function put($label){
-		global $myUser;
-		$log = new Log();
-		$log->label = $label;
-		if(is_object($myUser) && $myUser->getLogin() !='') $log->user = $myUser->getLogin();
-		$log->date = time();
-		$log->ip = Functions::getIP();
-		$log->save();
-	}
+ * Log selected action in database with ip, datetime and optional logged user.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Log extends Entity
+{
+    public $id,$label,$user,$date,$ip;
+    protected $fields =
+    array(
+        'id' => 'key',
+        'label' => 'longstring',
+        'user' => 'string',
+        'date' => 'string',
+        'ip' => 'string',
+    );
 
+    public static function put($label)
+    {
+        global $myUser;
+        $log = new self();
+        $log->label = $label;
+        if (is_object($myUser) && $myUser->getLogin() != '') {
+            $log->user = $myUser->getLogin();
+        }
+        $log->date = time();
+        $log->ip = Functions::getIP();
+        $log->save();
+    }
 }
-
-?>

+ 28 - 28
class/Part.class.php

@@ -1,34 +1,34 @@
 <?php
 
 /**
-* Define a part
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
+ * Define a part.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Part extends Entity
+{
+    public $id,$label,$price,$link,$image,$owner,$brand;
 
+    protected $fields =
+    array(
+        'id' => 'key',
+        'label' => 'string',
+        'price' => 'string',
+        'link' => 'longstring',
+        'image' => 'longstring',
+        'brand' => 'longstring',
+        'owner' => 'int',
+    );
 
-class Part extends Entity{
-
-	public $id,$label,$price,$link,$image,$owner,$brand;
-	
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'label' => 'string',
-		'price' => 'string',
-		'link' => 'longstring',
-		'image' => 'longstring',
-		'brand' => 'longstring',
-		'owner' => 'int'
-	);
-
-
-	public function remove(){
-		Part::deleteById($this->id);
-		if(file_exists(PART_PATH.$this->image))
-			unlink(PART_PATH.$this->image);
-	}
+    public function remove()
+    {
+        self::deleteById($this->id);
+        if (file_exists(PART_PATH.$this->image)) {
+            unlink(PART_PATH.$this->image);
+        }
+    }
 }
-
-?>

+ 27 - 27
class/Resource.class.php

@@ -1,32 +1,32 @@
 <?php
 
 /**
-* Define a resource
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
+ * Define a resource.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Resource extends Entity
+{
+    public $id,$label,$type,$content,$sketch,$sort;
+    protected $fields =
+    array(
+        'id' => 'key',
+        'label' => 'string',
+        'sort' => 'int',
+        'type' => 'string',
+        'content' => 'longstring',
+        'sketch' => 'int',
+    );
 
-
-class Resource extends Entity{
-
-	public $id,$label,$type,$content,$sketch,$sort;
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'label' => 'string',
-		'sort' => 'int',
-		'type' => 'string',
-		'content' => 'longstring',
-		'sketch' => 'int'
-	);
-	
-	public function remove(){
-		Resource::deleteById($this->id);
-		if($this->type == 'image' && file_exists(SKETCH_PATH.$this->content))
-			unlink(SKETCH_PATH.$this->content);
-	}
-	
+    public function remove()
+    {
+        self::deleteById($this->id);
+        if ($this->type == 'image' && file_exists(SKETCH_PATH.$this->content)) {
+            unlink(SKETCH_PATH.$this->content);
+        }
+    }
 }
-
-?>

+ 19 - 23
class/ResourcePart.class.php

@@ -1,27 +1,23 @@
 <?php
 
 /**
-* Define a ResourcePart
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
-
-
-class ResourcePart extends Entity{
-
-	public $id,$resource,$part,$sort;
-	
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'resource' => 'int',
-		'part' => 'int',
-		'sort' => 'int'
-	);
-
-
-
+ * Define a ResourcePart.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class ResourcePart extends Entity
+{
+    public $id,$resource,$part,$sort;
+
+    protected $fields =
+    array(
+        'id' => 'key',
+        'resource' => 'int',
+        'part' => 'int',
+        'sort' => 'int',
+    );
 }
-
-?>

+ 27 - 27
class/Sketch.class.php

@@ -1,33 +1,33 @@
 <?php
 
 /**
-* Define a Sketch
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
+ * Define a Sketch.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Sketch extends Entity
+{
+    public $id,$label,$owner,$state,$public,$slug;
 
+    protected $fields =
+    array(
+        'id' => 'key',
+        'label' => 'string',
+        'owner' => 'int',
+        'state' => 'int',
+        'public' => 'int',
+        'slug' => 'string',
+    );
 
-class Sketch extends Entity{
-
-	public $id,$label,$owner,$state,$public,$slug;
-	
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'label' => 'string',
-		'owner' => 'int',
-		'state' => 'int',
-		'public' => 'int',
-		'slug' => 'string'
-	);
-
-	public  function save(){
-		if($this->id==0)
-			$this->slug = slugify($this->label);
-		parent::save();
-	}
-	
+    public function save()
+    {
+        if ($this->id == 0) {
+            $this->slug = slugify($this->label);
+        }
+        parent::save();
+    }
 }
-
-?>

+ 51 - 46
class/User.class.php

@@ -1,50 +1,55 @@
 <?php
 
 /**
-* Define an application user
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
-
-
-class User extends Entity{
-
-	public $id,$login,$password,$name,$firstname,$mail,$state,$rank,$rights;
-	protected $fields = 
-	array(
-		'id'=>'key',
-		'login'=>'string',
-		'password'=>'string',
-		'name'=>'string',
-		'firstname'=>'string',
-		'mail'=>'string',
-		'rank'=>'longstring',
-		'state'=>'int'
-	);
-
-	public static function check($login,$password){
-	    $user = self::load(array('login'=>$login,'password'=>self::password_encrypt($password)));
-		return is_object($user)?$user:new self;
-	}
-
-	function can($section,$selectedRight){
-		return (!isset($this->rights[$section])?false:$this->rights[$section][$selectedRight]);
-	}
-
-	function fullName(){
-		$fullName = ucfirst($this->firstname).' '.strtoupper($this->name);
-		return trim($fullName)!=''?$fullName:$this->login;
-	}
-
-	public static function password_encrypt($password){
-		return sha1(md5($password));
-	}
-	
-	public function connected(){
-		return $this->id!=0;
-	}
-
+ * Define an application user.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class User extends Entity
+{
+    public $id,$login,$password,$name,$firstname,$mail,$state,$rank,$rights;
+    protected $fields =
+    array(
+        'id' => 'key',
+        'login' => 'string',
+        'password' => 'string',
+        'name' => 'string',
+        'firstname' => 'string',
+        'mail' => 'string',
+        'rank' => 'longstring',
+        'state' => 'int',
+    );
+
+    public static function check($login, $password)
+    {
+        $user = self::load(array('login' => $login, 'password' => self::password_encrypt($password)));
+
+        return is_object($user) ? $user : new self();
+    }
+
+    public function can($section, $selectedRight)
+    {
+        return !isset($this->rights[$section]) ? false : $this->rights[$section][$selectedRight];
+    }
+
+    public function fullName()
+    {
+        $fullName = ucfirst($this->firstname).' '.strtoupper($this->name);
+
+        return trim($fullName) != '' ? $fullName : $this->login;
+    }
+
+    public static function password_encrypt($password)
+    {
+        return sha1(md5($password));
+    }
+
+    public function connected()
+    {
+        return $this->id != 0;
+    }
 }
-
-?>

+ 22 - 24
common.php

@@ -1,28 +1,26 @@
 <?php 
-	session_start('hackpoint-session');
-	mb_internal_encoding('UTF-8');
-	
-	require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'constant.php');
-	require_once(__ROOT__.'function.php');
-	date_default_timezone_set(TIME_ZONE); 
+    session_start('hackpoint-session');
+    mb_internal_encoding('UTF-8');
+    
+    require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'constant.php');
+    require_once(__ROOT__.'function.php');
+    date_default_timezone_set(TIME_ZONE);
 
-	set_error_handler('errorToException');
-	spl_autoload_register('app_autoloader');
-	
-	if(!file_exists(__ROOT__.DATABASE_PATH)) header('location:install.php');
+    set_error_handler('errorToException');
+    spl_autoload_register('app_autoloader');
+    
+    if (!file_exists(__ROOT__.DATABASE_PATH)) {
+        header('location:install.php');
+    }
 
-	global $myUser,$conf,$_,$success;
-	
-	$_ = array_map('secure_user_vars',array_merge($_POST,$_GET));
-	$myUser = new User();
-	$conf = new Configuration();
-	$conf->getAll();
-	$page = basename($_SERVER['PHP_SELF']);
+    global $myUser,$conf,$_,$success;
+    
+    $_ = array_map('secure_user_vars', array_merge($_POST, $_GET));
+    $myUser = new User();
+    $conf = new Configuration();
+    $conf->getAll();
+    $page = basename($_SERVER['PHP_SELF']);
 
-	if(isset($_SESSION['currentUser']))
-		$myUser =unserialize($_SESSION['currentUser']);
-	
-	
-	
-
-?>
+    if (isset($_SESSION['currentUser'])) {
+        $myUser =unserialize($_SESSION['currentUser']);
+    }

+ 37 - 3
css/main.css

@@ -1,3 +1,13 @@
+html, body, #wrap {
+	height: 100%;
+	background-color: #ebebeb;
+}
+
+body > #wrap {
+	min-height: 100%;
+	height: auto;
+	padding-bottom: 60px;
+}
 
 .input-mini{
 	max-width:60px;
@@ -46,9 +56,24 @@ display:none;
 }
 
 .footer{
+	position: relative;
+	height: 60px;
+	margin-top: -60px;
+	padding: 20px 0;
+	color: #ffffff;
+	text-align: center;
+}
+
+
+#resources .list-group-item:nth-child(2){
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px;
+}
+
+.list-group-item.active i{
 	color:#ffffff;
-	text-align:center;
 }
+
 /* ==========================================================================
    Author's custom styles
    ========================================================================== */
@@ -60,10 +85,15 @@ div.CodeMirror{
 .navbar {
 	border-radius:0px;
 }
-
+#sketchTitle{
+	margin-bottom:0;
+}
 #sketchTitle input{
 	border:none;
 	border-bottom: 1px solid #cecece;
+	font-size: 30px;
+    font-weight: 200;
+	background-color:#EBEBEB;
 	width:100%;
 	transition:all 0.2s ease-in-out;
 }
@@ -72,6 +102,10 @@ div.CodeMirror{
 	border-color: #4FC1E9;
 }
 
+#resourceContent{
+	padding-top: 12px;
+}
+
 .resources a{
 	position:relative;
 	cursor:pointer;
@@ -214,4 +248,4 @@ div.CodeMirror{
 	color:#ffffff;
 	cursor:pointer;
 	text-align: center;
-}
+}

+ 4 - 2
footer.php

@@ -1,3 +1,4 @@
+</div>
 </div>
 		<!-- body -->
   
@@ -10,12 +11,13 @@
         <script src="js/vendor/codemirror.js"></script>
          <?php 
         echo PHP_EOL;
-        foreach(glob('js/vendor/codemirror/*.js') as $js)
+        foreach (glob('js/vendor/codemirror/*.js') as $js) {
             echo "\t\t<script type='text/javascript' src='$js'></script>".PHP_EOL;
+        }
         ?>
 		<script src="js/plugins.js"></script>
         <script src="js/vendor/jquery-ui.min.js"></script>
         <script src="js/main.js"></script>
 		<div class="footer"><?php echo PROGRAM_NAME.' V'.SOURCE_VERSION.'.'.BASE_VERSION.' by <a href="http://idleman.fr">@idleman</a>'; ?></div>
     </body>
-</html>
+</html>

+ 8 - 5
header.php

@@ -17,6 +17,7 @@ require_once __DIR__.DIRECTORY_SEPARATOR.'common.php';
       <link rel="stylesheet" href="css/main.css">
     </head>
     <body>
+        <div id="wrap">
     
 
 
@@ -35,7 +36,7 @@ require_once __DIR__.DIRECTORY_SEPARATOR.'common.php';
                     </div>
                     <!-- Collect the nav links, forms, and other content for toggling -->
                     
-					<?php if($myUser->connected()): ?>
+					<?php if ($myUser->connected()): ?>
 					<div id="bs-example-navbar-collapse-5" class="collapse navbar-collapse">
                       <ul class="nav navbar-nav">
                         <li <?php echo $page=='index.php'?'class="active"':''; ?>><a href="index.php">Sketch</a></li>
@@ -55,8 +56,10 @@ require_once __DIR__.DIRECTORY_SEPARATOR.'common.php';
                           </ul>
                         </li>
                         -->
+                      </ul>
+                      <ul class="nav navbar-nav navbar-right">
                         <li class="dropdown <?php echo $page=='account.php'?'active':''; ?>" >
-                          <a data-toggle="dropdown" class="dropdown-toggle" href="#"> Connecté avec <?php echo $myUser->login; ?> <b class="caret"></b></a>
+                          <a data-toggle="dropdown" class="dropdown-toggle" href="#"> Connecté en tant que <?php echo $myUser->login; ?> <b class="caret"></b></a>
                           <ul role="menu" class="dropdown-menu">
                             <li class="dropdown-header">Profil</li>
                             <li ><a href="account.php">Modifier</a></li>
@@ -86,16 +89,16 @@ require_once __DIR__.DIRECTORY_SEPARATOR.'common.php';
 		
 		
 		<!-- messages -->
-			<?php if(isset($_SESSION['error'])): ?>
+			<?php if (isset($_SESSION['error'])): ?>
 			<div class="alert alert-danger">
               <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
               <strong>Oops!</strong> <?php echo $_SESSION['error']; unset($_SESSION['error']); ?>
             </div>
 			<?php endif; ?>
-			<?php if(isset($_SESSION['success'])): ?>
+			<?php if (isset($_SESSION['success'])): ?>
 			<div class="alert alert-success alert-dismissable">
               <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
               <strong>Succès !</strong> <?php echo $_SESSION['success']; unset($_SESSION['success']); ?>
             </div>
 			<?php endif; ?>
-			<!-- messages -->
+			<!-- messages -->

+ 1 - 1
index.php

@@ -1,6 +1,6 @@
 <?php require_once __DIR__.DIRECTORY_SEPARATOR.'header.php'; ?>
 
-	<?php if($myUser->connected()): ?>
+	<?php if ($myUser->connected()): ?>
 
 			<div class="jumbotron">
 			<div class="jumbotron-contents">

+ 37 - 28
install.php

@@ -40,32 +40,39 @@
 		
 
 <?php
-try{
-mb_internal_encoding('UTF-8');
-require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'constant.php');
-require_once(__ROOT__.'function.php');
-date_default_timezone_set(TIME_ZONE); 
-set_error_handler('errorToException');
-spl_autoload_register('app_autoloader');
+try {
+    mb_internal_encoding('UTF-8');
+    require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'constant.php');
+    require_once(__ROOT__.'function.php');
+    date_default_timezone_set(TIME_ZONE);
+    set_error_handler('errorToException');
+    spl_autoload_register('app_autoloader');
+    
+    $_ = array_map('secure_user_vars', array_merge($_POST, $_GET));
+    
+    if (isset($_SESSION['currentUser'])) {
+        $myUser =unserialize($_SESSION['currentUser']);
+    }
+
 	
-$_ = array_map('secure_user_vars',array_merge($_POST,$_GET));
+	if(!is_writable (__ROOT__.UPLOAD_PATH)) throw new Exception('Le dossier '.__ROOT__.UPLOAD_PATH.' doit être accessible en ecriture, merci de taper la commande linux <code>sudo chown -R www-data:www-data '.__ROOT__.UPLOAD_PATH.'</code> ou de régler le dossier en écriture via votre client ftp');
+	if(!is_writable (dirname(__ROOT__.DATABASE_PATH))) throw new Exception('Le dossier '.dirname(__ROOT__.DATABASE_PATH).' doit être accessible en ecriture, merci de taper la commande linux <code>sudo chown -R www-data:www-data '.dirname(__ROOT__.DATABASE_PATH).'</code> ou de régler le dossier en écriture via votre client ftp');
+	if(!file_exists(__ROOT__.SKETCH_PATH)) mkdir(__ROOT__.SKETCH_PATH);
 	
-if(isset($_SESSION['currentUser']))
-$myUser =unserialize($_SESSION['currentUser']);	
-
-
-if(file_exists(__ROOT__.DATABASE_PATH) && filesize(__ROOT__.DATABASE_PATH)>0) throw new Exception('Base déjà installée, pour réinstaller la base, supprimez le fichier '.DATABASE_PATH.', puis rechargez cette page.');
-
-
-//Class entities
-Entity::install(__ROOT__.'class');
+    if (file_exists(__ROOT__.DATABASE_PATH) && filesize(__ROOT__.DATABASE_PATH)>0) throw new Exception('Base déjà installée, pour réinstaller la base, supprimez le fichier '.DATABASE_PATH.', puis rechargez cette page.');
+	if(!extension_loaded('gd') || !function_exists('gd_info'))  throw new Exception('L\'extension php GD2  est requise, veuillez installer GD2 (sous linux : <code>sudo apt-get install php5-gd && service apache2 restart</code>)');
+	if(!in_array('sqlite',PDO::getAvailableDrivers())) throw new Exception('Le driver SQLITE est requis, veuillez installer sqlite3 (sous linux : <code>sudo apt-get install php5-sqlite && service apache2 restart</code>)');
+	
+	
+	//Class entities
+	Entity::install(__ROOT__.'class');
 
-$admin = new User();
-$admin->login = 'admin';
-$admin->password = User::password_encrypt('admin');
-$admin->rank = 'ADMIN';
-$admin->save();
-?>
+    $admin = new User();
+    $admin->login = 'admin';
+    $admin->password = User::password_encrypt('admin');
+    $admin->rank = 'ADMIN';
+    $admin->save();
+    ?>
 
 <div class="alert alert-success alert-dismissable">
 	<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
@@ -73,14 +80,16 @@ $admin->save();
 </div>
 <?php
 
-}catch(Exception $e){
-?>
+} catch (Exception $e) {
+    ?>
 
 <div class="alert alert-danger">
 	<button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button>
-	<strong>Oops!</strong> <?php echo $e->getMessage(); ?> 
+	<strong>Oops!</strong> <?php echo $e->getMessage();
+    ?> 
 </div>
-<?php } ?>
+<?php 
+} ?>
 <a class="btn btn-primary" href="index.php">Revenir à l'index</a>
  </div>
 		<!-- body -->
@@ -93,4 +102,4 @@ $admin->save();
 		<script src="js/plugins.js"></script>
         <script src="js/main.js"></script>
     </body>
-</html>
+</html>

+ 42 - 23
sketch.php

@@ -1,24 +1,36 @@
-<?php require_once __DIR__.DIRECTORY_SEPARATOR.'header.php'; 
-try{
-if(!isset($_['id']) || !is_numeric($_['id'])) throw new Exception("Sketch non spécifié");
-$sketch = Sketch::getById($_['id']);
-if(!$sketch || $sketch->id == 0) throw new Exception("Sketch inexistant");
+<?php require_once __DIR__.DIRECTORY_SEPARATOR.'header.php';
+try {
+    if (!isset($_['id']) || !is_numeric($_['id'])) {
+        throw new Exception("Sketch non spécifié");
+    }
+    $sketch = Sketch::getById($_['id']);
+    if (!$sketch || $sketch->id == 0) {
+        throw new Exception("Sketch inexistant");
+    }
 
-if(!$sketch->public && $myUser->id != $sketch->owner) throw new Exception("Sketch privé, demandez à son propriétaire de le rendre publique");
+    if (!$sketch->public && $myUser->id != $sketch->owner) {
+        throw new Exception("Sketch privé, demandez à son propriétaire de le rendre publique");
+    }
 
-?>
-<div class="row" id="sketch" data-id="<?php echo $sketch->id; ?>">
+    ?>
+<div class="row" id="sketch" data-id="<?php echo $sketch->id;
+    ?>">
 	<div class="col-md-4">
 	
-		<h5 id="sketchTitle"><input onblur="save_sketch_title(this);" type="text" value="<?php echo htmlspecialchars(html_entity_decode($sketch->label)); ?>"/></h5>
+		<h5 id="sketchTitle"><input onblur="save_sketch_title(this);" type="text" value="<?php echo htmlspecialchars(html_entity_decode($sketch->label));
+    ?>"/></h5>
 	</div>
 	<div class="col-md-8">
 		<ul class="sketchOptions">
-			<li onclick="window.location='action.php?action=export_sketch&amp;id=<?php echo $sketch->id; ?>';" title="Exporter"><i class="fa fa-share-square-o"></i></li>
+			<li onclick="window.location='action.php?action=export_sketch&amp;id=<?php echo $sketch->id;
+    ?>';" title="Exporter"><i class="fa fa-share-square-o"></i></li>
 			<li id="importResource" title="Envoyer des fichiers"><i class="fa fa-files-o"></i></li>
 			<li onclick="toggle_embed_sketch();" title="Partager"><i class="fa fa-code"></i></li>
-			<li onclick="toggle_share_sketch(this);" title="Rendre <?php echo $sketch->public==0?'Public':'Privé'; ?>"><i class="fa <?php echo $sketch->public==0?'fa-eye-slash':'fa-eye'; ?>"></i></li>
-			<li id="download" onclick="window.location='action.php?action=download_sketch&amp;id=<?php echo $sketch->id; ?>'" title="Télécharger"><i class="fa fa-arrow-circle-o-down"></i></li>
+			<li onclick="toggle_share_sketch(this);" title="Rendre <?php echo $sketch->public==0?'Public':'Privé';
+    ?>"><i class="fa <?php echo $sketch->public==0?'fa-eye-slash':'fa-eye';
+    ?>"></i></li>
+			<li id="download" onclick="window.location='action.php?action=download_sketch&amp;id=<?php echo $sketch->id;
+    ?>'" title="Télécharger"><i class="fa fa-arrow-circle-o-down"></i></li>
 		</ul>
 	</div>
 </div>
@@ -26,7 +38,7 @@ if(!$sketch->public && $myUser->id != $sketch->owner) throw new Exception("Sketc
 	
 	<div class="col-md-3" id="resourceMenu">
 
-		<?php if($myUser->id == $sketch->owner) : ?>
+		<?php if ($myUser->id == $sketch->owner) : ?>
 			   <div class="btn-group" style="margin:10px auto;">
 				  <button onclick="add_resource();" type="button" class="btn btn-primary"><i class="fa fa-plus"></i> Ajouter une ressource</button>
 				  <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
@@ -34,12 +46,16 @@ if(!$sketch->public && $myUser->id != $sketch->owner) throw new Exception("Sketc
 					<span class="sr-only">Toggle Dropdown</span>
 				  </button>
 				  <ul class="dropdown-menu" role="menu">
-					<?php foreach(Type::all() as $uid=>$type): ?>
-					<li><a onclick="add_resource('<?php echo $uid; ?>');"><?php echo $type['label']; ?></a></li>
-					<?php endforeach; ?>
+					<?php foreach (Type::all() as $uid=>$type): ?>
+					<li><a onclick="add_resource('<?php echo $uid;
+    ?>');"><?php echo $type['label'];
+    ?></a></li>
+					<?php endforeach;
+    ?>
 				  </ul>
 			    </div>
-		<?php endif; ?>
+		<?php endif;
+    ?>
 		
 		<div class="list-group resources" id="resources">
 					  
@@ -81,9 +97,12 @@ if(!$sketch->public && $myUser->id != $sketch->owner) throw new Exception("Sketc
       <div class="modal-body">
 	  <label for="type">Type</label>
        <select class="form-control" id="type">
-       	<?php foreach(Type::all() as $uid=>$type): ?>
-       	<option value="<?php echo $uid; ?>"><?php echo $type['label']; ?></option>
-       <?php endforeach; ?>
+       	<?php foreach (Type::all() as $uid=>$type): ?>
+       	<option value="<?php echo $uid;
+    ?>"><?php echo $type['label'];
+    ?></option>
+       <?php endforeach;
+    ?>
        </select>
        <label for="label">Libellé</label>
        <input class="form-control" type="text" id="label"/>
@@ -124,8 +143,8 @@ if(!$sketch->public && $myUser->id != $sketch->owner) throw new Exception("Sketc
 </div>
 
 <?php 
-}catch(Exception $e){
-	$_SESSION['error'] = $e->getMessage();
-	header('location: index.php');
+} catch (Exception $e) {
+    $_SESSION['error'] = $e->getMessage();
+    header('location: index.php');
 }
 require_once __ROOT__.'footer.php' ?>