Completed
Push — master ( ed35ab...871ad1 )
by Michael
05:54
created

io.php ➔ GetCurrentFolder()   D

Complexity

Conditions 9
Paths 128

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 15
nc 128
nop 0
dl 0
loc 27
rs 4.6666
c 0
b 0
f 0
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
 *    http://www.gnu.org/licenses/gpl.html
13
 *
14
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
15
 *    http://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
function CombinePaths( $sBasePath, $sFolder )
25
{
26
	return RemoveFromEnd( $sBasePath, '/' ) . '/' . RemoveFromStart( $sFolder, '/' ) ;
27
}
28
function GetResourceTypePath( $resourceType, $sCommand )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
29
{
30
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
31
32
	if ( $sCommand == "QuickUpload")
33
		return $Config['QuickUploadPath'][$resourceType] ;
34
	else
35
		return $Config['FileTypesPath'][$resourceType] ;
36
}
37
38
function GetResourceTypeDirectory( $resourceType, $sCommand )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
39
{
40
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
41
	if ( $sCommand == "QuickUpload")
42
	{
43
		if ( strlen( $Config['QuickUploadAbsolutePath'][$resourceType] ) > 0 )
44
			return $Config['QuickUploadAbsolutePath'][$resourceType] ;
45
46
		// Map the "UserFiles" path to a local directory.
47
		return Server_MapPath( $Config['QuickUploadPath'][$resourceType] ) ;
48
	}
49
	else
50
	{
51
		if ( strlen( $Config['FileTypesAbsolutePath'][$resourceType] ) > 0 )
52
			return $Config['FileTypesAbsolutePath'][$resourceType] ;
53
54
		// Map the "UserFiles" path to a local directory.
55
		return Server_MapPath( $Config['FileTypesPath'][$resourceType] ) ;
56
	}
57
}
58
59
function GetUrlFromPath( $resourceType, $folderPath, $sCommand )
60
{
61
	return CombinePaths( GetResourceTypePath( $resourceType, $sCommand ), $folderPath ) ;
62
}
63
64
function RemoveExtension( $fileName )
65
{
66
	return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
67
}
68
69
function ServerMapFolder( $resourceType, $folderPath, $sCommand )
70
{
71
	// Get the resource type directory.
72
	$sResourceTypePath = GetResourceTypeDirectory( $resourceType, $sCommand ) ;
73
74
	// Ensure that the directory exists.
75
	$sErrorMsg = CreateServerFolder( $sResourceTypePath ) ;
76
	if ( $sErrorMsg != '' )
77
		SendError( 1, "Error creating folder \"{$sResourceTypePath}\" ({$sErrorMsg})" ) ;
78
79
	// Return the resource type directory combined with the required path.
80
	return CombinePaths( $sResourceTypePath , $folderPath ) ;
81
}
82
83
function GetParentFolder( $folderPath )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
84
{
85
	$sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-" ;
86
	return preg_replace( $sPattern, '', $folderPath ) ;
87
}
88
89
function CreateServerFolder( $folderPath, $lastFolder = null )
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
90
{
91
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
92
	$sParent = GetParentFolder( $folderPath ) ;
93
94
	// Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
95
	while ( strpos($folderPath, '//') !== false )
96
	{
97
		$folderPath = str_replace( '//', '/', $folderPath ) ;
98
	}
99
100
	// Check if the parent exists, or create it.
101
	if ( !empty($sParent) && !file_exists( $sParent ) )
102
	{
103
		//prevents agains infinite loop when we can't create root folder
104
		if ( !is_null( $lastFolder ) && $lastFolder === $sParent) {
105
			return "Can't create $folderPath directory" ;
106
		}
107
108
		$sErrorMsg = CreateServerFolder( $sParent, $folderPath ) ;
109
		if ( $sErrorMsg != '' )
110
			return $sErrorMsg ;
111
	}
112
113
	if ( !file_exists( $folderPath ) )
114
	{
115
		// Turn off all error reporting.
116
		error_reporting( 0 ) ;
117
118
		$php_errormsg = '' ;
119
		// Enable error tracking to catch the error.
120
		ini_set( 'track_errors', '1' ) ;
121
122
		if ( isset( $Config['ChmodOnFolderCreate'] ) && !$Config['ChmodOnFolderCreate'] )
123
		{
124
			mkdir( $folderPath ) ;
125
		}
126
		else
127
		{
128
			$permissions = 0777 ;
129
			if ( isset( $Config['ChmodOnFolderCreate'] ) )
130
			{
131
				$permissions = $Config['ChmodOnFolderCreate'] ;
132
			}
133
			// To create the folder with 0777 permissions, we need to set umask to zero.
134
			$oldumask = umask(0) ;
135
			mkdir( $folderPath, $permissions ) ;
136
			umask( $oldumask ) ;
137
		}
138
139
		$sErrorMsg = $php_errormsg ;
140
141
		// Restore the configurations.
142
		ini_restore( 'track_errors' ) ;
143
		ini_restore( 'error_reporting' ) ;
144
145
		return $sErrorMsg ;
146
	}
147
	else
148
		return '' ;
149
}
150
151
function GetRootPath()
0 ignored issues
show
Coding Style introduced by
GetRootPath uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
152
{
153
	if (!isset($_SERVER)) {
154
		global $_SERVER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
155
	}
156
	$sRealPath = realpath( './' ) ;
157
	// #2124 ensure that no slash is at the end
158
	$sRealPath = rtrim($sRealPath,"\\/");
159
160
	$sSelfPath = $_SERVER['PHP_SELF'] ;
161
	$sSelfPath = substr( $sSelfPath, 0, strrpos( $sSelfPath, '/' ) ) ;
162
163
	$sSelfPath = str_replace( '/', DIRECTORY_SEPARATOR, $sSelfPath ) ;
164
165
	$position = strpos( $sRealPath, $sSelfPath ) ;
166
167
	// This can check only that this script isn't run from a virtual dir
168
	// But it avoids the problems that arise if it isn't checked
169
	if ( $position === false || $position <> strlen( $sRealPath ) - strlen( $sSelfPath ) )
170
		SendError( 1, 'Sorry, can\'t map "UserFilesPath" to a physical path. You must set the "UserFilesAbsolutePath" value in "editor/filemanager/connectors/php/config.php".' ) ;
171
172
	return substr( $sRealPath, 0, $position ) ;
173
}
174
175
// Emulate the asp Server.mapPath function.
176
// given an url path return the physical directory that it corresponds to
177
function Server_MapPath( $path )
178
{
179
	// This function is available only for Apache
180
	if ( function_exists( 'apache_lookup_uri' ) )
181
	{
182
		$info = apache_lookup_uri( $path ) ;
183
		return $info->filename . $info->path_info ;
184
	}
185
186
	// This isn't correct but for the moment there's no other solution
187
	// If this script is under a virtual directory or symlink it will detect the problem and stop
188
	return GetRootPath() . $path ;
189
}
190
191
function IsAllowedExt( $sExtension, $resourceType )
192
{
193
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
194
	// Get the allowed and denied extensions arrays.
195
	$arAllowed	= $Config['AllowedExtensions'][$resourceType] ;
196
	$arDenied	= $Config['DeniedExtensions'][$resourceType] ;
197
198
	if ( count($arAllowed) > 0 && !in_array( $sExtension, $arAllowed ) )
199
		return false ;
200
201
	if ( count($arDenied) > 0 && in_array( $sExtension, $arDenied ) )
202
		return false ;
203
204
	return true ;
205
}
206
207
function IsAllowedType( $resourceType )
208
{
209
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
210
	if ( !in_array( $resourceType, $Config['ConfigAllowedTypes'] ) )
211
		return false ;
212
213
	return true ;
214
}
215
216
function IsAllowedCommand( $sCommand )
217
{
218
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
219
220
	if ( !in_array( $sCommand, $Config['ConfigAllowedCommands'] ) )
221
		return false ;
222
223
	return true ;
224
}
225
226
function GetCurrentFolder()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Coding Style introduced by
GetCurrentFolder uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
227
{
228
	if (!isset($_GET)) {
229
		global $_GET;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
230
	}
231
	$sCurrentFolder	= isset( $_GET['CurrentFolder'] ) ? $_GET['CurrentFolder'] : '/' ;
232
233
	// Check the current folder syntax (must begin and start with a slash).
234
	if ( !preg_match( '|/$|', $sCurrentFolder ) )
235
		$sCurrentFolder .= '/' ;
236
	if ( strpos( $sCurrentFolder, '/' ) !== 0 )
237
		$sCurrentFolder = '/' . $sCurrentFolder ;
238
239
	// Ensure the folder path has no double-slashes
240
	while ( strpos ($sCurrentFolder, '//') !== false ) {
241
		$sCurrentFolder = str_replace ('//', '/', $sCurrentFolder) ;
242
	}
243
244
	// Check for invalid folder paths (..)
245
	if ( strpos( $sCurrentFolder, '..' ) || strpos( $sCurrentFolder, "\\" ))
246
		SendError( 102, '' ) ;
247
248
	if ( preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"\<\>\|]),", $sCurrentFolder))
249
		SendError( 102, '' ) ;
250
251
	return $sCurrentFolder ;
252
}
253
254
// Do a cleanup of the folder name to avoid possible problems
255
function SanitizeFolderName( $sNewFolderName )
256
{
257
	$sNewFolderName = stripslashes( $sNewFolderName ) ;
258
259
	// Remove . \ / | : ? * " < >
260
	$sNewFolderName = preg_replace( '/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName ) ;
261
262
	return $sNewFolderName ;
263
}
264
265
// Do a cleanup of the file name to avoid possible problems
266
function SanitizeFileName( $sNewFileName )
267
{
268
	global $Config ;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
269
270
	$sNewFileName = stripslashes( $sNewFileName ) ;
271
272
	// Replace dots in the name with underscores (only one dot can be there... security issue).
273
	if ( $Config['ForceSingleExtension'] )
274
		$sNewFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sNewFileName ) ;
275
276
	// Remove \ / | : ? * " < >
277
	$sNewFileName = preg_replace( '/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName ) ;
278
279
	return $sNewFileName ;
280
}
281
282
// This is the function that sends the results of the uploading process.
283
function SendUploadResults( $errorNumber, $fileUrl = '', $fileName = '', $customMsg = '' )
284
{
285
	// Minified version of the document.domain automatic fix script (#1919).
286
	// The original script can be found at _dev/domain_fix_template.js
287
	echo <<<EOF
288
<script type="text/javascript">
289
(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;}}})();
290
EOF;
291
292
	if ($errorNumber && $errorNumber != 201) {
293
		$fileUrl = "";
294
		$fileName = "";
295
	}
296
297
	$rpl = array( '\\' => '\\\\', '"' => '\\"' ) ;
298
	echo 'window.parent.OnUploadCompleted(' . $errorNumber . ',"' . strtr( $fileUrl, $rpl ) . '","' . strtr( $fileName, $rpl ) . '", "' . strtr( $customMsg, $rpl ) . '") ;' ;
299
	echo '</script>' ;
300
	exit ;
0 ignored issues
show
Coding Style Compatibility introduced by
The function SendUploadResults() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
301
}
302
303
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
304