<?php
///////////////////////////////////////////////////////////////////////////////////////////
///Script PHP/MYSQL of management of classifieds ads developed by Script PAG
///Script PAG all rights reserved. Use under license. http://www.script-pag.com
///////////////////////////////////////////////////////////////////////////////////////////

require_once(__DIR__.'/cache_upload.php');

class uploadManager {
	//	@var _tmp_path String
	private $_tmp_path = '/upload/tmp/';
	
	//// upload process
	public function upload($datas = null, $files = null) {
		global $cache_upload;
		pool::execute('uploadContext');
		$context = isset($cache_upload[$_POST['context']]) ? $_POST['context'] : 'default';
		$field_name = $datas && isset($datas['field_name']) ? $datas['field_name'] : null;
		if(sizeof($files) > 0) {
			$id = $datas && isset($datas['id']) ? $datas['id'] : null;
			$file_name = $datas && isset($datas['file_name']) ? $datas['file_name'] : null;
			$current_part = $datas && isset($datas['part']) ? $datas['part'] : 1;
			$total_part = $datas && isset($datas['nb_part']) ? $datas['nb_part'] : 1;
			$max_file = isset($context['max_file']) ? (isset($context['dimensions']) && sizeof($context['dimensions']) > 1 ? $context['max_file'] * sizeof($context['dimensions']) : $context['max_file']) : 10;
			$result = sizeof($files) > $max_file ? 'error_upload_max_files' : true;
			if($result === true) {
				$new_files = array();
				foreach($files as $key => $file) {
					if($this->__fileIsAuth($context, $file, ($total_part > 1 ? $current_part : null), $file_name, $field_name)) {
						$tmp_path = $this->__formatUploadPath($this->_tmp_path.($id ? $id : '').($total_part > 1 ? '/'.self::__clean($file_name) : ''));
						$tmp_file_name = self::__cleanFileName(is_array($file['name']) ? $file['name'][0] : $file['name']);
						if(move_uploaded_file((is_array($file['tmp_name']) ? $file['tmp_name'][0] : $file['tmp_name']), $tmp_path.DIRECTORY_SEPARATOR.$tmp_file_name)) {
							$new_files = array('tmp_name' => $tmp_path.DIRECTORY_SEPARATOR.$file_name, 'name' => $file_name);
						} else $result = 'error_upload';
					}
				}
				if(!is_array($result)) $result = $new_files;
			}
		} else $result = 'error_upload';
		return $result;
	}
	
	//// Test if the file could be loaded
	public function completedUpload($datas = null, $files = null) {
		$result = true;
		if(isset($datas['total']) && $datas['total'] > 1) {
			$id = isset($datas['id']) ? $datas['id'] : null;
			$file_name = isset($datas['file_name']) ? $datas['file_name'] : null;
			$tmp_path = $this->_tmp_path.($id ? $id : '');
			$tmp_files = array();
			for($i = 0; $i < $datas['total']; $i++) {
				$part_file = $tmp_path.DIRECTORY_SEPARATOR.self::__clean($file_name).DIRECTORY_SEPARATOR.self::__cleanFileName($file_name.'.part'.($i + 1));
				if(file_exists(self::__path($part_file))) $tmp_files[$i] = $part_file;
			}
			if(sizeof($tmp_files) === (int) $datas['total']) {
				$tmp_file = fopen(self::__path($tmp_path.DIRECTORY_SEPARATOR.self::__cleanFileName($file_name)), 'a+');
				foreach($tmp_files as $file) fwrite($tmp_file, file_get_contents(self::__path($file)));
				fclose($tmp_file);
				$this->__deleteTmpDir(self::__path($tmp_path.DIRECTORY_SEPARATOR.self::__clean($file_name)));
				$relative_path = self::__path($tmp_path.DIRECTORY_SEPARATOR.self::__cleanFileName($file_name));
				$result = array('file_name' => self::__cleanFileName($file_name), 'tmp_name' => substr($relative_path, strrpos($relative_path, $this->_tmp_path)));
			} else $result = 'error_upload';
		} else if(isset($datas['file_name'])) {
			$id = isset($datas['id']) ? $datas['id'] : null;
			$file_name = $datas['file_name'];
			$tmp_path = $this->_tmp_path.($id ? $id : '');
			$relative_path = self::__path($tmp_path.DIRECTORY_SEPARATOR.self::__cleanFileName($file_name));
			$result = array('file_name' => self::__cleanFileName($file_name), 'tmp_name' => substr($relative_path, strrpos($relative_path, $this->_tmp_path)));
		}
		return $result;
	}
	
	//// Move file after submit action
	public function moveFile($datas = null, $files = null, $response = null, $module_context = null) {
		global $cache_upload;
		$result = true;	
		if(isset($datas) && isset($datas['move_file'])) {
			$context = isset($datas['module_contexr']) && is_array($datas['module_contexr']) ? $datas['module_contexr'] : $cache_upload[$datas['context']];
			if(is_array($datas['move_file'])) {
				$result = array();
				foreach($datas['move_file'] as $key => $field) {
					$new_filename = '';
					$tmp_dir = '';
					if(strpos($key, 'sp-uploader') > -1) {
						foreach($field as $file) {
							$tmp_file = self::__path($file);
							$new_path = $this->__defineMovePath($file, $context);
							if(strlen($new_filename) == 0) {
								$new_filename = $this->__defineMoveName($file, $context);
							}
							if(file_exists($tmp_file)) {
								if(!rename($tmp_file, $new_path.DIRECTORY_SEPARATOR.$new_filename)) {
									$result = 'error_upload';
									break;
								} else {
									$tmp_dir = array_slice(explode(DIRECTORY_SEPARATOR, $tmp_file), 0, -1);
									$basedir = realpath(__DIR__.'/../../../');
									$relative_path = self::__path($new_path.DIRECTORY_SEPARATOR.self::__cleanFileName($new_filename));
									$result[] = substr($relative_path, strlen($basedir));
								}
							}
						}
						if(is_array($tmp_dir)) $this->__deleteTmpDir(implode(DIRECTORY_SEPARATOR, $tmp_dir), true);
					} else $result[] = $field;
				}
			} else {
				$tmp_file = self::__path($datas['move_file']);
				$new_path = $this->__defineMovePath($datas['move_file'], $context);
				$new_filename = $this->__defineMoveName($datas['move_file'], $context);
				if(file_exists($tmp_file)) {
					if(!rename($tmp_file, $new_path.DIRECTORY_SEPARATOR.$new_filename)) 
						$result = 'error_upload';
					else {
						$tmp_dir = array_slice(explode(DIRECTORY_SEPARATOR, $tmp_file), 0, -1);
						$this->__deleteTmpDir(implode(DIRECTORY_SEPARATOR, $tmp_dir), true);
						$basedir = realpath(__DIR__.'/../../../');
						$relative_path = self::__path($new_path.DIRECTORY_SEPARATOR.self::__cleanFileName($new_filename));
						$result = substr($relative_path, strlen($basedir));
					}
				} else $result = 'error_upload';
			}
		} else if($files && sizeof($files) > 0 && isset($datas['jresized']) && $datas['jresized'] == true) {
			foreach($files as $index_name => $field) {
				$temp_dir = '';
				foreach($field as $key => $file) {
					if(!is_numeric($key)) {
						$tmp_dir = '';
						foreach($file as $index => $elt) {
							$content = file_get_contents($elt["tmp_name"]);
							if(strpos($content, '#;')) {
								$items = array_filter(explode('#;', $content));
								$old_file = sizeof($items) > 1 ? false : true;
								foreach($items as $k => $item) {
									if(strpos($item, '#') > 0) {
										list($filename, $tmp_path, $context_name, $field_name) = explode('#', $item);
										if(file_exists($tmp_path)) {
											$context = isset($module_context) && is_array($module_context) ? $module_context : $cache_upload[$context_name];
											$new_path = $this->__defineMovePath($filename, $context, $response);
											$new_filename = $this->__defineMoveName($filename, $context, $response);
											$tmp_dir = explode(DIRECTORY_SEPARATOR, $tmp_path);
											$temp_dir = array_slice(explode(DIRECTORY_SEPARATOR, $tmp_path), 0, -1);
											if(!rename($tmp_path, $new_path.DIRECTORY_SEPARATOR.$new_filename)) $result = 'error_upload';
										} else $result = 'error_upload';
									}
								}
							} 
						}
						if(!is_array($result)) {
							$this->__deleteTmpDir(implode(DIRECTORY_SEPARATOR, $tmp_dir), true);
						}
					} else {
						$content = file_get_contents($file["tmp_name"]);
						if(strpos($content, '#;')) {
							$items = array_filter(explode('#;', $content));
							$old_file = sizeof($items) > 1 ? false : true;
							$tmp_dir = '';
							foreach($items as $k => $item) {
								if(strpos($item, '#') > 0) {
									list($filename, $tmp_path, $context_name, $field_name) = explode('#', $item);
									if(preg_match('#www.youtube.com#i', $tmp_path) || preg_match('#player.vimeo.com#i', $tmp_path) || preg_match('#www.dailymotion.com#i', $tmp_path)) {
										$tmp_tmp_path = substr($tmp_path, (strrpos($tmp_path, '_') + 1));
										$tmp_path = substr($tmp_path, 0, strrpos($tmp_path, '/') ).'/'.$tmp_tmp_path;
									}
									$context = isset($module_context) && is_array($module_context) ? $module_context : $cache_upload[$context_name];
									if($old_file == true && file_exists(self::__path($tmp_path))) {
										$result = $this->__renameFile($filename, $tmp_path, $context, $response);
									} else if(file_exists($tmp_path)) {
										$new_path = $this->__defineMovePath($filename, $context, $response);
										$new_filename = $this->__defineMoveName($filename, $context, $response);
										$tmp_dir = explode(DIRECTORY_SEPARATOR, $tmp_path);
										$temp_dir = array_slice(explode(DIRECTORY_SEPARATOR, $tmp_path), 0, -1);
										if(!rename($tmp_path, $new_path.DIRECTORY_SEPARATOR.$new_filename)) $result = 'error_upload';
									} else if(isset($tmp_path) && strlen($tmp_path) > 0) $result = 'error_upload';			
								}
							}
						}
					}
				}
				if(!is_array($result) && is_array($temp_dir) && sizeof($temp_dir) > 0) {
					$this->__deleteTmpDir(implode(DIRECTORY_SEPARATOR, $temp_dir), true);
				}

			}
		}
		return $result;
	}
	
	//// Call to daylimotion api to get video data
	public static function callDaylimotionApi($video_id) {
		$result = array('name' => '', 'blob' => '', 'file_url' => '', 'file_type' => '', 'file_name' => '', 'video' => '');
		$feed = json_decode(@file_get_contents('https://api.dailymotion.com/video/'.$video_id.'?fields=thumbnail_1080_url,title'));
		if(!empty($feed) && isset($feed->thumbnail_1080_url))
			$result = self::__formatApiFeed('https://www.dailymotion.com/embed/video/'.$video_id, $feed->thumbnail_1080_url, (isset($feed->title) && strlen($feed->title) > 0 ? $feed->title : null));
		return $result;
	}
	
	//// Call to vimeo api to get video data
	public static function callVimeoApi($video_id) {
		$result = array('name' => '', 'blob' => '', 'file_url' => '', 'file_type' => '', 'file_name' => '', 'video' => '');
		$feed = json_decode(@file_get_contents('https://vimeo.com/api/v2/video/'.$video_id.'.json'));
		if(is_array($feed) && isset($feed[0]) && !empty($feed[0]) && isset($feed[0]->thumbnail_large))
			$result = self::__formatApiFeed('https://player.vimeo.com/video/'.$video_id, $feed[0]->thumbnail_large, (isset($feed[0]->title) && strlen($feed[0]->title) > 0 ? $feed[0]->title : null));
		return $result;
	}
	
	//// Call to youtube api to get video data
	public static function callYoutubeApi($video_id) {
		$result = array('name' => '', 'blob' => '', 'file_url' => '', 'file_type' => '', 'file_name' => '', 'video' => '');
		$url_thumb = 'https://img.youtube.com/vi/'.$video_id.'/maxresdefault.jpg';
		$feed = json_decode(@file_get_contents('https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v='.$video_id));
		if(!empty($feed))
			$result = self::__formatApiFeed('https://www.youtube.com/embed/'.$video_id, $url_thumb, (isset($feed->title) && strlen($feed->title) > 0 ? $feed->title : null));
		return $result;
	}
	
	//// Return exif image type
	public static function getImageType($filename) {
		$type = array(
			1 => 'image/gif',
			2 => 'image/jpeg',
			3 => 'image/png',
			6 => 'image/bmp',
			18 => 'image/webp'
		);
		$exif = exif_imagetype($filename);
		return $exif && isset($type[$exif]) ? $type[$exif] : null;
	}
	
	//// Decode base64 content
	private function __decodeChunk($chunk) {
		$content = explode(';base64,', $chunk);
		if (!is_array($content) || !isset($content[1])) return false;
		$content = base64_decode($content[1]);
		return !$content ? $content : false;
	}
	
	//// Test if the final could be loaded
	private function __fileIsAuth($context, $file, $part_extension = null, $file_name = null, $field_name = null) {
		$file_extension = self::__fileExstension($file_name);
		$extensions_allowed = isset($context['accepted']) ?(is_array($context['accepted']) ? $context['accepted'] : explode(',', $context['accepted'])) : array();
		$errors = 'error_file_not_allowed';
		$result = in_array($file_extension, $extensions_allowed) ? ($part_extension ? (substr($file['name'], strpos($file['name'], $file_extension) == $file_extension.'.part'.$part_extension) ? true : $errors) : true) : $errors;
		if($result === true) {
			$file_size = self::__fileExstension($file['size']);
			$env_max_size = self::__sizeToOctet(strtolower(ini_get('error_max_size')));
			$context_max_size = self::__sizeToOctet((isset($this->context['max_size']) ? $this->context['max_size'] : strtolower(ini_get('error_max_size'))));
			$max_size_auth = $context_max_size < $env_max_size ? $context_max_size : $env_max_size;
			$result = $file_size > $max_size_auth ? 'error_max_size' : true;
		}
		return $result;
	}
	
	//// Delete Directory and his content
	private function __deleteTmpDir($dir, $only_empty = false) {
		if(strpos($dir, DIRECTORY_SEPARATOR.'upload'.DIRECTORY_SEPARATOR) > -1 && is_dir($dir)) {
			$dir_iterator = new \RecursiveDirectoryIterator($dir);
			$iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::CHILD_FIRST);
			if($only_empty == false || ($iterator->getDepth() == 0 && $only_empty == true)) {
				foreach($iterator as $files) {
					$files->isDir() ? @rmdir($files) : @unlink($files);
				}
				@rmdir($dir);
			}

		}
		return true;
	}
	
	//// Rename file
	private function __renameFile($filename, $tmp_path, $context_max_size, $datas = null) {
		$result = true;
		if(isset($context['dimensions']) && sizeof($context['dimensions']) > 0) {
			foreach($context['dimensions'] as $key => $dimension) {
				$path = isset($dimension['path']) ? $dimension['path'] : 'upload';
				$new_path = $this->__formatUploadPath($path, $datas);
				$new_filename = isset($dimension['name']) ? $dimension['name'] : (isset($dimension['callback_name']) && method_exists($datas, $dimension['callback_name']) ? call_user_func_array(array($datas, $dimension['callback_name']), array(self::__fileExstension($filename), $new_path)) : $filename);
				if($new_filename != $filename) {
					$old_file_name = $filename;
					if(strrpos($new_path, '/mediums') > -1) $old_file_name = substr($filename, 0, strrpos($filename, '.')).'_medium'.self::__fileExstension($filename);
					if(strrpos($new_path, '/thumbnails') > -1) $old_file_name = substr($filename, 0, strrpos($filename, '.')).'_thumbnail'.self::__fileExstension($filename);
					$old_file = $new_path.DIRECTORY_SEPARATOR.$old_file_name;
					if(!rename($old_file, $new_path.DIRECTORY_SEPARATOR.$new_filename))
						$result = 'error_upload';
				}
			}
		}
		return $result;
	}
	
	//// Define name of  move file
	private function __defineMoveName($filename, $context, $datas = null) {
		$new_filename = isset($context['name']) ? $context['name'] : $filename;
		if(strpos($filename, 'size@') > -1 && isset($context['dimensions'])) {
			foreach($context['dimensions'] as $key => $dimension) {
				if(isset($dimension['size']) && strpos($filename, 'size@'.$dimension['size'][0].'@'.$dimension['size'][1]) > -1) {
					$new_filename = isset($dimension['name']) ? $dimension['name'] : (isset($dimension['callback_name']) && method_exists($datas, $dimension['callback_name']) ? call_user_func_array(array($datas, $dimension['callback_name']), array(self::__fileExstension($filename))) : str_replace('size@'.$dimension['size'][0].'@'.$dimension['size'][1].'_', '', $filename));
				}
			}
		} else if(isset($context['callback_name'])) {
			$new_filename = method_exists($datas, $context['callback_name']) ? call_user_func_array(array($datas, $context['callback_name']), array(self::__fileExstension($filename))) : $filename;
		}
		if(!self::__fileExstension($new_filename)) $new_filename = $new_filename.self::__fileExstension($filename);
		return self::__cleanFileName(self::__replaceAttributs($new_filename, $datas, true));
	}
	
	//// Define path and create dir move file
	private function __defineMovePath($filename, $context, $datas = null) {
		$path = isset($context['path']) ? $context['path'] : 'upload';
		if(strpos($filename, 'size@') > -1 && isset($context['dimensions'])) {
			foreach($context['dimensions'] as $key => $dimension) {
				if(isset($dimension['size']) && strpos($filename, 'size@'.$dimension['size'][0].'@'.$dimension['size'][1]) > -1)
					$path = isset($dimension['path']) ? $dimension['path'] : DIRECTORY_SEPARATOR.'upload';
			}
		}
		return $this->__formatUploadPath($path, $datas);
	}
	
	//// Create and return $path
	private function __formatUploadPath($path, $datas = null) {
		$new_path = self::__path(self::__replaceAttributs($path, $datas, true));
		if(!is_dir($new_path)) {
			if(strrpos($path, $this->_tmp_path) > -1) umask(0);
			@mkdir($new_path, 0777, true);
			if(strrpos($path, $this->_tmp_path) > -1) umask(022);
		}
		return $new_path;
	}
	
	//// Return a blob object for an url
	private static function __urlToBlob($url) {
		$result = array('type' => '', 'content' => '');
		$headers = array();
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
		curl_setopt($curl, CURLOPT_HEADER, 1);
		curl_setopt($curl, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) {
			$data = explode(':', $header, 2);
			if(sizeof($data) == 2) {
				$headers[trim($data[0])] = trim($data[1]);
			}
			return strlen($header);
		});
		$response = curl_exec($curl);
		$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
		$header = substr($response, 0, $header_size);
		$result['type'] = isset($headers['Content-Type']) ? $headers['Content-Type'] : (isset($headers['content-type']) ? $headers['content-type'] : '');
		$result['content'] = trim(substr($response, $header_size));
		curl_close($curl);
		return $result;
	}
	
	//// Format api feed result
	private static function __formatApiFeed($video, $url, $name = null) {
		$result = array('name' => $name, 'blob' => '', 'file_url' => $url, 'file_type' => '', 'file_name' => '', 'video' => $video);
		$blob = $url && strlen($url) > 0 ? self::__urlToBlob($url) : null;
		if($blob && strlen($blob['content']) > 0) $result['blob'] = base64_encode($blob['content']);
		$result['file_type'] = $blob && strlen($blob['type']) > 0 ? $blob['type'] : self::getImageType($url);
		$filename = explode('/', $result['file_url']);
		$result['file_name'] = array_pop($filename);
		if(!self::__fileExstension($url)) {
			$extension = explode('/', $result['file_type']);
			$result['file_name'] .= '.'.array_pop($extension);
		}
		return $result;
	}
	
	//// Return file name formated
	private static function __cleanFileName($string, $all_to_lower = false) {
		$name = $all_to_lower === true ? preg_replace('/[^a-zA-Z0-9_\-.@]/u', '_', strtolower(self::__noAccent($string))) : preg_replace('/[^a-zA-Z0-9_\-.@]/u', '_', self::__noAccent($string));
		$name = preg_replace('/[-]{2,}/u', '-', preg_replace('/[\_]{2,}/u', '_', $name));
		return $name;
	}
	
	//// Return string without accent
	private static function __noAccent($string) {
		$to_clean = array('œ', 'À','Á','Â','Ã','Ä','Å','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ò','Ó','Ô','Õ','Ö','Ù','Ú','Û','Ü','Ý','à','á','â','ã','ä','å','ç','è','é','ê','ë','ì','í','î','ï','ð','ò','ó','ô','õ','ö','ù','ú','û','ü','ý','ÿ','&agrave;', '&Agrave;', '&acirc;', '&Acirc;', '&eacute;', '&Eacute;', '&egrave;', '&Egrave;', '&ecirc;', '&Ecirc;', '&ocirc;', '&Ocirc;', '&ucirc;', '&Ucirc;', '&uuml;', '&Uuml;', '&icirc;', '&Icirc;', '&iuml;', '&Iuml;');
		$to_replace = array('oe', 'a','a','a','a','a','a','c','e','e','e','e','i','i','i','i','o','o','o','o','o','u','u','u','u','y','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i','o','o','o','o','o','o','u','u','u','u','y','y','a', 'a','a', 'a', 'e', 'e', 'e', 'e', 'e', 'e', 'o', 'o', 'u', 'u', 'u', 'i', 'i', 'i', 'i');
		return str_replace($to_clean, $to_replace, trim($string));
	}

	//// Return string formated
	private static function __clean($string, $all_to_lower = false) {
		return $all_to_lower === true ? preg_replace('/[^a-zA-Z0-9]/u', '', strtolower(self::__noAccent($string))) : preg_replace('/[^a-zA-Z0-9]/u', '', lcfirst(ucwords(preg_replace('/[-_]/u', ' ', self::__noAccent($string)))));
	}
	
	//// Return file extension if string is file
	private static function __fileExstension($string) {
		$extension =  pathinfo($string, PATHINFO_EXTENSION);
		$extension = $extension && strpos($extension, '?') > -1 ? substr($extension, 0, strpos($extension, '?')) : $extension;
		return $extension ? '.'.$extension : null;
	}

	//// Return size to octet
	private static function __sizeToOctet($size) {
		$formated = 0;
		if(strpos($size, 'k') > 0) {
			$formated = (int) substr($size, 0, -1);
			$formated *= 1024;
		} else if(strpos($size, 'm') > 0) {
			$formated = (int) substr($size, 0, -1);
			$formated *= 1048576;
		} else if(strpos($size, 'g') > 0) {
			$formated = (int) substr($size, 0, -1);
			$formated *= 1073741824;
		} else if(strpos($size, 't') > 0) {
			$formated = (int) substr($size, 0, -1);
			$formated *= 1099511627776;
		} else {
			$formated = $size;
		}
		return (int) $formated;
	}
	
	//// Return absolute path
	private static function __path($path) {
		$basepath = realpath(__DIR__.'/../../..');
		return (strpos($path, $basepath) > -1 ? '' : $basepath).$path;
	}
	
	//// Replace pattern <attribut_name> by value
	private static function __replaceAttributs($string, $datas = null, $clean = false, $delete_empty = false) {
		if($datas) {
			preg_match_all('#[<\[]([a-zA-Z_0-9]*)[>\]]#', $string, $matches);
			if($matches && sizeof($matches) > 1) {
				$datas_to_replace = is_object($datas) ? (array) $datas : $datas;
				foreach($matches[1] as $key => $elt) {
					$string = str_replace('<'.$elt.'>', ($elt === 'primary' ? (isset($datas) && is_object($datas) ? $datas->getID() : '') : ($elt === 'date' ? date('Ymdhis') : (isset($datas_to_replace[$elt]) ? ($clean == true ? self::__clean($datas_to_replace[$elt]) : $datas_to_replace[$elt]) : ($delete_empty == true  ? '' : '<'.$elt.'>')))), $string);
					$string = str_replace('['.$elt.']', ($elt === 'primary' ? (isset($datas) && is_object($datas) ? $datas->getID() : '') : ($elt === 'date' ? date('Ymdhis') : (isset($datas_to_replace[$elt]) ? ($clean == true ? self::__clean($datas_to_replace[$elt]) : $datas_to_replace[$elt]) : ($delete_empty == true  ? '' : '['.$elt.']')))), $string);
				}
			}
		} else {
			preg_match_all('#[<\[]([a-zA-Z_0-9]*)[>\]]#', $string, $matches);
			if($matches && sizeof($matches) > 1) {
				$datas_to_replace = is_object($datas) ? (array) $datas : $datas;
				foreach($matches[1] as $key => $elt) {
					if($elt == 'random') {
						$string = str_replace('<'.$elt.'>', self::__random(), $string);
						$string = str_replace('['.$elt.']', self::__random(), $string);
					} elseif($elt == 'Y' || $elt == 'm' || $elt == 'd' || $elt == 'H' || $elt == 'i') {
						$string = str_replace('<'.$elt.'>', date($elt), $string);
						$string = str_replace('['.$elt.']', date($elt), $string);
					}
				}
			}
		}
		return $string;
	}
	
	//// Return random string for file name
	private static function __random() {
		$chars = array(2, 'y', 9, 'a', 9, 'j', 5, 'i', 7, 'd', 3, 'b', 2, 's', 6, 'm', 8, 'h', 1, 'e', 9, 't', 2, 'r', 4, 'z', 6, 'f', 4, 'p', 7, 'n', 1, 's', 'q', 3, 'd', 2, 'v', 0, 'd', 0, 's', 6, 'i', 7, 'm', 9, 'q', 4, 't', 3, 'q', 2, 'd', 'o', 9, 'd', 'g', 9, 5, 'i', 7, 'v', 3, 2, 6, 's', 8, 1, 'z', 9, 2, 4, 'e', 6, 4, 7, 1, 'v'); 
		return implode('', array_rand($chars, 10));
	}
}