io.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. /*
  3. * FCKeditor - The text editor for Internet - http://www.fckeditor.net
  4. * Copyright (C) 2003-2010 Frederico Caldeira Knabben
  5. *
  6. * == BEGIN LICENSE ==
  7. *
  8. * Licensed under the terms of any of the following licenses at your
  9. * choice:
  10. *
  11. * - GNU General Public License Version 2 or later (the "GPL")
  12. * https://www.gnu.org/licenses/gpl.html
  13. *
  14. * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
  15. * https://www.gnu.org/licenses/lgpl.html
  16. *
  17. * - Mozilla Public License Version 1.1 or later (the "MPL")
  18. * http://www.mozilla.org/MPL/MPL-1.1.html
  19. *
  20. * == END LICENSE ==
  21. *
  22. * This is the File Manager Connector for PHP.
  23. */
  24. /**
  25. * CombinePaths
  26. *
  27. * @param string $sBasePath sBasePath
  28. * @param string $sFolder sFolder
  29. * @return string Combined path
  30. */
  31. function CombinePaths($sBasePath, $sFolder)
  32. {
  33. return RemoveFromEnd($sBasePath, '/').'/'.RemoveFromStart($sFolder, '/');
  34. }
  35. /**
  36. * GetResourceTypePath
  37. *
  38. * @param string $resourceType Resource type
  39. * @param string $sCommand Command
  40. * @return string Config
  41. */
  42. function GetResourceTypePath($resourceType, $sCommand)
  43. {
  44. global $Config;
  45. if ($sCommand == "QuickUpload") {
  46. return $Config['QuickUploadPath'][$resourceType];
  47. } else {
  48. return $Config['FileTypesPath'][$resourceType];
  49. }
  50. }
  51. /**
  52. * GetResourceTypeDirectory
  53. *
  54. * @param string $resourceType Resource type
  55. * @param string $sCommand Command
  56. * @return string
  57. */
  58. function GetResourceTypeDirectory($resourceType, $sCommand)
  59. {
  60. global $Config;
  61. if ($sCommand == "QuickUpload") {
  62. if (strlen($Config['QuickUploadAbsolutePath'][$resourceType]) > 0) {
  63. return $Config['QuickUploadAbsolutePath'][$resourceType];
  64. }
  65. // Map the "UserFiles" path to a local directory.
  66. return Server_MapPath($Config['QuickUploadPath'][$resourceType]);
  67. } else {
  68. if (strlen($Config['FileTypesAbsolutePath'][$resourceType]) > 0) {
  69. return $Config['FileTypesAbsolutePath'][$resourceType];
  70. }
  71. // Map the "UserFiles" path to a local directory.
  72. return Server_MapPath($Config['FileTypesPath'][$resourceType]);
  73. }
  74. }
  75. /**
  76. * GetUrlFromPath
  77. *
  78. * @param string $resourceType Resource type
  79. * @param string $folderPath Path
  80. * @param string $sCommand Command
  81. * @return string Full url
  82. */
  83. function GetUrlFromPath($resourceType, $folderPath, $sCommand)
  84. {
  85. return CombinePaths(GetResourceTypePath($resourceType, $sCommand), $folderPath);
  86. }
  87. /**
  88. * RemoveExtension
  89. *
  90. * @param string $fileName Filename
  91. * @return string String without extension
  92. */
  93. function RemoveExtension($fileName)
  94. {
  95. return substr($fileName, 0, strrpos($fileName, '.'));
  96. }
  97. /**
  98. * ServerMapFolder
  99. *
  100. * @param string $resourceType Resource type
  101. * @param string $folderPath Folder
  102. * @param string $sCommand Command
  103. * @return string
  104. */
  105. function ServerMapFolder($resourceType, $folderPath, $sCommand)
  106. {
  107. // Get the resource type directory.
  108. $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand);
  109. // Ensure that the directory exists.
  110. $sErrorMsg = CreateServerFolder($sResourceTypePath);
  111. if ($sErrorMsg != '') {
  112. SendError(1, "Error creating folder \"{$sResourceTypePath}\" ({$sErrorMsg})");
  113. }
  114. // Return the resource type directory combined with the required path.
  115. return CombinePaths($sResourceTypePath, $folderPath);
  116. }
  117. /**
  118. * GetParentFolder
  119. *
  120. * @param string $folderPath Folder path
  121. * @return string Parent folder
  122. */
  123. function GetParentFolder($folderPath)
  124. {
  125. $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-";
  126. return preg_replace($sPattern, '', $folderPath);
  127. }
  128. /**
  129. * CreateServerFolder
  130. *
  131. * @param string $folderPath Folder
  132. * @param string $lastFolder Folder
  133. * @return string ''=success, error message otherwise
  134. */
  135. function CreateServerFolder($folderPath, $lastFolder = null)
  136. {
  137. global $Config;
  138. $sParent = GetParentFolder($folderPath);
  139. // Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
  140. while (strpos($folderPath, '//') !== false) {
  141. $folderPath = str_replace('//', '/', $folderPath);
  142. }
  143. // Check if the parent exists, or create it.
  144. if (!empty($sParent) && !file_exists($sParent)) {
  145. //prevents agains infinite loop when we can't create root folder
  146. if (!is_null($lastFolder) && $lastFolder === $sParent) {
  147. return "Can't create $folderPath directory";
  148. }
  149. $sErrorMsg = CreateServerFolder($sParent, $folderPath);
  150. if ($sErrorMsg != '') {
  151. return $sErrorMsg;
  152. }
  153. }
  154. if (!file_exists($folderPath)) {
  155. // Turn off all error reporting.
  156. error_reporting(0);
  157. $php_errormsg = '';
  158. // Enable error tracking to catch the error.
  159. ini_set('track_errors', '1');
  160. if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) {
  161. mkdir($folderPath);
  162. } else {
  163. $permissions = '0777';
  164. if (isset($Config['ChmodOnFolderCreate']) && $Config['ChmodOnFolderCreate']) {
  165. $permissions = (string) $Config['ChmodOnFolderCreate'];
  166. }
  167. $permissionsdec = octdec($permissions);
  168. $permissionsdec |= octdec('0111'); // Set x bit required for directories
  169. dol_syslog("io.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
  170. // To create the folder with 0777 permissions, we need to set umask to zero.
  171. $oldumask = umask(0);
  172. mkdir($folderPath, $permissionsdec);
  173. umask($oldumask);
  174. }
  175. $sErrorMsg = $php_errormsg;
  176. // Restore the configurations.
  177. ini_restore('track_errors');
  178. ini_restore('error_reporting');
  179. return $sErrorMsg;
  180. } else {
  181. return '';
  182. }
  183. }
  184. /**
  185. * Get Root Path
  186. *
  187. * @return string real path
  188. */
  189. function GetRootPath()
  190. {
  191. if (!isset($_SERVER)) {
  192. global $_SERVER;
  193. }
  194. $sRealPath = realpath('./');
  195. // #2124 ensure that no slash is at the end
  196. $sRealPath = rtrim($sRealPath, "\\/");
  197. $sSelfPath = $_SERVER['PHP_SELF'];
  198. $sSelfPath = substr($sSelfPath, 0, strrpos($sSelfPath, '/'));
  199. $sSelfPath = str_replace('/', DIRECTORY_SEPARATOR, $sSelfPath);
  200. $position = strpos($sRealPath, $sSelfPath);
  201. // This can check only that this script isn't run from a virtual dir
  202. // But it avoids the problems that arise if it isn't checked
  203. if ($position === false || $position <> strlen($sRealPath) - strlen($sSelfPath)) {
  204. SendError(1, 'Sorry, can\'t map "UserFilesPath" to a physical path. You must set the "UserFilesAbsolutePath" value in "editor/filemanager/connectors/php/config.php".');
  205. }
  206. return substr($sRealPath, 0, $position);
  207. }
  208. /**
  209. * Emulate the asp Server.mapPath function.
  210. * @param string $path given an url path return the physical directory that it corresponds to
  211. * @return string Path
  212. */
  213. function Server_MapPath($path)
  214. {
  215. // This function is available only for Apache
  216. if (function_exists('apache_lookup_uri')) {
  217. $info = apache_lookup_uri($path);
  218. return $info->filename.$info->path_info;
  219. }
  220. // This isn't correct but for the moment there's no other solution
  221. // If this script is under a virtual directory or symlink it will detect the problem and stop
  222. return GetRootPath().$path;
  223. }
  224. /**
  225. * Is Allowed Extension
  226. *
  227. * @param string $sExtension File extension
  228. * @param string $resourceType ressource type
  229. * @return boolean true or false
  230. */
  231. function IsAllowedExt($sExtension, $resourceType)
  232. {
  233. global $Config;
  234. // Get the allowed and denied extensions arrays.
  235. $arAllowed = $Config['AllowedExtensions'][$resourceType];
  236. $arDenied = $Config['DeniedExtensions'][$resourceType];
  237. if (count($arAllowed) > 0 && !in_array($sExtension, $arAllowed)) {
  238. return false;
  239. }
  240. if (count($arDenied) > 0 && in_array($sExtension, $arDenied)) {
  241. return false;
  242. }
  243. return true;
  244. }
  245. /**
  246. * Is Allowed Type
  247. *
  248. * @param string $resourceType ressource type
  249. * @return boolean true or false
  250. */
  251. function IsAllowedType($resourceType)
  252. {
  253. global $Config;
  254. if (!in_array($resourceType, $Config['ConfigAllowedTypes'])) {
  255. return false;
  256. }
  257. return true;
  258. }
  259. /**
  260. * IsAllowedCommand
  261. *
  262. * @param string $sCommand Command
  263. * @return boolean True or false
  264. */
  265. function IsAllowedCommand($sCommand)
  266. {
  267. global $Config;
  268. if (!in_array($sCommand, $Config['ConfigAllowedCommands'])) {
  269. return false;
  270. }
  271. return true;
  272. }
  273. /**
  274. * GetCurrentFolder
  275. *
  276. * @return string current folder
  277. */
  278. function GetCurrentFolder()
  279. {
  280. if (!isset($_GET)) {
  281. global $_GET;
  282. }
  283. $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', '', 1) : '/';
  284. // Check the current folder syntax (must begin and start with a slash).
  285. if (!preg_match('|/$|', $sCurrentFolder)) {
  286. $sCurrentFolder .= '/';
  287. }
  288. if (strpos($sCurrentFolder, '/') !== 0) {
  289. $sCurrentFolder = '/'.$sCurrentFolder;
  290. }
  291. // Ensure the folder path has no double-slashes
  292. while (strpos($sCurrentFolder, '//') !== false) {
  293. $sCurrentFolder = str_replace('//', '/', $sCurrentFolder);
  294. }
  295. // Check for invalid folder paths (..)
  296. if (strpos($sCurrentFolder, '..') || strpos($sCurrentFolder, "\\")) {
  297. SendError(102, '');
  298. }
  299. if (preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"\<\>\|]),", $sCurrentFolder)) {
  300. SendError(102, '');
  301. }
  302. return $sCurrentFolder;
  303. }
  304. /**
  305. * Do a cleanup of the folder name to avoid possible problems
  306. *
  307. * @param string $sNewFolderName Folder
  308. * @return string Folder sanitized
  309. */
  310. function SanitizeFolderName($sNewFolderName)
  311. {
  312. $sNewFolderName = stripslashes($sNewFolderName);
  313. // Remove . \ / | : ? * " < >
  314. $sNewFolderName = preg_replace('/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName);
  315. return $sNewFolderName;
  316. }
  317. /**
  318. * Do a cleanup of the file name to avoid possible problems
  319. *
  320. * @param string $sNewFileName Folder
  321. * @return string Folder sanitized
  322. */
  323. function SanitizeFileName($sNewFileName)
  324. {
  325. global $Config;
  326. $sNewFileName = stripslashes($sNewFileName);
  327. // Replace dots in the name with underscores (only one dot can be there... security issue).
  328. if ($Config['ForceSingleExtension']) {
  329. $sNewFileName = preg_replace('/\\.(?![^.]*$)/', '_', $sNewFileName);
  330. }
  331. // Remove \ / | : ? * " < >
  332. $sNewFileName = preg_replace('/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName);
  333. return $sNewFileName;
  334. }
  335. /**
  336. * This is the function that sends the results of the uploading process.
  337. *
  338. * @param string $errorNumber errorNumber
  339. * @param string $fileUrl fileUrl
  340. * @param string $fileName fileName
  341. * @param string $customMsg customMsg
  342. * @return void
  343. */
  344. function SendUploadResults($errorNumber, $fileUrl = '', $fileName = '', $customMsg = '')
  345. {
  346. // Minified version of the document.domain automatic fix script (#1919).
  347. // The original script can be found at _dev/domain_fix_template.js
  348. echo <<<EOF
  349. <script type="text/javascript">
  350. (function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();
  351. EOF;
  352. if ($errorNumber && $errorNumber != 201) {
  353. $fileUrl = "";
  354. $fileName = "";
  355. }
  356. $rpl = array('\\' => '\\\\', '"' => '\\"');
  357. echo 'console.log('.$errorNumber.');';
  358. echo 'window.parent.OnUploadCompleted('.$errorNumber.', "'.strtr($fileUrl, $rpl).'", "'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");';
  359. echo '</script>';
  360. exit;
  361. }
  362. // @CHANGE
  363. // This is the function that sends the results of the uploading process to CKE.
  364. /**
  365. * SendCKEditorResults
  366. *
  367. * @param string $callback callback
  368. * @param string $sFileUrl sFileUrl
  369. * @param string $customMsg customMsg
  370. * @return void
  371. */
  372. function SendCKEditorResults($callback, $sFileUrl, $customMsg = '')
  373. {
  374. echo '<script type="text/javascript">';
  375. $rpl = array('\\' => '\\\\', '"' => '\\"');
  376. echo 'window.parent.CKEDITOR.tools.callFunction("'.$callback.'","'.strtr($sFileUrl, $rpl).'", "'.strtr($customMsg, $rpl).'");';
  377. echo '</script>';
  378. }