PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Quản lý website thi trắc nghiệm qua mạng PHP/tracnghiem/editors/htmlarea/plugins/ImageManager/Classes/ImageEditor.php

https://gitlab.com/phamngsinh/baitaplon_sinhvien
PHP | 446 lines | 252 code | 67 blank | 127 comment | 53 complexity | 621684544da5e91d9ef3054fb86e974d MD5 | raw file
  1. <?
  2. /**
  3. * Image Editor. Editing tools, crop, rotate, scale and save.
  4. * @author $Author: Wei Zhuo $
  5. * @version $Id: ImageEditor.php 27 2004-04-01 08:31:57Z Wei Zhuo $
  6. * @package ImageManager
  7. */
  8. require_once('Transform.php');
  9. /**
  10. * Handles the basic image editing capbabilities.
  11. * @author $Author: Wei Zhuo $
  12. * @version $Id: ImageEditor.php 27 2004-04-01 08:31:57Z Wei Zhuo $
  13. * @package ImageManager
  14. * @subpackage Editor
  15. */
  16. class ImageEditor
  17. {
  18. /**
  19. * ImageManager instance.
  20. */
  21. var $manager;
  22. /**
  23. * user based on IP address
  24. */
  25. var $_uid;
  26. /**
  27. * tmp file storage time.
  28. */
  29. var $lapse_time =900; //15 mins
  30. var $filesaved = 0;
  31. /**
  32. * Create a new ImageEditor instance. Editing requires a
  33. * tmp file, which is saved in the current directory where the
  34. * image is edited. The tmp file is assigned by md5 hash of the
  35. * user IP address. This hashed is used as an ID for cleaning up
  36. * the tmp files. In addition, any tmp files older than the
  37. * the specified period will be deleted.
  38. * @param ImageManager $manager the image manager, we need this
  39. * for some file and path handling functions.
  40. */
  41. function ImageEditor($manager)
  42. {
  43. $this->manager = $manager;
  44. $this->_uid = md5($_SERVER['REMOTE_ADDR']);
  45. }
  46. /**
  47. * Did we save a file?
  48. * @return int 1 if the file was saved sucessfully,
  49. * 0 no save operation, -1 file save error.
  50. */
  51. function isFileSaved()
  52. {
  53. Return $this->filesaved;
  54. }
  55. /**
  56. * Process the image, if not action, just display the image.
  57. * @return array with image information, empty array if not an image.
  58. * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
  59. * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
  60. */
  61. function processImage()
  62. {
  63. if(isset($_GET['img']))
  64. $relative = rawurldecode($_GET['img']);
  65. else
  66. Return array();
  67. //$relative = '/Series2004NoteFront.jpg';
  68. $imgURL = $this->manager->getFileURL($relative);
  69. $fullpath = $this->manager->getFullPath($relative);
  70. $imgInfo = @getImageSize($fullpath);
  71. if(!is_array($imgInfo))
  72. Return array();
  73. $action = $this->getAction();
  74. if(!is_null($action))
  75. {
  76. $image = $this->processAction($action, $relative, $fullpath);
  77. }
  78. else
  79. {
  80. $image['src'] = $imgURL;
  81. $image['dimensions'] = $imgInfo[3];
  82. $image['file'] = $relative;
  83. $image['fullpath'] = $fullpath;
  84. }
  85. Return $image;
  86. }
  87. /**
  88. * Process the actions, crop, scale(resize), rotate, flip, and save.
  89. * When ever an action is performed, the result is save into a
  90. * temporary image file, see createUnique on the filename specs.
  91. * It does not return the saved file, alway returning the tmp file.
  92. * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save'
  93. * @param string $relative the relative image filename
  94. * @param string $fullpath the fullpath to the image file
  95. * @return array with image information
  96. * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
  97. * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
  98. */
  99. function processAction($action, $relative, $fullpath)
  100. {
  101. $params = '';
  102. if(isset($_GET['params']))
  103. $params = $_GET['params'];
  104. $values = explode(',',$params,4);
  105. $saveFile = $this->getSaveFileName($values[0]);
  106. $img = Image_Transform::factory(IMAGE_CLASS);
  107. $img->load($fullpath);
  108. switch ($action)
  109. {
  110. case 'crop':
  111. $img->crop(intval($values[0]),intval($values[1]),
  112. intval($values[2]),intval($values[3]));
  113. break;
  114. case 'scale':
  115. $img->resize(intval($values[0]),intval($values[1]));
  116. break;
  117. case 'rotate':
  118. $img->rotate(floatval($values[0]));
  119. break;
  120. case 'flip':
  121. if ($values[0] == 'hoz')
  122. $img->flip(true);
  123. else if($values[0] == 'ver')
  124. $img->flip(false);
  125. break;
  126. case 'save':
  127. if(!is_null($saveFile))
  128. {
  129. $quality = intval($values[1]);
  130. if($quality <0) $quality = 85;
  131. $newSaveFile = $this->makeRelative($relative, $saveFile);
  132. $newSaveFile = $this->getUniqueFilename($newSaveFile);
  133. //get unique filename just returns the filename, so
  134. //we need to make the relative path once more.
  135. $newSaveFile = $this->makeRelative($relative, $newSaveFile);
  136. $newSaveFullpath = $this->manager->getFullPath($newSaveFile);
  137. $img->save($newSaveFullpath, $values[0], $quality);
  138. if(is_file($newSaveFullpath))
  139. $this->filesaved = 1;
  140. else
  141. $this->filesaved = -1;
  142. }
  143. break;
  144. }
  145. //create the tmp image file
  146. $filename = $this->createUnique($fullpath);
  147. $newRelative = $this->makeRelative($relative, $filename);
  148. $newFullpath = $this->manager->getFullPath($newRelative);
  149. $newURL = $this->manager->getFileURL($newRelative);
  150. //save the file.
  151. $img->save($newFullpath);
  152. $img->free();
  153. //get the image information
  154. $imgInfo = @getimagesize($newFullpath);
  155. $image['src'] = $newURL;
  156. $image['dimensions'] = $imgInfo[3];
  157. $image['file'] = $newRelative;
  158. $image['fullpath'] = $newFullpath;
  159. Return $image;
  160. }
  161. /**
  162. * Get the file name base on the save name
  163. * and the save type.
  164. * @param string $type image type, 'jpeg', 'png', or 'gif'
  165. * @return string the filename according to save type
  166. */
  167. function getSaveFileName($type)
  168. {
  169. if(!isset($_GET['file']))
  170. Return null;
  171. $filename = Files::escape(rawurldecode($_GET['file']));
  172. $index = strrpos($filename,'.');
  173. $base = substr($filename,0,$index);
  174. $ext = strtolower(substr($filename,$index+1,strlen($filename)));
  175. if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg'))
  176. {
  177. Return $base.'.jpeg';
  178. }
  179. if($type=='png' && $ext != 'png')
  180. Return $base.'.png';
  181. if($type=='gif' && $ext != 'gif')
  182. Return $base.'.gif';
  183. Return $filename;
  184. }
  185. /**
  186. * Get the default save file name, used by editor.php.
  187. * @return string a suggestive filename, this should be unique
  188. */
  189. function getDefaultSaveFile()
  190. {
  191. if(isset($_GET['img']))
  192. $relative = rawurldecode($_GET['img']);
  193. else
  194. Return null;
  195. Return $this->getUniqueFilename($relative);
  196. }
  197. /**
  198. * Get a unique filename. If the file exists, the filename
  199. * base is appended with an increasing integer.
  200. * @param string $relative the relative filename to the base_dir
  201. * @return string a unique filename in the current path
  202. */
  203. function getUniqueFilename($relative)
  204. {
  205. $fullpath = $this->manager->getFullPath($relative);
  206. $pathinfo = pathinfo($fullpath);
  207. $path = Files::fixPath($pathinfo['dirname']);
  208. $file = Files::escape($pathinfo['basename']);
  209. $filename = $file;
  210. $dotIndex = strrpos($file, '.');
  211. $ext = '';
  212. if(is_int($dotIndex))
  213. {
  214. $ext = substr($file, $dotIndex);
  215. $base = substr($file, 0, $dotIndex);
  216. }
  217. $counter = 0;
  218. while(is_file($path.$filename))
  219. {
  220. $counter++;
  221. $filename = $base.'_'.$counter.$ext;
  222. }
  223. Return $filename;
  224. }
  225. /**
  226. * Specifiy the original relative path, a new filename
  227. * and return the new filename with relative path.
  228. * i.e. $pathA (-filename) + $file
  229. * @param string $pathA the relative file
  230. * @param string $file the new filename
  231. * @return string relative path with the new filename
  232. */
  233. function makeRelative($pathA, $file)
  234. {
  235. $index = strrpos($pathA,'/');
  236. if(!is_int($index))
  237. Return $file;
  238. $path = substr($pathA, 0, $index);
  239. Return Files::fixPath($path).$file;
  240. }
  241. /**
  242. * Get the action GET parameter
  243. * @return string action parameter
  244. */
  245. function getAction()
  246. {
  247. $action = null;
  248. if(isset($_GET['action']))
  249. $action = $_GET['action'];
  250. Return $action;
  251. }
  252. /**
  253. * Generate a unique string based on md5(microtime()).
  254. * Well not so uniqe, as it is limited to 6 characters
  255. * @return string unique string.
  256. */
  257. function uniqueStr()
  258. {
  259. return substr(md5(microtime()),0,6);
  260. }
  261. /**
  262. * Create unique tmp image file name.
  263. * The filename is based on the tmp file prefix
  264. * specified in config.inc.php plus
  265. * the UID (basically a md5 of the remote IP)
  266. * and some random 6 character string.
  267. * This function also calls to clean up the tmp files.
  268. * @param string $file the fullpath to a file
  269. * @return string a unique filename for that path
  270. * NOTE: it only returns the filename, path no included.
  271. */
  272. function createUnique($file)
  273. {
  274. $pathinfo = pathinfo($file);
  275. $path = Files::fixPath($pathinfo['dirname']);
  276. $imgType = $this->getImageType($file);
  277. $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
  278. //make sure the the unique temp file does not exists
  279. while (file_exists($path.$unique_str))
  280. {
  281. $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
  282. }
  283. $this->cleanUp($path,$pathinfo['basename']);
  284. Return $unique_str;
  285. }
  286. /**
  287. * Delete any tmp image files.
  288. * @param string $path the full path
  289. * where the clean should take place.
  290. */
  291. function cleanUp($path,$file)
  292. {
  293. $path = Files::fixPath($path);
  294. if(!is_dir($path))
  295. Return false;
  296. $d = @dir($path);
  297. $tmp = $this->manager->getTmpPrefix();
  298. $tmpLen = strlen($tmp);
  299. $prefix = $tmp.$this->_uid;
  300. $len = strlen($prefix);
  301. while (false !== ($entry = $d->read()))
  302. {
  303. //echo $entry."<br>";
  304. if(is_file($path.$entry) && $this->manager->isTmpFile($entry))
  305. {
  306. if(substr($entry,0,$len)==$prefix && $entry != $file)
  307. Files::delFile($path.$entry);
  308. else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file)
  309. {
  310. if(filemtime($path.$entry)+$this->lapse_time < time())
  311. Files::delFile($path.$entry);
  312. }
  313. }
  314. }
  315. $d->close();
  316. }
  317. /**
  318. * Get the image type base on an image file.
  319. * @param string $file the full path to the image file.
  320. * @return string of either 'gif', 'jpeg', 'png' or 'bmp'
  321. * otherwise it will return null.
  322. */
  323. function getImageType($file)
  324. {
  325. $imageInfo = @getImageSize($file);
  326. if(!is_array($imageInfo))
  327. Return null;
  328. switch($imageInfo[2])
  329. {
  330. case 1:
  331. Return 'gif';
  332. case 2:
  333. Return 'jpeg';
  334. case 3:
  335. Return 'png';
  336. case 6:
  337. Return 'bmp';
  338. }
  339. Return null;
  340. }
  341. /**
  342. * Check if the specified image can be edit by GD
  343. * mainly to check that GD can read and save GIFs
  344. * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable.
  345. */
  346. function isGDEditable()
  347. {
  348. if(isset($_GET['img']))
  349. $relative = rawurldecode($_GET['img']);
  350. else
  351. Return 0;
  352. if(IMAGE_CLASS != 'GD')
  353. Return 0;
  354. $fullpath = $this->manager->getFullPath($relative);
  355. $type = $this->getImageType($fullpath);
  356. if($type != 'gif')
  357. Return 0;
  358. if(function_exists('ImageCreateFrom'+$type)
  359. && function_exists('image'+$type))
  360. Return 1;
  361. else
  362. Return -1;
  363. }
  364. /**
  365. * Check if GIF can be edit by GD.
  366. * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable.
  367. */
  368. function isGDGIFAble()
  369. {
  370. if(IMAGE_CLASS != 'GD')
  371. Return 0;
  372. if(function_exists('ImageCreateFromGif')
  373. && function_exists('imagegif'))
  374. Return 1;
  375. else
  376. Return -1;
  377. }
  378. }
  379. ?>