'key', 'path' => 'longstring', 'label' => 'string', 'type' => 'string', 'extension' => 'string', 'size' => 'string', 'creatorSite' => 'int' ); //Récupération de la racine de la GED public static function root(){ return File::dir().'documents'.SLASH; } public function save(){ $this->path = str_replace('\\','/',$this->path); parent::save(); } //Récuperation du chemin ou du flux de thumbnail associé à l'élement public function thumbnail(){ if(!in_array($this->extension, array('jpg','png','jpeg','gif','bmp'))) return $this->icon(); if(!file_exists(self::root().'.thumbnails')) mkdir(self::root().'.thumbnails',755,true); $thumbname = str_replace(array('\\','./'),array('/',''),$this->path); $thumbnail = self::root().'.thumbnails'.SLASH.base64_encode($thumbname).'.'.$this->extension; if(!file_exists($thumbnail)){ $osPath = File::convert_decoding($this->path); copy(self::root().$osPath,$thumbnail); Image::resize($thumbnail,200,200); } $path ='data:image/'.$this->extension.';base64,'.base64_encode(file_get_contents($thumbnail)); return $path; } //Récuperation du chemin di'one à l'élement public function icon(){ $path = 'plugin/document/img/file-types/'; $icon = $this->type == 'directory' ? 'folder.svg' : 'document.svg'; switch($this->extension){ case 'docx': case 'doc': case 'dot': case 'dotx': $icon = 'word.svg'; break; case 'xls': case 'xlsx': case 'csv': $icon = 'excel.svg'; break; case 'ppt': case 'pptx': $icon = 'powerpoint.svg'; break; case 'pdf': $icon = 'pdf.svg'; break; case 'mp3': case 'wav': case 'mp4': case 'flac': $icon = 'music.svg'; break; case 'html': case 'htm': $icon = 'url.svg'; break; case 'msg': $icon = 'mail.svg'; break; case 'psd': $icon = 'photoshop.svg'; break; case 'rss': $icon = 'feed.svg'; break; case 'mdb': $icon = 'access.svg'; break; case 'bat': case 'sh': case 'cmd': $icon = 'gear.svg'; break; case 'php': case 'js': case 'java': case 'class': case 'css': case 'c': case 'cpp': case 'py': $icon = 'code.svg'; break; case 'jpg': case 'jpeg': case 'png': case 'bmp': case 'gif': case 'svg': $icon = 'image.svg'; break; } $path .= $icon; return $path; } //Récuperation d'un element base depuis un chemin physique, ou d'un objet element rensiegné a partir du path si non existant en base (prend du utf8 en entré) public static function fromPath($path){ global $conf; $element = new self(); //convertion utf8 ISO-8859-1 $osPath = File::convert_decoding($path); $infos = pathinfo($path); //Gestion label $element->label = mt_basename($path); $element->path = str_replace(self::root(),'',$path); $element->type = is_dir($osPath) ? 'directory' : 'file'; $exists = file_exists($osPath); if($element->type == 'directory'){ $path .= SLASH; $fi = new FilesystemIterator($osPath, FilesystemIterator::SKIP_DOTS); $element->childNumber = iterator_count($fi); $element->size = 0; } else { if(isset($infos['extension'])) $element->extension = $infos['extension']; $element->size = !$exists ? 0 : filesize($osPath); } $element->updated = !$exists ? 0 : filemtime($osPath); $element->created = !$exists ? 0 : filectime($osPath); $relativePath = trim(str_replace(Element::root(),'',$path),SLASH); if ($baseElement = Element::load(array('path'=>str_replace('\\','/',$relativePath) ))) { $element->creator = $baseElement->creator; $element->id = $baseElement->id; } $element->path = trim($element->path,SLASH); return $element; } //Récuperation de la liste des élements d'un repertoire (tiens compte des droits utilisateur) (attends de l'utf8) public static function browse($scanned,$folderOnly = false){ global $myUser,$myFirm; require_once(__DIR__.SLASH.'ElementRight.class.php'); $osScanned = File::convert_decoding($scanned); $elements = array(); User::check_access('document','read'); $toCheck = array(); //Récuperation du tableau des rang utilisateur sous forme d'id. $ranks = array(); if(!$myUser->superadmin){ foreach($myUser->ranks[$myFirm->id] as $rank) $ranks[] = $rank->id; } $existingPathes = array(); //Pour chaque fichier physique existant foreach(glob($osScanned) as $osPath){ $osPath = str_replace(SLASH.'.'.SLASH, SLASH, $osPath); $basePath = File::convert_encoding($osPath); if((substr(mt_basename($osPath), 0,1)=='.') || ($folderOnly && !is_dir($osPath))) continue; //Récuperation/création de l'element objet correspondant (frompath n'accepte que l'utf8, on lui donne le basepath) $line = Element::fromPath($basePath); $existingPathes[] = $line->path; //Si l'element correspondant n'existe pas en base, on le créé if($line->id == ''){ $line->creator = 'anonymous'; $line->save(); } //Si l'utilisateur n'est pas le créateur, pas un super admin et n'a pas le droit configure sur les documents on check les partages de droits if($myUser->login != $line->creator && !$myUser->can('document','configure') && !$myUser->superadmin){ $can = false; $pathes = array(); $path = ''; //Récuperation des chemins dont on doit récuperer les droits : // ex : pour le fichier a/b/c les chemins sont a, a/b, et a/b/c foreach(explode(SLASH,$line->path) as $i=>$pathCrumb){ if($i!=0) $path.= SLASH; $path.= $pathCrumb; $pathes[] = str_replace("\\","\\\\",$path); } //On récupere les droits pour chaques chemin foreach(ElementRight::staticQuery('SELECT er.*,el.path as '.Element::tableName().'_join_path FROM {{table}} er LEFT JOIN '.Element::tableName().' el ON el.id=er.element WHERE ( er.entity="all" OR (er.entity="user" AND er.uid=?) OR (er.entity="rank" AND er.uid IN ('.implode(',',$ranks).') ) ) AND element IN(SELECT id from '.Element::tableName().' WHERE path IN ("'.implode('","',$pathes).'")) ',array($myUser->login),true,1) as $right){ $element = $right->join('element'); //Si les droits sont sur un dossier parent et son recursif OU si les droits sont sur le fichier concerné on continue la verification if($right->element == $line->id || ($right->recursive && strpos($line->path, $element->path)!==false ) ) $can = true; } if(!$can) continue; } $elements[] = $line; } //Element::staticQuery('SELECT * FROM {{table}} WHERE `path` NOT IN ("'.implode('","',$existingPathes).'") '); return $elements; } //Téléchargement d'un fichier ou d'un repertoire (prends de l'utf 8 en entrée) public static function download($path){ $osPath = File::convert_decoding($path); if(!file_exists($osPath)) return ''; $element = Element::fromPath($path); if(!self::hasRight($element,'read')) throw new Exception("Permissions insuffisantes",403); if(is_dir($osPath)){ $filename = rand().'-'.time().'.zip'; $filepath = sys_get_temp_dir().SLASH.$filename; $zip = new ZipArchive; $res = $zip->open($filepath, ZipArchive::CREATE); if ($res === TRUE) { $ressources = glob_recursive($osPath.SLASH.'*') ; foreach($ressources as $i=>$resource){ if(is_dir($resource)) continue; $filename = $resource; $filename = File::convert_encoding($filename); $filename = str_replace($path,mt_basename($path),$filename); $filename=iconv("UTF-8", "IBM850", $filename); if(!$zip->addFromString($filename, file_get_contents($resource))) throw new Exception("Impossible de compresser le fichier ".$path); } if(count($ressources)==0) $zip->addEmptyDir('.'); $zip->close(); } $stream = file_get_contents($filepath); unlink($filepath); }else{ $stream = file_get_contents($osPath); } return $stream; } //Supression d'un répértoire ou d'un fichier en base et en physique (prends de l'utf 8 en entrée) public static function remove($path){ global $myUser,$myFirm; require_once(__DIR__.SLASH.'ElementRight.class.php'); $osPath = File::convert_decoding($path); if(!file_exists($osPath)) return; $element = Element::fromPath($path); $dbPath = str_replace('\\','/',$element->path); if(!self::hasRight($element,'edit')) throw new Exception("Permissions insuffisantes",403); if(is_dir($osPath)) { self::remove_dir_recursive($osPath); Element::staticQuery('DELETE FROM {{table}} WHERE `path` = ? OR `path` LIKE ?',array($dbPath,$dbPath.'/%')); } else { unlink($osPath); Element::delete(array('path'=>$dbPath)); } ElementRight::delete(array('element'=>$element->id)); } //Copie d'un répértoire ou d'un fichier en base et en physique (prends de l'utf 8 en entrée) public static function copy($path,$to){ global $conf, $myUser; $osPath = File::convert_decoding($path); $osTo = File::convert_decoding($to); if(!file_exists($osPath)) return; $element = Element::fromPath($path); if(file_exists($osTo)) return false; $parentPathTo = dirname($to); $parentOsPathTo = dirname($osTo); if(!file_exists($parentOsPathTo)) throw new Exception("Dossier de destination inexistant",404); $parentTo = Element::fromPath($parentPathTo); if(!self::hasRight($parentTo,'read')) throw new Exception("Permissions insuffisantes",403); if(!self::hasRight($element,'read')) throw new Exception("Permissions insuffisantes",403); $dbPath = str_replace('\\','/',$element->path); if($element->type == 'directory'){ $element->path = $element->path; //Si c'est un dossier, on récupere tous les élements commendant par ce nom afin de gerer leurs chemins $baseElement = Element::staticQuery('SELECT * FROM {{table}} WHERE `path` = ? OR `path` LIKE ?',array($dbPath,$dbPath.'/%'), true); } else { $baseElement = Element::load(array('path'=>$dbPath)); if(is_object($baseElement) && $baseElement->id != 0) $element->id = $baseElement->id; } if(!copy($osPath,$osTo)) throw new Exception('Erreur lors de la copie...'); $newelement = Element::fromPath($to); if(is_array($baseElement)){ foreach ($baseElement as $elem) { if($elem->path == $dbPath) $elem->label = $element->label; $elem->path = str_replace($dbPath, $newelement->path, $elem->path); $elem->id = 0; $elem->save(); } } else { $baseElement->path = $newelement->path; $baseElement->label = $newelement->label; $baseElement->id = 0; $baseElement->save(); } } //Déplacement d'un répertoire ou d'un fichier en base et en physique public static function move($path,$to, $label=''){ global $conf, $myUser; $osPath = File::convert_decoding($path); $osTo = File::convert_decoding($to); if(!file_exists($osPath)) return; $element = Element::fromPath($path); //Si le dossier se termine par un ., on supprime ce . (non pris en charge par l'os) if($element->type=="directory" && substr($to, -1,1) =='.') $to = substr($to, 0,strlen($to)-1); if($to == $path) return $element; if(!self::hasRight($element,'edit')) throw new Exception("Permissions insuffisantes",403); $parentPathTo = dirname($to); $parentPathOsTo = dirname($osTo); if(!file_exists($parentPathOsTo)) throw new Exception("Dossier de destination inexistant",404); $parentTo = Element::fromPath($parentPathTo); if(!self::hasRight($parentTo,'read')) throw new Exception("Permissions insuffisantes",403); $dbPath = str_replace('\\','/',$element->path); if(file_exists($osTo)) return false; if($element->type == 'directory'){ $element->path = $oldPath = $element->path; //Si c'est un dossier, on récupere tous les élements commencant par ce nom afin de modifier leurs chemins $baseElement = Element::staticQuery('SELECT * FROM {{table}} WHERE `path` = ? OR `path` LIKE ?',array($dbPath,$dbPath.'/%'), true); } else { $baseElement = Element::load(array('path'=>$dbPath)); if(is_object($baseElement) && $baseElement->id != 0) $element->id = $baseElement->id; } try { if(!rename($osPath,$osTo)) throw new Exception('Un élément du même nom existe déjà.'); } catch (Exception $e) { return false; } $toElement = Element::fromPath($to); //Si type est image, on supprime l'ancienne miniature if(in_array($element->extension, array('jpg','png','jpeg','gif','bmp')) && file_exists(self::root().'.thumbnails'.SLASH.base64_encode($element->path).'.'.$element->extension)) unlink(self::root().'.thumbnails'.SLASH.base64_encode($element->path).'.'.$element->extension); if(is_array($baseElement)){ foreach ($baseElement as $elem) { if($elem->path == $oldPath) $elem->label = $toElement->label; $elem->path = str_replace($dbPath, $toElement->path, $elem->path); $elem->save(); } } else { $baseElement->path = $toElement->path; $baseElement->label = $toElement->label; $baseElement->save(); } return $toElement; } //Ajout d'un fichier en base et en physique (prend de l'utf8 en entré pour le path) public static function addFile($path,$stream){ //on enregistre le fichier dans l'encodage du système $osPath = File::convert_decoding($path); $parentPath = dirname($path); $parentOsPath = File::convert_decoding($parentPath); if(!file_exists($parentOsPath)) throw new Exception("Dossier de destination inexistant",404); $parent = Element::fromPath($parentPath); if(!self::hasRight($parent,'read')) throw new Exception("Permissions insuffisantes",403); file_put_contents($osPath, $stream); $element = Element::fromPath($path, array('preview'=>false)); $element->save(); return $element; } //Ajout d'un dossier en base et en physique (prend de l'utf8 en entré pour le path) public static function addFolder($path, $recursive = false, $checkRight=true, $creator = null){ $osPath = File::convert_decoding($path); $parentPath = dirname($path); $osParentPath = dirname($osPath); if(!file_exists($osParentPath)) { if(!$recursive){ throw new Exception("Dossier parent ".$parentPath." inexistant",404); } else { self::addFolder($parentPath, $recursive, $checkRight, $creator); } } $parent = Element::fromPath($parentPath); if($checkRight && !self::hasRight($parent,'read')) throw new Exception("Permissions insuffisantes",403); if(file_exists($osPath)) return; mkdir($osPath,0755,$recursive); $element = Element::fromPath($path); if(isset($creator)) $element->creator = $creator; $element->save(); return $element; } public static function hasRight($element,$type){ global $myUser,$myFirm; require_once(__DIR__.SLASH.'ElementRight.class.php'); $documentRight = ''; switch($type){ case 'read': $documentRight = 'read'; break; case 'delete': $documentRight = 'edit'; break; case 'edit': $documentRight = 'edit'; break; } if(!$myUser->can('document',$type)) return false; if($myUser->login == $element->creator || $myUser->can('document','configure') || $myUser->superadmin == 1) return true; $allPathes = array(); $rootPath = ''; foreach (explode(SLASH,$element->path) as $i=>$crumb) { $rootPath .= ($i==0?'':SLASH).$crumb; $allPathes[] = str_replace("\\","\\\\",$rootPath); } $userRanks = array(); foreach ($myUser->ranks[$myFirm->id] as $rank) $userRanks[] = $rank->id; $query = 'SELECT COUNT(id) allowed FROM {{table}} WHERE (element IN(SELECT id from '.Element::tableName().' WHERE path IN("'.implode('","',$allPathes).'")) AND `'.$documentRight.'`=1) AND (entity="all" OR (entity="user" AND uid=?) '; if(count($userRanks)!=0) $query .= ' OR (entity="rank" AND uid IN('.implode(',',$userRanks).')) '; $query .= ')'; $result = ElementRight::staticQuery($query,array($myUser->login)); $result = $result->fetch(); if(!$result || $result['allowed']<=0) return false; return true; } public static function remove_dir_recursive($path) { foreach(glob($path.SLASH.'*') as $element){ if(mt_basename($element) == '.' || mt_basename($element) == '..') continue; if(is_dir($element)) { self::remove_dir_recursive($element); } else { unlink($element); } } rmdir($path); } } ?>