-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathUtilityHandler.php
145 lines (127 loc) · 4.79 KB
/
UtilityHandler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
/**
* Created by JetBrains PhpStorm.
* User: iluvatar
* Date: 31/7/13
* Time: 10:47 AM
* To change this template use File | Settings | File Templates.
*/
namespace Codebender\CompilerBundle\Handler;
class UtilityHandler
{
/**
* \brief Extracts the files included in a compile request.
*
* \param string $directory The directory to extract the files to.
* \param array $request_files The files structure, as taken from the JSON request.
* \return A list of files or a reply message in case of error.
*
* Takes the files structure from a compile request and creates each file in a
* specified directory. If requested, it may create additional directories and
* have the files placed inside them accordingly.
*
* Also creates a new structure where each key is the file extension and the
* associated value is an array containing the absolute paths of the file, minus
* the extension.
*
* In case of error, the return value is an array that has a key <b>success</b>
* and contains the response to be sent back to the user.
*/
function extractFiles($directory, $request_files, $lib_extraction)
{
// File extensions used by Arduino projects. They are put in a string,
// separated by "|" to be used in regular expressions. They are also
// used as keys in an array that will contain the paths of all the
// extracted files.
$allowedExtensions = array("c", "cpp", "h", "inc", "ino", "o", "S", "hpp");
$files = array();
foreach ($allowedExtensions as $ext)
$files[$ext] = array();
$allowedExtensions = implode("|", $allowedExtensions);
// Matches filename that end with an appropriate extension. The name
// without the extension is stored in registerd 1, the extension itself
// in register 2.
//
// Examples: foo.c bar.cpp
$extensionsRegex = "/(.*)\.($allowedExtensions)$/";
if (!file_exists($directory))
mkdir($directory, 0777, true);
foreach ($request_files as $file)
{
$filename = $file["filename"];
$content = $file["content"];
$ignore = false;
$failureResponse = array(
"success" => false,
"step" => 1,
"message" => "Failed to extract file '$filename'.");
// Filenames may not use the special directory "..". This is a
// serious security risk.
$directories = explode("/", "$directory/$filename");
if (in_array("..", $directories))
return $failureResponse;
if (strpos($filename, DIRECTORY_SEPARATOR))
{
$new_directory = pathinfo($filename, PATHINFO_DIRNAME);
if (($lib_extraction === true) && ($new_directory !== "utility"))
$ignore = true;
if (!file_exists("$directory/$new_directory"))
mkdir("$directory/$new_directory", 0777, true);
// There is no reason to check whether mkdir()
// succeeded, given that the call to
// file_put_contents() that follows would fail
// as well.
}
if (file_put_contents("$directory/$filename", $content) === false)
return $failureResponse;
if ($ignore)
continue;
if (preg_match($extensionsRegex, $filename, $matches))
$files[$matches[2]][] = "$directory/$matches[1]";
else
error_log(__FUNCTION__."(): Unhandled file extension '$filename'");
}
// All files were extracted successfully.
return array("success" => true, "files" => $files);
}
/**
* \brief Searches for files with specific extensions in a directory.
*
* \param string $directory The directory to search for files.
* \param mixed $extensions An array of strings, the extensions to look for.
* \return A list of files that have the appropriate extension.
*/
function get_files_by_extension($directory, $extensions)
{
if (is_string($extensions))
$extensions = array($extensions);
$files = array();
foreach (scandir($directory) as $entry)
if (is_file("$directory/$entry") && in_array(pathinfo("$directory/$entry", PATHINFO_EXTENSION), $extensions))
$files[] = $entry;
return $files;
}
/**
* \brief Executes a command and displays the command itself and its output.
*
* \param string $command The command to be executed.
*
* Simplifies the creation and debugging of pages that rely on multiple external
* programs by "emulating" the execution of the requested command in a terminal
* emulator. Can be useful during early stages of development. Replace with
* <b>exec()</b> afterwards.
*
* To perform the command execution, <b>passthru()</b> is used. The string
* <b>2\>&1</b> is appended to the command to ensure messages sent to standard
* error are not lost.
*
* \warning It is not possible to redirect the standard error output to a file.
*/
function execWithDebugging($command, /** @noinspection PhpUnusedParameterInspection */
&$output, /** @noinspection PhpUnusedParameterInspection */
&$retval)
{
echo "$ $command\n";
passthru("$command 2>&1");
}
}