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