Browse Source

Merge pull request #4 from gmarsay/master

Merci :)
Idleman 8 years ago
parent
commit
e63fb922f0
24 changed files with 2427 additions and 2141 deletions
  1. 3 1
      account.php
  2. 674 582
      action.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. 460 438
      class/Type.class.php
  14. 51 46
      class/User.class.php
  15. 22 24
      common.php
  16. 25 14
      component.php
  17. 15 16
      constant.php
  18. 16 3
      css/main.css
  19. 4 2
      footer.php
  20. 151 143
      function.php
  21. 8 5
      header.php
  22. 1 1
      index.php
  23. 28 23
      install.php
  24. 42 23
      sketch.php

+ 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">

+ 674 - 582
action.php

@@ -3,612 +3,704 @@
 require_once __DIR__.DIRECTORY_SEPARATOR."common.php";
 
 
-if(!isset($_['action'])) throw new Exception('Action inexistante');
+if (!isset($_['action'])) {
+    throw new Exception('Action inexistante');
+}
 
 //Execution du code en fonction de l'action
-switch ($_['action']){
-	
-	
-	case 'login':
-		global $myUser;
-		try{
-			$myUser = User::check($_['login'],$_['password']);
-			
-			if(!$myUser->connected()) throw new Exception('Utilisateur inexistant');
-			$_SESSION['currentUser'] = serialize($myUser);
-			
-		}catch(Exception $e){
-			$_SESSION['error'] = $e->getMessage();
-		}
-		header('location: index.php');
-	break;
-	
-	case 'logout':
-		unset($_SESSION['currentUser']);
-		session_destroy();
-		header('location: index.php');
-	break;
-
-	case 'save_user':
-		try{
-		global $myUser;
-		if(!$myUser->connected()) throw new Exception("Permission refusée, seul un connecté peux faire ça");
-		if($myUser->id!=$_['id']) throw new Exception("Permission refusée, seul le propriétaire du compte peux faire ça");
-		if($_['password']!=$_['confirmPassword']) throw new Exception("Les deux mot de passe ne correspondent pas");
-			$myUser->password = User::password_encrypt($_['password']);
-			$myUser->save();
-			$_SESSION['success'] = "Mot de passe modifié avec succès";
-		}catch(Exception $e){
-			$_SESSION['error'] = $e->getMessage();
-		}
-		header('location: account.php');
-	break;
+switch ($_['action']) {
+    
+    
+    case 'login':
+        global $myUser;
+        try {
+            $myUser = User::check($_['login'], $_['password']);
+            
+            if (!$myUser->connected()) {
+                throw new Exception('Utilisateur inexistant');
+            }
+            $_SESSION['currentUser'] = serialize($myUser);
+        } catch (Exception $e) {
+            $_SESSION['error'] = $e->getMessage();
+        }
+        header('location: index.php');
+    break;
+    
+    case 'logout':
+        unset($_SESSION['currentUser']);
+        session_destroy();
+        header('location: index.php');
+    break;
 
-	
+    case 'save_user':
+        try {
+            global $myUser;
+            if (!$myUser->connected()) {
+                throw new Exception("Permission refusée, seul un connecté peux faire ça");
+            }
+            if ($myUser->id!=$_['id']) {
+                throw new Exception("Permission refusée, seul le propriétaire du compte peux faire ça");
+            }
+            if ($_['password']!=$_['confirmPassword']) {
+                throw new Exception("Les deux mot de passe ne correspondent pas");
+            }
+            $myUser->password = User::password_encrypt($_['password']);
+            $myUser->save();
+            $_SESSION['success'] = "Mot de passe modifié avec succès";
+        } catch (Exception $e) {
+            $_SESSION['error'] = $e->getMessage();
+        }
+        header('location: account.php');
+    break;
 
-	// SKETCH
-	case 'create_sketch':
-		Action::write(function($_,&$response){
-			global $myUser;
+    
 
-			if(!$myUser->connected()) throw new Exception("Permission refusée, seul un connecté peux faire ça");
-			$sketch = new Sketch();
-			$sketch->fromArray($_);
-			$sketch->owner = $myUser->id;
-			$sketch->save();
-			$resource = new Resource();
-			$resource->label = 'README';
-			$resource->type = 'readme';
-			$resource->sketch = $sketch->id;
-			$resource->content = 'Décrivez votre projet ici...';
-			$resource->sort = 0;
-			$resource->save();
-			$response = $sketch->toArray();
-		});
-	break;
-	
-	case 'export_sketch':
-	
-		global $myUser;
-		$response = array();
-		try{
-		
-			$sketch = Sketch::getById($_['id']);
-			
-			if(!$sketch->public && $myUser->id!=$sketch->owner)throw new Exception('Ce sketch est privé');
-			
-			$response['sketch'] = $sketch->toArray();
-			$response['resources'] = array();
-			
-			foreach(Resource::loadAll(array('sketch'=>$_['id'])) as $resource)
-				$response['resources'][] = Type::toExport($resource);
+    // SKETCH
+    case 'create_sketch':
+        Action::write(function ($_, &$response) {
+            global $myUser;
 
-		
-		}catch(Exception $e){
-			$response['error'] = $e->getMessage();
-		}
-	
-		$response = gzdeflate(json_encode($response));
-		
-		if(!isset($_['api'])){
-			$filename = slugify($sketch->label).('.export.').date('d-m-Y_H-i').'.json';
-			header("Content-Type: application/json");
-			header("Content-Length: " . strlen($response));
-			header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
-			header('Cache-Control: no-store, no-cache, must-revalidate');
-			header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
-			header('Cache-Control: post-check=0, pre-check=0', FALSE);
-			header('Pragma: no-cache');
-			header("Content-Disposition: attachment; filename=\"".$filename."\"");
-		}
+            if (!$myUser->connected()) {
+                throw new Exception("Permission refusée, seul un connecté peux faire ça");
+            }
+            $sketch = new Sketch();
+            $sketch->fromArray($_);
+            $sketch->owner = $myUser->id;
+            $sketch->save();
+            $resource = new Resource();
+            $resource->label = 'README';
+            $resource->type = 'readme';
+            $resource->sketch = $sketch->id;
+            $resource->content = 'Décrivez votre projet ici...';
+            $resource->sort = 0;
+            $resource->save();
+            $response = $sketch->toArray();
+        });
+    break;
+    
+    case 'export_sketch':
+    
+        global $myUser;
+        $response = array();
+        try {
+            $sketch = Sketch::getById($_['id']);
+            
+            if (!$sketch->public && $myUser->id!=$sketch->owner) {
+                throw new Exception('Ce sketch est privé');
+            }
+            
+            $response['sketch'] = $sketch->toArray();
+            $response['resources'] = array();
+            
+            foreach (Resource::loadAll(array('sketch'=>$_['id'])) as $resource) {
+                $response['resources'][] = Type::toExport($resource);
+            }
+        } catch (Exception $e) {
+            $response['error'] = $e->getMessage();
+        }
+    
+        $response = gzdeflate(json_encode($response));
+        
+        if (!isset($_['api'])) {
+            $filename = slugify($sketch->label).('.export.').date('d-m-Y_H-i').'.json';
+            header("Content-Type: application/json");
+            header("Content-Length: " . strlen($response));
+            header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
+            header('Cache-Control: no-store, no-cache, must-revalidate');
+            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+            header('Cache-Control: post-check=0, pre-check=0', false);
+            header('Pragma: no-cache');
+            header("Content-Disposition: attachment; filename=\"".$filename."\"");
+        }
 
-		echo $response;
-	break;
-	
-	case 'import_sketch':
-		Action::write(function($_,&$response){
-			global $myUser;
+        echo $response;
+    break;
+    
+    case 'import_sketch':
+        Action::write(function ($_, &$response) {
+            global $myUser;
 
-			if(!$myUser->connected()) throw new Exception("Permission refusée, seul un connecté peux faire ça");
-			
-			if($_['from'] == 'url'){
-				if(!isset($_['url']) || empty($_['url'])) throw new Exception("Adresse du sketch invalide");
-				$url = parse_url($_['url']);
-				parse_str($url['query'], $parameters);
-				if(!isset($parameters['id']) || empty($parameters['id']) || !is_numeric($parameters['id'])) throw new Exception("ID du sketch invalide");
-				$contentPath = $url['scheme'].'://'.$url['host'].'/'.substr($url['path'],0,-11).'/action.php?action=export_sketch&id='.$parameters['id'].'&api=true';
-			}else{
-				$ext = getExt($_FILES['file']['name']);
-				if($ext!='json') throw new Exception('Extension JSON autorisée uniquement');
-				$contentPath = $_FILES['file']['tmp_name'];
-			}
-			
-			$stream = false;
-			try{ $stream = @file_get_contents($contentPath); }catch(Exception $a){}
-			if($stream === false) throw new Exception("Impossible d'atteindre le contenu hackpoint : $contentPath ");
-			$stream = gzinflate($stream);
-			if($stream === false) throw new Exception('Impossible de décompresser le sketch...');
-			$json = json_decode($stream,true);
-			if($json == false) throw new Exception('Impossible de parser la réponse du hackpoint, json invalide :'.$stream);
-			
-			
-			
-			if(isset($json['error'])) throw new Exception($json['error']);
-			$sketch = new Sketch();
-			$sketch->fromArray($json['sketch']);
-			$sketch->id = null;
-			$sketch->owner = $myUser->id;
-			$sketch->public = 0;
-			$sketch->label = $sketch->label .='-import-'.date('d/m/Y H:i');
-			$sketch->save();
-			
-			
-			
-			foreach($json['resources'] as $res)
-				Type::fromImport($res,$sketch);
+            if (!$myUser->connected()) {
+                throw new Exception("Permission refusée, seul un connecté peux faire ça");
+            }
+            
+            if ($_['from'] == 'url') {
+                if (!isset($_['url']) || empty($_['url'])) {
+                    throw new Exception("Adresse du sketch invalide");
+                }
+                $url = parse_url($_['url']);
+                parse_str($url['query'], $parameters);
+                if (!isset($parameters['id']) || empty($parameters['id']) || !is_numeric($parameters['id'])) {
+                    throw new Exception("ID du sketch invalide");
+                }
+                $contentPath = $url['scheme'].'://'.$url['host'].'/'.substr($url['path'], 0, -11).'/action.php?action=export_sketch&id='.$parameters['id'].'&api=true';
+            } else {
+                $ext = getExt($_FILES['file']['name']);
+                if ($ext!='json') {
+                    throw new Exception('Extension JSON autorisée uniquement');
+                }
+                $contentPath = $_FILES['file']['tmp_name'];
+            }
+            
+            $stream = false;
+            try {
+                $stream = @file_get_contents($contentPath);
+            } catch (Exception $a) {
+            }
+            if ($stream === false) {
+                throw new Exception("Impossible d'atteindre le contenu hackpoint : $contentPath ");
+            }
+            $stream = gzinflate($stream);
+            if ($stream === false) {
+                throw new Exception('Impossible de décompresser le sketch...');
+            }
+            $json = json_decode($stream, true);
+            if ($json == false) {
+                throw new Exception('Impossible de parser la réponse du hackpoint, json invalide :'.$stream);
+            }
+            
+            
+            
+            if (isset($json['error'])) {
+                throw new Exception($json['error']);
+            }
+            $sketch = new Sketch();
+            $sketch->fromArray($json['sketch']);
+            $sketch->id = null;
+            $sketch->owner = $myUser->id;
+            $sketch->public = 0;
+            $sketch->label = $sketch->label .='-import-'.date('d/m/Y H:i');
+            $sketch->save();
+            
+            
+            
+            foreach ($json['resources'] as $res) {
+                Type::fromImport($res, $sketch);
+            }
 
-		});
-	break;
-	case 'search_sketch':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$sketchs = Sketch::loadAll(array('owner'=>$myUser->id));
-			foreach($sketchs as $sketch){
-				$sketch->label = html_entity_decode($sketch->label);
-				$response['rows'][] = $sketch->toArray();
-			}
-		});
-	break;
-	case 'delete_sketch':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$sketch = Sketch::getById($_['id']);
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			Part::staticQuery("delete FROM ".ResourcePart::tableName()." WHERE resource IN(SELECT id FROM ".Resource::tableName()." WHERE sketch=".$_['id'].") ");
-			foreach(Resource::loadAll(array('sketch'=>$_['id'])) as $resource):
-				$resource->remove();
-			endforeach;
-			Sketch::deleteById($_['id']);
-		});
-	break;
+        });
+    break;
+    case 'search_sketch':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $sketchs = Sketch::loadAll(array('owner'=>$myUser->id));
+            foreach ($sketchs as $sketch) {
+                $sketch->label = html_entity_decode($sketch->label);
+                $response['rows'][] = $sketch->toArray();
+            }
+        });
+    break;
+    case 'delete_sketch':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $sketch = Sketch::getById($_['id']);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            Part::staticQuery("delete FROM ".ResourcePart::tableName()." WHERE resource IN(SELECT id FROM ".Resource::tableName()." WHERE sketch=".$_['id'].") ");
+            foreach (Resource::loadAll(array('sketch'=>$_['id'])) as $resource):
+                $resource->remove();
+            endforeach;
+            Sketch::deleteById($_['id']);
+        });
+    break;
 
-	case 'save_sketch_title':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$sketch = Sketch::getById($_['id']);
-			if($myUser->id != $sketch->owner) return;
-			$sketch->fromArray($_);
-			$sketch->save();
-		});
-	break;
+    case 'save_sketch_title':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $sketch = Sketch::getById($_['id']);
+            if ($myUser->id != $sketch->owner) {
+                return;
+            }
+            $sketch->fromArray($_);
+            $sketch->save();
+        });
+    break;
 
-	case 'toggle_share_sketch':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$sketch = Sketch::getById($_['id']);
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			$sketch->public = $_['state'];
-			$sketch->save();
-		});
-	break;
+    case 'toggle_share_sketch':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $sketch = Sketch::getById($_['id']);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            $sketch->public = $_['state'];
+            $sketch->save();
+        });
+    break;
 
-	case 'download_sketch':
+    case 'download_sketch':
 
-		$sketch = Sketch::getByid($_['id']);
-		$resources = Resource::loadAll(array('sketch'=>$sketch->id),'sort');
-		
-		$filename = $sketch->slug.'-'.time().'.zip';
-		$filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
-		$zip = new ZipArchive;
-		$res = $zip->open($filepath, ZipArchive::CREATE);
-		if ($res === TRUE) {
-			foreach($resources as $resource){
-				$type = Type::get($resource->type);
-				$file = Type::toFileStream($resource);
-				$zip->addFromString($file->name, $file->content);
-			}
-			$zip->close();
-		}
-		header("Content-Type: application/zip");
-		header("Content-Length: " . filesize($filepath));
-		header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
-		header('Cache-Control: no-store, no-cache, must-revalidate');
-		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
-		header('Cache-Control: post-check=0, pre-check=0', FALSE);
-		header('Pragma: no-cache');
-		header("Content-Disposition: attachment; filename=\"".$filename."\"");
-		readfile($filepath);
-		unlink($filepath); 
-	break;
-	
-	// RESOURCES
+        $sketch = Sketch::getByid($_['id']);
+        $resources = Resource::loadAll(array('sketch'=>$sketch->id), 'sort');
+        
+        $filename = $sketch->slug.'-'.time().'.zip';
+        $filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
+        $zip = new ZipArchive;
+        $res = $zip->open($filepath, ZipArchive::CREATE);
+        if ($res === true) {
+            foreach ($resources as $resource) {
+                $type = Type::get($resource->type);
+                $file = Type::toFileStream($resource);
+                $zip->addFromString($file->name, $file->content);
+            }
+            $zip->close();
+        }
+        header("Content-Type: application/zip");
+        header("Content-Length: " . filesize($filepath));
+        header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
+        header('Cache-Control: no-store, no-cache, must-revalidate');
+        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+        header('Cache-Control: post-check=0, pre-check=0', false);
+        header('Pragma: no-cache');
+        header("Content-Disposition: attachment; filename=\"".$filename."\"");
+        readfile($filepath);
+        unlink($filepath);
+    break;
+    
+    // RESOURCES
 
-	case 'upload_resource':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$resource = Resource::getByid($_['id']);
-			$sketch = Sketch::getById($resource->sketch);
-			$ext = getExt($_FILES['file']['name']);
-			if($myUser->id != $sketch->owner) throw new Exception("Seul le propriétaire du sketch peux faire ça");
-			if(!in_array($ext,explode(',',ALLOWED_RESOURCE_IMAGE))) throw new Exception('Extensions autorisées '.ALLOWED_RESOURCE_IMAGE);
-			if($_FILES['file']['size']>ALLOWED_RESOURCE_SIZE) throw new Exception('Taille maximum autorisée '.ALLOWED_RESOURCE_SIZE.' o');
-			$name = $resource->id.'.'.$ext;
-			$path = SKETCH_PATH.$name;	
-			move_uploaded_file($_FILES['file']['tmp_name'], $path);
-			$resource->content = $name;
-			$resource->save();
-			$response = array_merge(Type::get($resource->type));
-			$response['url'] = $path.'?v='.time();
-		});
-	break;
-	
-	case 'upload_resource_file':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$resource = Resource::getByid($_['id']);
-			$sketch = Sketch::getById($resource->sketch);
-			$ext = getExt($_FILES['file']['name']);
-			if($myUser->id != $sketch->owner) throw new Exception("Seul le propriétaire du sketch peux faire ça");
-			if(ALLOWED_RESOURCE_FILE!='' && !in_array($ext,explode(',',ALLOWED_RESOURCE_FILE))) throw new Exception('Extensions autorisées '.ALLOWED_RESOURCE_FILE);
-			if($_FILES['file']['size']>ALLOWED_RESOURCE_SIZE) throw new Exception('Taille maximum autorisée '.ALLOWED_RESOURCE_SIZE.' o');
-			$name = $resource->id;
-			$folder = SKETCH_PATH.$name;	
-			if(!file_exists($folder)) mkdir($folder);
-			
-			$path = $folder.'/'.$_FILES['file']['name'];
-			
-			move_uploaded_file($_FILES['file']['tmp_name'], $path);
-			$response = array_merge(Type::get($resource->type));
-			$response['url'] = $path.'?v='.time();
-		});
-	break;
-	
-	case 'search_resources':
-	    
-		
-		Action::write(function($_,&$response){
-			
-			if(!isset($_['id']) || !is_numeric($_['id'])) throw new Exception("Sketch non spécifié");
-			$resources = Resource::loadAll(array('sketch'=>$_['id']),'sort');
-			
-			foreach($resources as $resource){
-				$resource->label = html_entity_decode($resource->label);
-				$resource->content = null;
-				$response['rows'][] = $resource->toArray();
-			}
-				
-		});
-	break;
-	
-	case 'import_resource':
-		global $myUser;
-		$sketch = Sketch::getByid($_['id']);
-		if($myUser->id != $sketch->owner) return;
-		$ext = explode('.',$_FILES['file']['name']);
-		$ext = strtolower(array_pop($ext));
-		$types = Type::all();
-		$type = 'readme';
-		foreach($types as $uid=>$tp)
-			if(isset($tp['extension']) && $ext == $tp['extension']) $type = $uid;
-		
-		Type::fromFileImport($_FILES['file'],$sketch,$type);
-		
-	break;
-	
-	//COMPONENT
+    case 'upload_resource':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $resource = Resource::getByid($_['id']);
+            $sketch = Sketch::getById($resource->sketch);
+            $ext = getExt($_FILES['file']['name']);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Seul le propriétaire du sketch peux faire ça");
+            }
+            if (!in_array($ext, explode(',', ALLOWED_RESOURCE_IMAGE))) {
+                throw new Exception('Extensions autorisées '.ALLOWED_RESOURCE_IMAGE);
+            }
+            if ($_FILES['file']['size']>ALLOWED_RESOURCE_SIZE) {
+                throw new Exception('Taille maximum autorisée '.ALLOWED_RESOURCE_SIZE.' o');
+            }
+            $name = $resource->id.'.'.$ext;
+            $path = SKETCH_PATH.$name;
+            move_uploaded_file($_FILES['file']['tmp_name'], $path);
+            $resource->content = $name;
+            $resource->save();
+            $response = array_merge(Type::get($resource->type));
+            $response['url'] = $path.'?v='.time();
+        });
+    break;
+    
+    case 'upload_resource_file':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $resource = Resource::getByid($_['id']);
+            $sketch = Sketch::getById($resource->sketch);
+            $ext = getExt($_FILES['file']['name']);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Seul le propriétaire du sketch peux faire ça");
+            }
+            if (ALLOWED_RESOURCE_FILE!='' && !in_array($ext, explode(',', ALLOWED_RESOURCE_FILE))) {
+                throw new Exception('Extensions autorisées '.ALLOWED_RESOURCE_FILE);
+            }
+            if ($_FILES['file']['size']>ALLOWED_RESOURCE_SIZE) {
+                throw new Exception('Taille maximum autorisée '.ALLOWED_RESOURCE_SIZE.' o');
+            }
+            $name = $resource->id;
+            $folder = SKETCH_PATH.$name;
+            if (!file_exists($folder)) {
+                mkdir($folder);
+            }
+            
+            $path = $folder.'/'.$_FILES['file']['name'];
+            
+            move_uploaded_file($_FILES['file']['tmp_name'], $path);
+            $response = array_merge(Type::get($resource->type));
+            $response['url'] = $path.'?v='.time();
+        });
+    break;
+    
+    case 'search_resources':
+        
+        
+        Action::write(function ($_, &$response) {
+            
+            if (!isset($_['id']) || !is_numeric($_['id'])) {
+                throw new Exception("Sketch non spécifié");
+            }
+            $resources = Resource::loadAll(array('sketch'=>$_['id']), 'sort');
+            
+            foreach ($resources as $resource) {
+                $resource->label = html_entity_decode($resource->label);
+                $resource->content = null;
+                $response['rows'][] = $resource->toArray();
+            }
+                
+        });
+    break;
+    
+    case 'import_resource':
+        global $myUser;
+        $sketch = Sketch::getByid($_['id']);
+        if ($myUser->id != $sketch->owner) {
+            return;
+        }
+        $ext = explode('.', $_FILES['file']['name']);
+        $ext = strtolower(array_pop($ext));
+        $types = Type::all();
+        $type = 'readme';
+        foreach ($types as $uid=>$tp) {
+            if (isset($tp['extension']) && $ext == $tp['extension']) {
+                $type = $uid;
+            }
+        }
+        
+        Type::fromFileImport($_FILES['file'], $sketch, $type);
+        
+    break;
+    
+    //COMPONENT
 
-	case 'upload_component_image':
-		global $myUser;
-		$ext = explode('.',$_FILES['file']['name']);
-		$ext = strtolower(array_pop($ext));
-		if(!in_array($ext,explode(',',ALLOWED_RESOURCE_IMAGE))) exit();
-		imageResize($_FILES['file']['tmp_name'],100,100);
-		echo 'data:image/png;base64,'.base64_encode(file_get_contents($_FILES['file']['tmp_name']));
-	break;
-	
-	
-	
-	case 'search_component':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$parts = Part::populate();
-			foreach($parts as $part){
-				$part->label = html_entity_decode($part->label);
-				$part->link = html_entity_decode($part->link);
-				if($part->image==''){
-					$part->image = 'img/default_image.png';
-				}else{
-					$part->image = PART_PATH.html_entity_decode($part->image);
-				}
-				$response['rows'][] = $part->toArray();
-			}
-		});
-	break;
+    case 'upload_component_image':
+        global $myUser;
+        $ext = explode('.', $_FILES['file']['name']);
+        $ext = strtolower(array_pop($ext));
+        if (!in_array($ext, explode(',', ALLOWED_RESOURCE_IMAGE))) {
+            exit();
+        }
+        imageResize($_FILES['file']['tmp_name'], 100, 100);
+        echo 'data:image/png;base64,'.base64_encode(file_get_contents($_FILES['file']['tmp_name']));
+    break;
+    
+    
+    
+    case 'search_component':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $parts = Part::populate();
+            foreach ($parts as $part) {
+                $part->label = html_entity_decode($part->label);
+                $part->link = html_entity_decode($part->link);
+                if ($part->image=='') {
+                    $part->image = 'img/default_image.png';
+                } else {
+                    $part->image = PART_PATH.html_entity_decode($part->image);
+                }
+                $response['rows'][] = $part->toArray();
+            }
+        });
+    break;
 
-	
+    
 
-	case 'delete_component':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$part = Part::getById($_['id']);
-			if($myUser->id!=$part->owner) throw new Exception('Seul le propriétaire du composant peux faire ça');
-			$part->remove();
-		});
-	break;
+    case 'delete_component':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $part = Part::getById($_['id']);
+            if ($myUser->id!=$part->owner) {
+                throw new Exception('Seul le propriétaire du composant peux faire ça');
+            }
+            $part->remove();
+        });
+    break;
 
-	case 'save_component':
-		Action::write(function($_,&$response){
-			global $myUser;
+    case 'save_component':
+        Action::write(function ($_, &$response) {
+            global $myUser;
 
-			if(!$myUser->connected()) throw new Exception("Permission refusée, seul un connecté peux faire ça");
-			$part = isset($_['id']) && is_numeric($_['id'])?Part::getById($_['id']):new Part();
-			$part->fromArray($_);
-			$part->owner = $myUser->id;
-			$part->save();
-			if(substr($part->image,0,10) == 'data:image'){
-				$imageName = $part->id.'.png';
-				base64_to_image($part->image,PART_PATH.$imageName);
-				$part->image = $imageName;
-				$part->save();
-			}
-			$response = $part->toArray();
-		});
-	break;
+            if (!$myUser->connected()) {
+                throw new Exception("Permission refusée, seul un connecté peux faire ça");
+            }
+            $part = isset($_['id']) && is_numeric($_['id'])?Part::getById($_['id']):new Part();
+            $part->fromArray($_);
+            $part->owner = $myUser->id;
+            $part->save();
+            if (substr($part->image, 0, 10) == 'data:image') {
+                $imageName = $part->id.'.png';
+                base64_to_image($part->image, PART_PATH.$imageName);
+                $part->image = $imageName;
+                $part->save();
+            }
+            $response = $part->toArray();
+        });
+    break;
 
-	case 'edit_component':
-		Action::write(function($_,&$response){
-			$part = isset($_['id'])? Part::getById($_['id']):new Part;
-			$part->label = html_entity_decode($part->label);
-			$part->link = html_entity_decode($part->link);
-			$part->brand = html_entity_decode($part->brand);
-			if($part->image==''){
-				$part->image = 'img/default_image.png';
-			}else{
-				$part->image = PART_PATH.html_entity_decode($part->image);
-			}
-			$part->image.='?t='.time();
-			$response = $part->toArray();
-		});
-	break;
+    case 'edit_component':
+        Action::write(function ($_, &$response) {
+            $part = isset($_['id'])? Part::getById($_['id']):new Part;
+            $part->label = html_entity_decode($part->label);
+            $part->link = html_entity_decode($part->link);
+            $part->brand = html_entity_decode($part->brand);
+            if ($part->image=='') {
+                $part->image = 'img/default_image.png';
+            } else {
+                $part->image = PART_PATH.html_entity_decode($part->image);
+            }
+            $part->image.='?t='.time();
+            $response = $part->toArray();
+        });
+    break;
 
-	//RESOURCE
+    //RESOURCE
 
-	case 'save_resource':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$sketch = Sketch::getById($_['sketch']);
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			$resource = isset($_['id']) && is_numeric($_['id']) && !empty($_['id']) ? Resource::getByid($_['id']) : new Resource();
-			$resource->fromArray($_);
-			$resource->sort = 10;
-			if($resource->type=='readme' && $resource->id==0) $resource->sort = 0;
-			$resource->label = $resource->label == ''?'Sans titre '.date('d-m-Y H:i'):$resource->label;
-			$resource->save();
-	
-			$response = $resource->toArray();
-		});
-	break;
-	case 'save_resource_content':
-		Action::write(function($_,&$response){
-			global $myUser;
-			
-			$resource = Resource::getByid($_['id']);
-			$sketch = Sketch::getById($resource->sketch);
-			if($myUser->id != $sketch->owner) return;
-			$resource->fromArray($_);
-			$resource->save();
-		});
-	break;
-	
-	case 'get_resource_file':
-		global $myUser;
-		$resource = Resource::getById($_['id']);
-		$sketch =$resource->sketch_object;
-		if($myUser->id != $sketch->owner && !$sketch->public){
-			echo 'Désolé, vous n\'avez pas d\'accès à cette ressource...';
-			return;
-		}
-		$filepath = SKETCH_PATH.$resource->id.'/'.$_['file'];
-		$finfo = finfo_open(FILEINFO_MIME_TYPE); 
-		
-		$mime = finfo_file($finfo, $filepath);
-		
-		header('Content-Type: '.$mime);
-		header("Content-Length: " . filesize($filepath));
-		header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
-		header('Cache-Control: no-store, no-cache, must-revalidate');
-		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
-		header('Cache-Control: post-check=0, pre-check=0', FALSE);
-		header('Pragma: no-cache');
-		header("Content-Disposition: attachment; filename=\"".basename($filepath)."\"");
-		
-		echo file_get_contents($filepath);
-		finfo_close($finfo);
-	break;
-	
-	case 'get_resource_image':
-		global $myUser;
-		
-		$resource = Resource::getById($_['id']);
-		$sketch =$resource->sketch_object;
-		if($myUser->id != $sketch->owner && !$sketch->public){
-			readfile('img/default_image.png');
-			return;
-		}
-		$finfo = finfo_open(FILEINFO_MIME_TYPE);
-		$filepath = SKETCH_PATH.$resource->content;
-		$mime = finfo_file($finfo, $filepath);
-		header('Content-Type: '.$mime);
-		readfile($filepath);
-	break;
-	
-	case 'edit_resource':
-		Action::write(function($_,&$response){
-		
-			$resource = Resource::getById($_['id']);
-			global $myUser;
-			$sketch = Sketch::getById($resource->sketch);
-			$resource->label = html_entity_decode($resource->label);
-			$response = Type::toHtml($resource,$sketch);
-		});
-	break;
-	case 'delete_resource':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$resource = Resource::getById($_['id']);
-			$sketch = Sketch::getById($resource->sketch);
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			Resource::getById($_['id']);
-			$resource->remove();
-		});
-	break;
-	
-	/*FILES*/
-	case 'search_file':
-	
-	Action::write(function($_,&$response){
-			global $myUser;
-			if(!isset($_['id']) || !is_numeric($_['id'])) throw new Exception("Ressource non spécifiée");
-			
-			$resource = Resource::getById($_['id']);
-			$sketch = $resource->sketch_object;
-			
-			if($myUser->id != $sketch->owner && !$sketch->public) throw new Exception("Désolé, le sketch est privé");
-			
-			foreach(glob(SKETCH_PATH.'/'.$_['id'].'/*') as $file):
-				$icon = getExtIcon(getExt($file));
-				
-				$response['rows'][] = array('id'=>basename($file),'icon'=>$icon,'label'=>basename($file),'resource'=>$resource->id);
-			endforeach;
-		});
-	break;
-	
-	case 'download_file':
-			
-			global $myUser;
-			$path = SKETCH_PATH.'/'.$_['resource'];
-			
-			
-			$resource = Resource::getById($_['resource']);
-			$sketch = $resource->sketch_object;
-			if($myUser->id != $sketch->owner && !$sketch->public) throw new Exception("Permission refusée, le sketch est privé");
-			
-		
-			
-			$filename = $resource->label.'-'.time().'.zip';
-			$filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
-			$zip = new ZipArchive;
-			if(file_exists($filepath))unlink($filepath); 
-			$res = $zip->open($filepath, ZipArchive::CREATE);
-			if ($res === TRUE) {
-				foreach(glob($path.'/*') as $file)
-					$zip->addFile($file,basename($file));
-				
-				
-				$zip->close();
-			}
-		
-			header("Content-Type: application/zip");
-			header("Content-Length: " . filesize($filepath));
-			header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
-			header('Cache-Control: no-store, no-cache, must-revalidate');
-			header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
-			header('Cache-Control: post-check=0, pre-check=0', FALSE);
-			header('Pragma: no-cache');
-			header("Content-Disposition: attachment; filename=\"".$filename."\"");
-			readfile($filepath);
-			unlink($filepath); 
+    case 'save_resource':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $sketch = Sketch::getById($_['sketch']);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            $resource = isset($_['id']) && is_numeric($_['id']) && !empty($_['id']) ? Resource::getByid($_['id']) : new Resource();
+            $resource->fromArray($_);
+            $resource->sort = 10;
+            if ($resource->type=='readme' && $resource->id==0) {
+                $resource->sort = 0;
+            }
+            $resource->label = $resource->label == ''?'Sans titre '.date('d-m-Y H:i'):$resource->label;
+            $resource->save();
+    
+            $response = $resource->toArray();
+        });
+    break;
+    case 'save_resource_content':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            
+            $resource = Resource::getByid($_['id']);
+            $sketch = Sketch::getById($resource->sketch);
+            if ($myUser->id != $sketch->owner) {
+                return;
+            }
+            $resource->fromArray($_);
+            $resource->save();
+        });
+    break;
+    
+    case 'get_resource_file':
+        global $myUser;
+        $resource = Resource::getById($_['id']);
+        $sketch =$resource->sketch_object;
+        if ($myUser->id != $sketch->owner && !$sketch->public) {
+            echo 'Désolé, vous n\'avez pas d\'accès à cette ressource...';
+            return;
+        }
+        $filepath = SKETCH_PATH.$resource->id.'/'.$_['file'];
+        $finfo = finfo_open(FILEINFO_MIME_TYPE);
+        
+        $mime = finfo_file($finfo, $filepath);
+        
+        header('Content-Type: '.$mime);
+        header("Content-Length: " . filesize($filepath));
+        header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
+        header('Cache-Control: no-store, no-cache, must-revalidate');
+        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+        header('Cache-Control: post-check=0, pre-check=0', false);
+        header('Pragma: no-cache');
+        header("Content-Disposition: attachment; filename=\"".basename($filepath)."\"");
+        
+        echo file_get_contents($filepath);
+        finfo_close($finfo);
+    break;
+    
+    case 'get_resource_image':
+        global $myUser;
+        
+        $resource = Resource::getById($_['id']);
+        $sketch =$resource->sketch_object;
+        if ($myUser->id != $sketch->owner && !$sketch->public) {
+            readfile('img/default_image.png');
+            return;
+        }
+        $finfo = finfo_open(FILEINFO_MIME_TYPE);
+        $filepath = SKETCH_PATH.$resource->content;
+        $mime = finfo_file($finfo, $filepath);
+        header('Content-Type: '.$mime);
+        readfile($filepath);
+    break;
+    
+    case 'edit_resource':
+        Action::write(function ($_, &$response) {
+        
+            $resource = Resource::getById($_['id']);
+            global $myUser;
+            $sketch = Sketch::getById($resource->sketch);
+            $resource->label = html_entity_decode($resource->label);
+            $response = Type::toHtml($resource, $sketch);
+        });
+    break;
+    case 'delete_resource':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $resource = Resource::getById($_['id']);
+            $sketch = Sketch::getById($resource->sketch);
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            Resource::getById($_['id']);
+            $resource->remove();
+        });
+    break;
+    
+    /*FILES*/
+    case 'search_file':
+    
+    Action::write(function ($_, &$response) {
+            global $myUser;
+            if (!isset($_['id']) || !is_numeric($_['id'])) {
+                throw new Exception("Ressource non spécifiée");
+            }
+            
+            $resource = Resource::getById($_['id']);
+            $sketch = $resource->sketch_object;
+            
+            if ($myUser->id != $sketch->owner && !$sketch->public) {
+                throw new Exception("Désolé, le sketch est privé");
+            }
+            
+            foreach (glob(SKETCH_PATH.'/'.$_['id'].'/*') as $file):
+                $icon = getExtIcon(getExt($file));
+                
+                $response['rows'][] = array('id'=>basename($file), 'icon'=>$icon, 'label'=>basename($file), 'resource'=>$resource->id);
+            endforeach;
+        });
+    break;
+    
+    case 'download_file':
+            
+            global $myUser;
+            $path = SKETCH_PATH.'/'.$_['resource'];
+            
+            
+            $resource = Resource::getById($_['resource']);
+            $sketch = $resource->sketch_object;
+            if ($myUser->id != $sketch->owner && !$sketch->public) {
+                throw new Exception("Permission refusée, le sketch est privé");
+            }
+            
+        
+            
+            $filename = $resource->label.'-'.time().'.zip';
+            $filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
+            $zip = new ZipArchive;
+            if (file_exists($filepath)) {
+                unlink($filepath);
+            }
+            $res = $zip->open($filepath, ZipArchive::CREATE);
+            if ($res === true) {
+                foreach (glob($path.'/*') as $file) {
+                    $zip->addFile($file, basename($file));
+                }
+                
+                
+                $zip->close();
+            }
+        
+            header("Content-Type: application/zip");
+            header("Content-Length: " . filesize($filepath));
+            header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
+            header('Cache-Control: no-store, no-cache, must-revalidate');
+            header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+            header('Cache-Control: post-check=0, pre-check=0', false);
+            header('Pragma: no-cache');
+            header("Content-Disposition: attachment; filename=\"".$filename."\"");
+            readfile($filepath);
+            unlink($filepath);
 
-		
-	break;
-	
-	case 'delete_file':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$path = SKETCH_PATH.'/'.$_['resource'].'/'.$_['id'];
-			$resource = Resource::getById($_['resource']);
-			$sketch = $resource->sketch_object;
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			if(file_exists($path)) unlink($path);
-		});
-	break;
-	
-	/*PART*/
-	
-	case 'search_part':
-	
-	Action::write(function($_,&$response){
-			if(!isset($_['id']) || !is_numeric($_['id'])) throw new Exception("Ressource non spécifiée");
-			$resourceParts = ResourcePart::loadAll(array('resource'=>$_['id']),'sort');
-			foreach($resourceParts as $resourcePart):
-				$part = $resourcePart->part_object;
-				$part->label = html_entity_decode($part->label);
-				$part->link = html_entity_decode($part->link);
-				if($part->image == '') { 
-					$part->image = 'img/default_image.png';
-				}else{
-					$part->image = PART_PATH.$part->image;
-				}
-				$line = $part->toArray();
-				$line['id'] = $resourcePart->id;
-				$response['rows'][] = $line;
-			endforeach;
-		});
-	break;
-	
-	case 'delete_part':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$part = ResourcePart::getById($_['id']);
-			
-			$resource = $part->resource_object;
-			$sketch = $resource->sketch_object;
-			if($myUser->id != $sketch->owner) throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
-			ResourcePart::deleteById($_['id']);
-		});
-	break;
-	case 'save_part':
-		Action::write(function($_,&$response){
-			global $myUser;
-			$model = isset($_['model']) && is_numeric($_['model']) && !empty($_['model']) ? Part::getByid($_['model']) : new Part();
-			if($model->id==0){
-				$model->fromArray($_);
-				$model->save();
-			}
-			
-			$resourcePart = new ResourcePart();
-			$resourcePart->fromArray($_);
-			$resourcePart->part = $model->id;
-			$resourcePart->save();
-			
-		});
-	break;
-	
-	case 'autocomplete_part':
-		global $myUser;
-		$parts = Part::staticQuery("SELECT DISTINCT label,* FROM ".Part::tableName()." WHERE label LIKE ? GROUP BY label ORDER BY price ASC ",array('%'.$_['term'].'%'),true);
-		$rows = array();
-		levenshtein_deduplication($parts);
-		foreach($parts as $part):
-			$part->image = PART_PATH.$part->image;
-			$rows[] = array('label'=>$part->label.' ('.$part->price.'€)','value'=>$part->toArray());
-		endforeach;
-		echo json_encode($rows);
-	break;
-	
-	default:
-		
-	break;
+        
+    break;
+    
+    case 'delete_file':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $path = SKETCH_PATH.'/'.$_['resource'].'/'.$_['id'];
+            $resource = Resource::getById($_['resource']);
+            $sketch = $resource->sketch_object;
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            if (file_exists($path)) {
+                unlink($path);
+            }
+        });
+    break;
+    
+    /*PART*/
+    
+    case 'search_part':
+    
+    Action::write(function ($_, &$response) {
+            if (!isset($_['id']) || !is_numeric($_['id'])) {
+                throw new Exception("Ressource non spécifiée");
+            }
+            $resourceParts = ResourcePart::loadAll(array('resource'=>$_['id']), 'sort');
+            foreach ($resourceParts as $resourcePart):
+                $part = $resourcePart->part_object;
+                $part->label = html_entity_decode($part->label);
+                $part->link = html_entity_decode($part->link);
+                if ($part->image == '') {
+                    $part->image = 'img/default_image.png';
+                } else {
+                    $part->image = PART_PATH.$part->image;
+                }
+                $line = $part->toArray();
+                $line['id'] = $resourcePart->id;
+                $response['rows'][] = $line;
+            endforeach;
+        });
+    break;
+    
+    case 'delete_part':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $part = ResourcePart::getById($_['id']);
+            
+            $resource = $part->resource_object;
+            $sketch = $resource->sketch_object;
+            if ($myUser->id != $sketch->owner) {
+                throw new Exception("Permission refusée, seul l'auteur du sketch peux faire ça");
+            }
+            ResourcePart::deleteById($_['id']);
+        });
+    break;
+    case 'save_part':
+        Action::write(function ($_, &$response) {
+            global $myUser;
+            $model = isset($_['model']) && is_numeric($_['model']) && !empty($_['model']) ? Part::getByid($_['model']) : new Part();
+            if ($model->id==0) {
+                $model->fromArray($_);
+                $model->save();
+            }
+            
+            $resourcePart = new ResourcePart();
+            $resourcePart->fromArray($_);
+            $resourcePart->part = $model->id;
+            $resourcePart->save();
+            
+        });
+    break;
+    
+    case 'autocomplete_part':
+        global $myUser;
+        $parts = Part::staticQuery("SELECT DISTINCT label,* FROM ".Part::tableName()." WHERE label LIKE ? GROUP BY label ORDER BY price ASC ", array('%'.$_['term'].'%'), true);
+        $rows = array();
+        levenshtein_deduplication($parts);
+        foreach ($parts as $part):
+            $part->image = PART_PATH.$part->image;
+            $rows[] = array('label'=>$part->label.' ('.$part->price.'€)','value'=>$part->toArray());
+        endforeach;
+        echo json_encode($rows);
+    break;
+    
+    default:
+        
+    break;
 }
 
 
-function levenshtein_deduplication(&$objs){
-	foreach($objs as $obj1):
-		foreach($objs as $u=>$obj2):
-			if($obj1->id==$obj2->id) continue;
-			if(levenshtein($obj1->label,$obj2->label) < 5 )
-			unset($objs[$u]);
-		endforeach;
-	endforeach;
+function levenshtein_deduplication(&$objs)
+{
+    foreach ($objs as $obj1):
+        foreach ($objs as $u=>$obj2):
+            if ($obj1->id==$obj2->id) {
+                continue;
+            }
+    if (levenshtein($obj1->label, $obj2->label) < 5) {
+        unset($objs[$u]);
+    }
+    endforeach;
+    endforeach;
 }
-?>

+ 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();
+    }
 }
-
-?>

+ 460 - 438
class/Type.class.php

@@ -1,455 +1,477 @@
 <?php
 
 /**
-* Declare available resource types
-* @author valentin carruesco
-* @category Core
-* @license copyright
-*/
-
-
-class Type{
-
-	public static function get($uid){
-		$t = Type::all();
-		return $t[$uid];
-	}
-
-	public static function all(){
-		$types = array();
-
-
-		$types['readme'] = array(
-			'label' => 'README',
-			'extension' => 'md',
-			'codemirror' => array(
-				'smartIndent' => false,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['arduino'] = array(
-			'label' => 'Source Arduino',
-			'extension' => 'ino',
-			'codemirror' => array(
-				'mode'=>'clike',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-		$types['clike'] = array(
-			'label' => 'Source C++/C',
-			'extension' => 'cpp',
-			'codemirror' => array(
-				'mode'=>'clike',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-		$types['shell'] = array(
-			'label' => 'Shell',
-			'extension' => 'sh',
-			'codemirror' => array(
-				'mode'=>'shell',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['php'] = array(
-			'label' => 'Source PHP',
-			'extension' => 'php',
-			'codemirror' => array(
-				'mode'=>'php',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['python'] = array(
-			'label' => 'Source Python',
-			'extension' => 'py',
-			'codemirror' => array(
-				'mode'=>'python',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['c'] = array(
-			'label' => 'Source C++',
-			'extension' => 'cpp',
-			'codemirror' => array(
-				'mode'=>'clike',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['java'] = array(
-			'label' => 'Source JAVA',
-			'extension' => 'java',
-			'codemirror' => array(
-				'mode'=>'java',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['css'] = array(
-			'label' => 'Feuille CSS',
-			'extension' => 'css',
-			'codemirror' => array(
-				'mode'=>'css',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-		$types['javascript'] = array(
-			'label' => 'Source Javascript',
-			'extension' => 'js',
-			'codemirror' => array(
-				'mode'=>'javascript',
-				'theme'=>'monokai',
-				'lineNumbers' => true,
-				'readOnly' =>  false
-			)
-		);
-
-		$types['image'] = array(
-			'label' => 'Image',
-			'upload' => array(
-				'url'     => 'action.php?action=upload_resource',
-				'element' => '#resource p img:eq(0)',
-				'callback' => '$(\'#resource img:eq(0)\').attr(\'src\',r.url);'
-			)
-		);
-		
-		$types['files'] = array(
-			'label' => 'Set de fichiers',
-			'upload' => array(
-				'url'=>'action.php?action=upload_resource_file',
-				'element' => '#dropZoneFiles',
-				'callback' => "search_file();",
-			),
-			'extension' => 'zip'
-		);
-
-		$types['part'] = array(
-			'label' => 'Set de composants',
-			'extension' => 'part'
-		);
-
-		
-		return $types;
-	}
-	
-	public static function fromFileImport($file,$sketch,$type){
-		$resource = new Resource();
-		$resource->sketch = $sketch->id;
-		$stream = file_get_contents($file['tmp_name']);
-		$resource->label = $file['name'];
-		$resource->type = $type;
-		switch($resource->type){
-			case 'arduino':
-			case 'php':
-			case 'shell':
-			case 'python':
-			case 'c':
-			case 'css':
-			case 'javascript':
-			case 'java':
-			case 'readme':
-				$resource->content = file_get_contents($file['tmp_name']);
-				$enc = mb_detect_encoding($resource->content,"UTF-8, ISO-8859-1, GBK");
-				if($enc!='UTF-8')
-					$resource->content = iconv($enc,"utf-8",$resource->content); 
-				
-				
-				$resource->save();
-			break;
-			case 'files':
-				$resource->save();
-				$path = SKETCH_PATH.'/'.$resource->id;
-				if(!file_exists($path)) mkdir($path);
-				$zip = new ZipArchive;
-				$res = $zip->open($file['tmp_name']);
-				if ($res === TRUE) {
-				  $zip->extractTo($path);
-				  $zip->close();
-				}
-			break;
-			case 'image':
-				
-				$resource->save();
-				$name = $resource->id.'.'.$ext;
-				file_put_contents(SKETCH_PATH.$name,$stream);
-				$resource->content = $name;
-				$resource->save();
-			break;
-			default:
-			break;
-		}
-	}
-	
-	public static function fromImport($res,$sketch){
-		global $myUser;
-		$resource = new Resource();
-		$resource->fromArray($res);
-		$resource->id = null;
-		$resource->sketch = $sketch->id;
-		$stream = '';
-		
-		switch($resource->type){
-			case 'image':
-				$stream = base64_decode($resource->content);
-				$resource->content = '';
-			break;
-			case 'part':
-				$parts = $resource->content;
-				$resource->content = '';
-			break;
-			case 'files':
-				$files = $resource->content;
-				$resource->content = '';
-			break;
-			default:
-			break;
-		}
-
-
-		if(is_string($resource->content))
-			$resource->content = htmlspecialchars_decode($resource->content);
-	
-		$resource->save();
-		
-		switch($resource->type){
-			case 'image':
-				$resource->content = $resource->id.'.png';
-				file_put_contents(SKETCH_PATH.$resource->content,$stream);
-				$resource->save();
-			break;
-			case 'part':
-				foreach($parts as $p):
-				
-					$part = new Part();
-					$part->fromArray($p['part']);
-					$part->id = null;
-					$stream = base64_decode($part->image);
-					$part->owner = $myUser->id;
-					$part->save();
-					$name = $part->id.'.png';
-					file_put_contents(PART_PATH.$name,$stream);
-					$part->image = $name;
-					$part->save();
-					
-							
-					$resourcePart = new ResourcePart();
-					$resourcePart->fromArray($p['resourcePart']);
-					$resourcePart->id = null;
-					$resourcePart->part = $part->id;
-					$resourcePart->resource = $resource->id;
-					$resourcePart->save();
-					
-				endforeach;
-				$resource->content = '';
-				$resource->save();
-			break;
-			case 'files':
-				$folder = SKETCH_PATH.'/'.$resource->id;
-				if(!file_exists($folder)) mkdir($folder);
-				foreach($files as $file):
-					
-					$stream = base64_decode($file['stream']);
-					file_put_contents($folder.'/'.$file['label'],$stream);
-
-				endforeach;
-				$resource->content = '';
-				$resource->save();
-			break;
-			default:
-			break;
-		}
-	}
-	
-	
-	public static function toExport($resource){
-		$resource = $resource->toArray();
-		
-		switch($resource['type']){
-			case 'image':
-				$resource['content'] = base64_encode(file_get_contents(SKETCH_PATH.$resource['content']));
-			break;
-			case 'part':
-				$resource['content'] = array();
-				foreach(ResourcePart::loadAll(array('resource'=>$resource['id'])) as $resourcePart):
-					$part = $resourcePart->part_object;
-					$part = $part->toArray();
-					$resourcePart = $resourcePart->toArray();
-					if($part['image']!='') $part['image'] = base64_encode(file_get_contents(PART_PATH.$part['image']));
-					$resource['content'][] = array('resourcePart'=>$resourcePart,'part'=>$part);
-				endforeach;
-			break;
-			case 'files':
-				$resource['content'] = array();
-				$folder = SKETCH_PATH.'/'.$resource['id'];
-				foreach(glob($folder.'/*') as $file):
-					$resource['content'][] = array('label'=>basename($file),'stream'=>base64_encode(file_get_contents($file)));
-				endforeach;
-			break;
-			default:
-				$resource['content'] = htmlspecialchars(SKETCH_PATH.$resource['content']);
-			break;
-		}
-	
-		return $resource;
-	}
-	
-	public static function toHtml($resource,$sketch){
-		global $myUser;
-		$response = array();
-		$response = $resource->toArray();
-		$type = self::get($resource->type);
-		switch($resource->type){
-				
-				case 'image':
-					
-					
-						$image = $response['content']==''?'img/default_image.png':'action.php?action=get_resource_image&id='.$response['id'];
-						$response['content'] = '<img style="width:100%;height:auto;" class="dropzone" src="'.$image.'" />';
-					if($myUser->id == $sketch->owner){
-						$response['upload'] = $type['upload'];
-					}
-				break;
-				
-				case 'files':
-
-					if($myUser->id == $sketch->owner){
-						$response['upload'] = $type['upload'];
-						$response['content'] = '<div id="dropZoneFiles"><i class="fa fa-file-text-o"></i> Faites glisser vos fichiers ici</div>';
-					}
-					$response['callback'] = 'init_file();';
-					$response['content'] .= '<table class="table table-stripped table-bordered" id="files"><thead>
+ * Declare available resource types.
+ *
+ * @author valentin carruesco
+ *
+ * @category Core
+ *
+ * @license copyright
+ */
+class Type
+{
+    public static function get($uid)
+    {
+        $t = self::all();
+
+        return $t[$uid];
+    }
+
+    public static function all()
+    {
+        $types = array();
+
+        $types['readme'] = array(
+            'label' => 'README',
+            'extension' => 'md',
+            'codemirror' => array(
+                'smartIndent' => false,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['arduino'] = array(
+            'label' => 'Source Arduino',
+            'extension' => 'ino',
+            'codemirror' => array(
+                'mode' => 'clike',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+        $types['clike'] = array(
+            'label' => 'Source C++/C',
+            'extension' => 'cpp',
+            'codemirror' => array(
+                'mode' => 'clike',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+        $types['shell'] = array(
+            'label' => 'Shell',
+            'extension' => 'sh',
+            'codemirror' => array(
+                'mode' => 'shell',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['php'] = array(
+            'label' => 'Source PHP',
+            'extension' => 'php',
+            'codemirror' => array(
+                'mode' => 'php',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['python'] = array(
+            'label' => 'Source Python',
+            'extension' => 'py',
+            'codemirror' => array(
+                'mode' => 'python',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['c'] = array(
+            'label' => 'Source C++',
+            'extension' => 'cpp',
+            'codemirror' => array(
+                'mode' => 'clike',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['java'] = array(
+            'label' => 'Source JAVA',
+            'extension' => 'java',
+            'codemirror' => array(
+                'mode' => 'java',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['css'] = array(
+            'label' => 'Feuille CSS',
+            'extension' => 'css',
+            'codemirror' => array(
+                'mode' => 'css',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+        $types['javascript'] = array(
+            'label' => 'Source Javascript',
+            'extension' => 'js',
+            'codemirror' => array(
+                'mode' => 'javascript',
+                'theme' => 'monokai',
+                'lineNumbers' => true,
+                'readOnly' => false,
+            ),
+        );
+
+        $types['image'] = array(
+            'label' => 'Image',
+            'upload' => array(
+                'url' => 'action.php?action=upload_resource',
+                'element' => '#resource p img:eq(0)',
+                'callback' => '$(\'#resource img:eq(0)\').attr(\'src\',r.url);',
+            ),
+        );
+
+        $types['files'] = array(
+            'label' => 'Set de fichiers',
+            'upload' => array(
+                'url' => 'action.php?action=upload_resource_file',
+                'element' => '#dropZoneFiles',
+                'callback' => 'search_file();',
+            ),
+            'extension' => 'zip',
+        );
+
+        $types['part'] = array(
+            'label' => 'Set de composants',
+            'extension' => 'part',
+        );
+
+        return $types;
+    }
+
+    public static function fromFileImport($file, $sketch, $type)
+    {
+        $resource = new Resource();
+        $resource->sketch = $sketch->id;
+        $stream = file_get_contents($file['tmp_name']);
+        $resource->label = $file['name'];
+        $resource->type = $type;
+        switch ($resource->type) {
+            case 'arduino':
+            case 'php':
+            case 'shell':
+            case 'python':
+            case 'c':
+            case 'css':
+            case 'javascript':
+            case 'java':
+            case 'readme':
+                $resource->content = file_get_contents($file['tmp_name']);
+                $enc = mb_detect_encoding($resource->content, 'UTF-8, ISO-8859-1, GBK');
+                if ($enc != 'UTF-8') {
+                    $resource->content = iconv($enc, 'utf-8', $resource->content);
+                }
+
+                $resource->save();
+            break;
+            case 'files':
+                $resource->save();
+                $path = SKETCH_PATH.'/'.$resource->id;
+                if (!file_exists($path)) {
+                    mkdir($path);
+                }
+                $zip = new ZipArchive();
+                $res = $zip->open($file['tmp_name']);
+                if ($res === true) {
+                    $zip->extractTo($path);
+                    $zip->close();
+                }
+            break;
+            case 'image':
+
+                $resource->save();
+                $name = $resource->id.'.'.$ext;
+                file_put_contents(SKETCH_PATH.$name, $stream);
+                $resource->content = $name;
+                $resource->save();
+            break;
+            default:
+            break;
+        }
+    }
+
+    public static function fromImport($res, $sketch)
+    {
+        global $myUser;
+        $resource = new Resource();
+        $resource->fromArray($res);
+        $resource->id = null;
+        $resource->sketch = $sketch->id;
+        $stream = '';
+
+        switch ($resource->type) {
+            case 'image':
+                $stream = base64_decode($resource->content);
+                $resource->content = '';
+            break;
+            case 'part':
+                $parts = $resource->content;
+                $resource->content = '';
+            break;
+            case 'files':
+                $files = $resource->content;
+                $resource->content = '';
+            break;
+            default:
+            break;
+        }
+
+        if (is_string($resource->content)) {
+            $resource->content = htmlspecialchars_decode($resource->content);
+        }
+
+        $resource->save();
+
+        switch ($resource->type) {
+            case 'image':
+                $resource->content = $resource->id.'.png';
+                file_put_contents(SKETCH_PATH.$resource->content, $stream);
+                $resource->save();
+            break;
+            case 'part':
+                foreach ($parts as $p):
+
+                    $part = new Part();
+                    $part->fromArray($p['part']);
+                    $part->id = null;
+                    $stream = base64_decode($part->image);
+                    $part->owner = $myUser->id;
+                    $part->save();
+                    $name = $part->id.'.png';
+                    file_put_contents(PART_PATH.$name, $stream);
+                    $part->image = $name;
+                    $part->save();
+
+                    $resourcePart = new ResourcePart();
+                    $resourcePart->fromArray($p['resourcePart']);
+                    $resourcePart->id = null;
+                    $resourcePart->part = $part->id;
+                    $resourcePart->resource = $resource->id;
+                    $resourcePart->save();
+
+                endforeach;
+                $resource->content = '';
+                $resource->save();
+            break;
+            case 'files':
+                $folder = SKETCH_PATH.'/'.$resource->id;
+                if (!file_exists($folder)) {
+                    mkdir($folder);
+                }
+                foreach ($files as $file):
+
+                    $stream = base64_decode($file['stream']);
+                    file_put_contents($folder.'/'.$file['label'], $stream);
+
+                endforeach;
+                $resource->content = '';
+                $resource->save();
+            break;
+            default:
+            break;
+        }
+    }
+
+    public static function toExport($resource)
+    {
+        $resource = $resource->toArray();
+
+        switch ($resource['type']) {
+            case 'image':
+                $resource['content'] = base64_encode(file_get_contents(SKETCH_PATH.$resource['content']));
+            break;
+            case 'part':
+                $resource['content'] = array();
+                foreach (ResourcePart::loadAll(array('resource' => $resource['id'])) as $resourcePart):
+                    $part = $resourcePart->part_object;
+                    $part = $part->toArray();
+                    $resourcePart = $resourcePart->toArray();
+                    if ($part['image'] != '') {
+                        $part['image'] = base64_encode(file_get_contents(PART_PATH.$part['image']));
+                    }
+                    $resource['content'][] = array('resourcePart' => $resourcePart, 'part' => $part);
+                endforeach;
+            break;
+            case 'files':
+                $resource['content'] = array();
+                $folder = SKETCH_PATH.'/'.$resource['id'];
+                foreach (glob($folder.'/*') as $file):
+                    $resource['content'][] = array('label' => basename($file), 'stream' => base64_encode(file_get_contents($file)));
+                endforeach;
+            break;
+            default:
+                $resource['content'] = htmlspecialchars(SKETCH_PATH.$resource['content']);
+            break;
+        }
+
+        return $resource;
+    }
+
+    public static function toHtml($resource, $sketch)
+    {
+        global $myUser;
+        $response = array();
+        $response = $resource->toArray();
+        $type = self::get($resource->type);
+        switch ($resource->type) {
+
+                case 'image':
+
+                        $image = $response['content'] == '' ? 'img/default_image.png' : 'action.php?action=get_resource_image&id='.$response['id'];
+                        $response['content'] = '<img style="width:100%;height:auto;" class="dropzone" src="'.$image.'" />';
+                    if ($myUser->id == $sketch->owner) {
+                        $response['upload'] = $type['upload'];
+                    }
+                break;
+
+                case 'files':
+
+                    if ($myUser->id == $sketch->owner) {
+                        $response['upload'] = $type['upload'];
+                        $response['content'] = '<div id="dropZoneFiles"><i class="fa fa-file-text-o"></i> Faites glisser vos fichiers ici</div>';
+                    }
+                    $response['callback'] = 'init_file();';
+                    $response['content'] .= '<table class="table table-stripped table-bordered" id="files"><thead>
 						<tr>
 							<th>Fichiers disponibles <a class="btn btn-primary" href="action.php?action=download_file&resource='.$resource->id.'" style="float:right;" title="Télécharger les fichiers"><i class="fa fa-file-zip-o"></i> Télécharger</a></th>';
-					
-					$response['content'] .= '<th style="width:50px;"></th>';
-							
-					$response['content'] .= '</tr></thead><tbody>';
-					
-					$response['content'] .= '<tr style="display:none" data-id="{{id}}">
+
+                    $response['content'] .= '<th style="width:50px;"></th>';
+
+                    $response['content'] .= '</tr></thead><tbody>';
+
+                    $response['content'] .= '<tr style="display:none" data-id="{{id}}">
 							<td ><a href="action.php?action=get_resource_file&id={{resource}}&file={{label}}"><i class="fa {{icon}}"></i> {{label}}</a></td>';
-					
-					
-						$response['content'] .= '<td>';
-						if($myUser->id == $sketch->owner)
-						$response['content'] .= '<div class="btn btn-danger" onclick="delete_file(this);"><i class="fa fa-times" ></i></div>';
-						$response['content'] .= '</td>';
-					
-					$response['content'] .= '</tr>';
-					$response['content'] .='</tbody></table>';
-				break;
-				case 'part':
-					$response['callback'] = 'init_part();';
-					$response['content'] = '<table class="table table-stripped table-bordered" id="parts"><thead>
+
+                        $response['content'] .= '<td>';
+                        if ($myUser->id == $sketch->owner) {
+                            $response['content'] .= '<div class="btn btn-danger" onclick="delete_file(this);"><i class="fa fa-times" ></i></div>';
+                        }
+                        $response['content'] .= '</td>';
+
+                    $response['content'] .= '</tr>';
+                    $response['content'] .= '</tbody></table>';
+                break;
+                case 'part':
+                    $response['callback'] = 'init_part();';
+                    $response['content'] = '<table class="table table-stripped table-bordered" id="parts"><thead>
 						<tr>
 							<th>Libellé</th>
 							<!--<th>Lien</th>
 							<th>Prix</th>-->';
-					if($myUser->id == $sketch->owner)
-							$response['content'] .= '<th></th>';
-							
-					$response['content'] .= '</tr>';
-						
-					if($myUser->id == $sketch->owner){
-						$response['content'] .= '<tr id="partForm" data-action="save_part" data-id="">
+                    if ($myUser->id == $sketch->owner) {
+                        $response['content'] .= '<th></th>';
+                    }
+
+                    $response['content'] .= '</tr>';
+
+                    if ($myUser->id == $sketch->owner) {
+                        $response['content'] .= '<tr id="partForm" data-action="save_part" data-id="">
 							<td><input type="text" id="label" class="form-control"></td>
 							<!--<td><input type="url" id="link"  class="form-control"></td>
 							<td><input type="text" id="price"  class="form-control input-mini"></td>-->
 							<td><div class="btn btn-success" onclick="save_part();"><i class="fa fa-plus"></i></div></td>
 						</tr>';
-					}
-						
-					$response['content'] .= '</thead><tbody>';
-					
-					$response['content'] .= '<tr style="display:none" data-id="{{id}}">
+                    }
+
+                    $response['content'] .= '</thead><tbody>';
+
+                    $response['content'] .= '<tr style="display:none" data-id="{{id}}">
 							<td ><a href="{{link}}"><div class="componentImage"><img src="{{image}}"/></div> {{label}}</a> {{#price}}<code>{{price}} €</code>{{/price}}{{#brand}} <small>{{brand}}</small>{{/brand}}</td>';
-					
-					if($myUser->id == $sketch->owner)
-						$response['content'] .= '<td><div class="btn btn-danger" onclick="delete_part(this);"><i class="fa fa-times" ></i></div></td>';
-					
-					$response['content'] .= '</tr>';
-					$response['content'] .='</tbody></table>';
-				break;
-			}
-			//for sources
-			if(isset($type['codemirror'])){
-				$response['content'] = '<textarea>'.$response['content'].'</textarea>';
-				$response['code'] = $type['codemirror'];
-				if($myUser->id != $sketch->owner) $response['code']['readOnly'] = true;
-			}
-			
-			return $response;
-	}
-	
-	public static function toFileStream($resource){
-		$type = self::get($resource->type);
-		$file = (object) array('name'=>slugify($resource->label),'content'=>'');
-		if(isset($type['extension'])) $file->name .= '.'.$type['extension'];
-		switch($resource->type){
-			case 'part':
-				$file->content = '> '.strtoupper($resource->label).PHP_EOL;
-				$file->content .= str_repeat('=',strlen($resource->label)+2).PHP_EOL;
-				foreach(ResourcePart::loadAll(array('resource'=>$resource->id)) as $resourcePart):
-					$part = $resourcePart->part_object;
-					$file->content .= $part->label."\t";
-					if(isset($part->link) && !empty($part->link)) $file->content .= $part->link."\t";
-					if(isset($part->price) && !empty($part->price)) $file->content .= $part->price.'€';
-					$file->content .= PHP_EOL;
-				endforeach;
-			break;
-			case 'files':
-
-				global $myUser;
-				$path = SKETCH_PATH.'/'.$resource->id;
-
-				$filename = $resource->label.'-'.time().'.zip';
-				$filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
-				$zip = new ZipArchive;
-				if(file_exists($filepath))unlink($filepath); 
-				$res = $zip->open($filepath, ZipArchive::CREATE);
-				if ($res === TRUE) {
-					foreach(glob($path.'/*') as $f)
-						$zip->addFile($f,basename($f));
-					
-					$zip->close();
-				}
-			
-				$file->name = slugify($resource->label).'.zip';
-				$file->content = file_get_contents($filepath);
-
-			break;
-			case 'image':
-				$ext = getExt($resource->content);
-				$file->name = slugify($resource->label).'.'.$ext;
-				if(file_exists(SKETCH_PATH.$resource->content))
-				$file->content = file_get_contents(SKETCH_PATH.$resource->content);
-			break;
-			default:
-				$file->content = html_entity_decode($resource->content);
-			break;
-		}
-		return $file;
-	}
-	
-}
 
-?>
+                    if ($myUser->id == $sketch->owner) {
+                        $response['content'] .= '<td><div class="btn btn-danger" onclick="delete_part(this);"><i class="fa fa-times" ></i></div></td>';
+                    }
+
+                    $response['content'] .= '</tr>';
+                    $response['content'] .= '</tbody></table>';
+                break;
+            }
+            //for sources
+            if (isset($type['codemirror'])) {
+                $response['content'] = '<textarea>'.$response['content'].'</textarea>';
+                $response['code'] = $type['codemirror'];
+                if ($myUser->id != $sketch->owner) {
+                    $response['code']['readOnly'] = true;
+                }
+            }
+
+        return $response;
+    }
+
+    public static function toFileStream($resource)
+    {
+        $type = self::get($resource->type);
+        $file = (object) array('name' => slugify($resource->label), 'content' => '');
+        if (isset($type['extension'])) {
+            $file->name .= '.'.$type['extension'];
+        }
+        switch ($resource->type) {
+            case 'part':
+                $file->content = '> '.strtoupper($resource->label).PHP_EOL;
+                $file->content .= str_repeat('=', strlen($resource->label) + 2).PHP_EOL;
+                foreach (ResourcePart::loadAll(array('resource' => $resource->id)) as $resourcePart):
+                    $part = $resourcePart->part_object;
+                    $file->content .= $part->label."\t";
+                    if (isset($part->link) && !empty($part->link)) {
+                        $file->content .= $part->link."\t";
+                    }
+                    if (isset($part->price) && !empty($part->price)) {
+                        $file->content .= $part->price.'€';
+                    }
+                    $file->content .= PHP_EOL;
+                endforeach;
+            break;
+            case 'files':
+
+                global $myUser;
+                $path = SKETCH_PATH.'/'.$resource->id;
+
+                $filename = $resource->label.'-'.time().'.zip';
+                $filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
+                $zip = new ZipArchive();
+                if (file_exists($filepath)) {
+                    unlink($filepath);
+                }
+                $res = $zip->open($filepath, ZipArchive::CREATE);
+                if ($res === true) {
+                    foreach (glob($path.'/*') as $f) {
+                        $zip->addFile($f, basename($f));
+                    }
+
+                    $zip->close();
+                }
+
+                $file->name = slugify($resource->label).'.zip';
+                $file->content = file_get_contents($filepath);
+
+            break;
+            case 'image':
+                $ext = getExt($resource->content);
+                $file->name = slugify($resource->label).'.'.$ext;
+                if (file_exists(SKETCH_PATH.$resource->content)) {
+                    $file->content = file_get_contents(SKETCH_PATH.$resource->content);
+                }
+            break;
+            default:
+                $file->content = html_entity_decode($resource->content);
+            break;
+        }
+
+        return $file;
+    }
+}

+ 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']);
+    }

+ 25 - 14
component.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">
@@ -21,7 +21,7 @@
 						<tr data-id="{{id}}" style="display:none;">
 							<td>{{id}}</td>
 							<td><div class="componentImage"><img src="{{image}}"/></div></td>
-							<td>{{label}}</td>
+							<td>{{label}}<br/><small class="text-muted"><a href="{{link}}" target="_blank">{{link}}</a></small></td>
 							<td>{{brand}}</td>
 							<td>{{price}}</td>
 							<td>
@@ -45,15 +45,26 @@
 	        <h4 class="modal-title">Edition composant</h4>
 	      </div>
 	      <div class="modal-body">
-	      	<label for="label">Libellé</label>
-	        <input class="form-control" type="text" id="label"/>
-	        <label for="label">Marque</label>
-	        <input class="form-control" type="text" id="brand"/>
-	        <label for="label">Prix</label>
-	        <input class="form-control" type="text" id="price"/>
-			<label for="imageUpload">Image (fichier)</label><br/>
-			<img src="img/default_image.png" style="width:100px;height:100px;" id="imageUpload"/>
-			
+                <div class="form-group">
+	          <label for="label">Libellé</label>
+	          <input class="form-control" type="text" id="label"/>
+	        </div>
+                <div class="form-group">
+	          <label for="label">Marque</label>
+	          <input class="form-control" type="text" id="brand"/>
+	        </div>
+                <div class="form-group">
+	          <label for="label">Lien</label>
+	          <input class="form-control" type="text" id="link"/>
+	        </div>
+                <div class="form-group">
+	          <label for="label">Prix</label>
+	          <input class="form-control" type="text" id="price"/>
+	        </div>
+                <div class="form-group">
+	          <label for="imageUpload">Image (fichier)</label><br/>
+	          <img src="img/default_image.png" style="width:100px;height:100px;" id="imageUpload"/>
+	        </div>
 	      </div>
 	      <div class="modal-footer">
 	      	<button type="button" class="btn btn-primary" onclick="save_component();" data-dismiss="modal">Enregistrer</button>
@@ -65,9 +76,9 @@
 	</div>
 			
 	<?php
-	 else: 
-		header('index.php');
-	 endif; ?>
+     else:
+        header('index.php');
+     endif; ?>
 
 <?php 
 

+ 15 - 16
constant.php

@@ -1,22 +1,21 @@
 <?php
 
-define('__ROOT__',dirname(__FILE__).DIRECTORY_SEPARATOR);
-define('TIME_ZONE','Europe/Paris');
+define('__ROOT__', dirname(__FILE__).DIRECTORY_SEPARATOR);
+define('TIME_ZONE', 'Europe/Paris');
 define('ENTITY_PREFIX', '');
-define('DATABASE_PATH','database/.db');
-define('BASE_CONNECTION_STRING','sqlite:'.DATABASE_PATH);
-define('BASE_LOGIN',null);
-define('BASE_PASSWORD',null);
-define('UPLOAD_PATH','upload');
-define('SKETCH_PATH',UPLOAD_PATH.'/sketch/');
-define('PART_PATH',UPLOAD_PATH.'/part/');
-define('ALLOWED_RESOURCE_IMAGE','jpg,png,jpeg,gif,bmp');
+define('DATABASE_PATH', 'database/.db');
+define('BASE_CONNECTION_STRING', 'sqlite:'.DATABASE_PATH);
+define('BASE_LOGIN', null);
+define('BASE_PASSWORD', null);
+define('UPLOAD_PATH', 'upload');
+define('SKETCH_PATH', UPLOAD_PATH.'/sketch/');
+define('PART_PATH', UPLOAD_PATH.'/part/');
+define('ALLOWED_RESOURCE_IMAGE', 'jpg,png,jpeg,gif,bmp');
 //Laisser vide si pas de vérification sur les resources de fichiers, sinon placez les extension
 //autorisées sous la forme : jpg,png,jpeg,gif,bmp,txt,doc,docx,cmd,bat,exe,cpp,c,h,hpp,ino,php,js,css,ttf,woff,svg,pdf,xls,xlsx,sql,ico,doc,docx
-define('ALLOWED_RESOURCE_FILE','');
-define('ALLOWED_RESOURCE_SIZE',1000000);
+define('ALLOWED_RESOURCE_FILE', '');
+define('ALLOWED_RESOURCE_SIZE', 1000000);
 
-define('PROGRAM_NAME','Hackpoint');
-define('SOURCE_VERSION','1.0');
-define('BASE_VERSION','1.0');
-?>
+define('PROGRAM_NAME', 'Hackpoint');
+define('SOURCE_VERSION', '1.0');
+define('BASE_VERSION', '1.0');

+ 16 - 3
css/main.css

@@ -1,3 +1,12 @@
+html, body, #wrap {
+	height: 100%;
+}
+
+body > #wrap {
+	min-height: 100%;
+	height: auto;
+	padding-bottom: 60px;
+}
 
 .input-mini{
 	max-width:60px;
@@ -46,8 +55,12 @@ display:none;
 }
 
 .footer{
-	color:#ffffff;
-	text-align:center;
+	position: relative;
+	height: 60px;
+	margin-top: -60px;
+	padding: 20px 0;
+	color: #ffffff;
+	text-align: center;
 }
 /* ==========================================================================
    Author's custom styles
@@ -214,4 +227,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>

+ 151 - 143
function.php

@@ -1,163 +1,171 @@
 <?php
-function secondToTime($seconds) {
-  $t = round($seconds);
-  return sprintf('%02d:%02d:%02d', ($t/3600),($t/60%60), $t%60);
+function secondToTime($seconds)
+{
+    $t = round($seconds);
+    return sprintf('%02d:%02d:%02d', ($t/3600), ($t/60%60), $t%60);
 }
-function app_autoloader($class_name) {
-		require_once('class/'.$class_name.'.class.php');
+function app_autoloader($class_name)
+{
+    require_once('class/'.$class_name.'.class.php');
 }
-function errorToException( $errno, $errstr, $errfile, $errline, $errcontext)
+function errorToException($errno, $errstr, $errfile, $errline, $errcontext)
 {
-	if(strpos($errstr,'disk_')!==false) return;
-	throw new ErrorException($errstr, 0, $errno, $errfile, $errline);   
+    if (strpos($errstr, 'disk_')!==false) {
+        return;
+    }
+    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
 }
 
 
 function slugify($text)
-	{ 
-	  // replace non letter or digits by -
-	  $text = preg_replace('~[^\\pL\.\d]+~u', '-', $text);
-	  // trim
-	  $text = trim($text, '-');
-	  // transliterate
-	  $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
-	  // lowercase
-	  $text = strtolower($text);
-	  // remove unwanted characters
-	  $text = preg_replace('~[^-\.\w]+~', '', $text);
+{
+    // replace non letter or digits by -
+      $text = preg_replace('~[^\\pL\.\d]+~u', '-', $text);
+      // trim
+      $text = trim($text, '-');
+      // transliterate
+      $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
+      // lowercase
+      $text = strtolower($text);
+      // remove unwanted characters
+      $text = preg_replace('~[^-\.\w]+~', '', $text);
 
-	  if (empty($text))
-	    return 'n-a';
-	  return $text;
+    if (empty($text)) {
+        return 'n-a';
+    }
+    return $text;
 }
-function secure_user_vars($var){
-	if(is_array($var)){
-		$array = array();
-		foreach($var as $key=>$value):
-			$array[secure_user_vars($key)] = secure_user_vars($value);
-		endforeach;
-		return $array;
-	}else{
-		return htmlspecialchars($var, ENT_NOQUOTES, "UTF-8");
-	}
+function secure_user_vars($var)
+{
+    if (is_array($var)) {
+        $array = array();
+        foreach ($var as $key=>$value):
+            $array[secure_user_vars($key)] = secure_user_vars($value);
+        endforeach;
+        return $array;
+    } else {
+        return htmlspecialchars($var, ENT_NOQUOTES, "UTF-8");
+    }
 }
 
-function base64_to_image($base64_string, $output_file) {
-    $ifp = fopen($output_file, "wb"); 
+function base64_to_image($base64_string, $output_file)
+{
+    $ifp = fopen($output_file, "wb");
     $data = explode(',', $base64_string);
-    fwrite($ifp, base64_decode($data[1])); 
-    fclose($ifp); 
-    return $output_file; 
+    fwrite($ifp, base64_decode($data[1]));
+    fclose($ifp);
+    return $output_file;
 }
 
-function getExt($file){
-	$ext = explode('.',$file);
-	return strtolower(array_pop($ext));
+function getExt($file)
+{
+    $ext = explode('.', $file);
+    return strtolower(array_pop($ext));
 }
 
-function getExtIcon($ext){
-	$icon = '';
-	switch($ext){
-		case '7z':
-		case 'rar':
-		case 'gz':
-		case 'zip':
-			$icon = 'fa-file-archive-o';
-		break;
-		
-		case 'php':
-		case 'js':
-		case 'py':
-		case 'c':
-		case 'cpp':
-		case 'css':
-		case 'h':
-		case 'hpp':
-		case 'html':
-		case 'htm':
-		case 'asp':
-		case 'jsp':
-			$icon = 'fa-file-code-o';
-		break;
-		
-		case 'xls':
-		case 'xlsx':
-		case 'csv':
-			$icon = 'fa-file-excel-o';
-		break;
-		
-		case 'bmp':
-		case 'jpg':
-		case 'jpeg':
-		case 'ico':
-		case 'gif':
-		case 'png':
-		case 'svg':
-			$icon = 'fa-file-image-o';
-		break;
-		
-		case 'pdf':
-			$icon = 'fa-file-pdf-o';
-		break;
-		case 'ppt':
-		case 'pptx':
-			$icon = 'fa-file-powerpoint-o';
-		break;
-		
-		case 'txt':
-		case 'htaccess':
-		case 'md':
-			$icon = 'fa-file-text-o';
-		break;
-		
-		case 'doc':
-		case 'docx':
-		case 'word':
-			$icon = 'fa-file-word-o';
-		break;
-		
-		case 'avi':
-		case 'wmv':
-		case 'mov':
-		case 'divx':
-		case 'xvid':
-		case 'mkv':
-		case 'flv':
-		case 'mpeg':
-		case 'h264':
-		case 'rmvb':
-		case 'mp4':
-			$icon = 'fa-file-movie-o';
-		break;
-		
-		case 'wav':
-		case 'ogg':
-		case 'ogv':
-		case 'ogx':
-		case 'oga':
-		case 'riff':
-		case 'bwf':
-		case 'wma':
-		case 'flac':
-		case 'aac':
-		case 'mp3':
-			$icon = 'fa-file-audio-o';
-		break;
-		default:
-			$icon = 'fa-file-o';
-		break;
-	}
-	return $icon;
+function getExtIcon($ext)
+{
+    $icon = '';
+    switch ($ext) {
+        case '7z':
+        case 'rar':
+        case 'gz':
+        case 'zip':
+            $icon = 'fa-file-archive-o';
+        break;
+        
+        case 'php':
+        case 'js':
+        case 'py':
+        case 'c':
+        case 'cpp':
+        case 'css':
+        case 'h':
+        case 'hpp':
+        case 'html':
+        case 'htm':
+        case 'asp':
+        case 'jsp':
+            $icon = 'fa-file-code-o';
+        break;
+        
+        case 'xls':
+        case 'xlsx':
+        case 'csv':
+            $icon = 'fa-file-excel-o';
+        break;
+        
+        case 'bmp':
+        case 'jpg':
+        case 'jpeg':
+        case 'ico':
+        case 'gif':
+        case 'png':
+        case 'svg':
+            $icon = 'fa-file-image-o';
+        break;
+        
+        case 'pdf':
+            $icon = 'fa-file-pdf-o';
+        break;
+        case 'ppt':
+        case 'pptx':
+            $icon = 'fa-file-powerpoint-o';
+        break;
+        
+        case 'txt':
+        case 'htaccess':
+        case 'md':
+            $icon = 'fa-file-text-o';
+        break;
+        
+        case 'doc':
+        case 'docx':
+        case 'word':
+            $icon = 'fa-file-word-o';
+        break;
+        
+        case 'avi':
+        case 'wmv':
+        case 'mov':
+        case 'divx':
+        case 'xvid':
+        case 'mkv':
+        case 'flv':
+        case 'mpeg':
+        case 'h264':
+        case 'rmvb':
+        case 'mp4':
+            $icon = 'fa-file-movie-o';
+        break;
+        
+        case 'wav':
+        case 'ogg':
+        case 'ogv':
+        case 'ogx':
+        case 'oga':
+        case 'riff':
+        case 'bwf':
+        case 'wma':
+        case 'flac':
+        case 'aac':
+        case 'mp3':
+            $icon = 'fa-file-audio-o';
+        break;
+        default:
+            $icon = 'fa-file-o';
+        break;
+    }
+    return $icon;
 };
 
-function imageResize($image,$w,$h){
-	$resource = imagecreatefromstring(file_get_contents($image));
-	$size = getimagesize($image);
-	$h = (($size[1] * (($w)/$size[0])));
-	$thumbnail = imagecreatetruecolor($w , $h);
-	imagecopyresampled($thumbnail ,$resource, 0,0, 0,0, $w, $h, $size[0],$size[1]);
-	imagedestroy($resource);
-	imagejpeg($thumbnail , $image, 100);
+function imageResize($image, $w, $h)
+{
+    $resource = imagecreatefromstring(file_get_contents($image));
+    $size = getimagesize($image);
+    $h = (($size[1] * (($w)/$size[0])));
+    $thumbnail = imagecreatetruecolor($w, $h);
+    imagecopyresampled($thumbnail, $resource, 0, 0, 0, 0, $w, $h, $size[0], $size[1]);
+    imagedestroy($resource);
+    imagejpeg($thumbnail, $image, 100);
 }
-
-?>

+ 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">

+ 28 - 23
install.php

@@ -40,32 +40,35 @@
 		
 
 <?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');
-	
-$_ = array_map('secure_user_vars',array_merge($_POST,$_GET));
-	
-if(isset($_SESSION['currentUser']))
-$myUser =unserialize($_SESSION['currentUser']);	
+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']);
+    }
 
 
-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 (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');
 
-$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 +76,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 -->

+ 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' ?>