Fixed bug #7962: Add icon to selected entry (currently icons are only shown in dropdown)
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_exec.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2002-2008 René Fritz (r.fritz@colorcube.de)
6 * All rights reserved
7 *
8 * This script is part of the Typo3 project. The Typo3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24 /**
25 * t3lib_exec finds executables (programs) on Unix and Windows without knowing where they are
26 *
27 * $Id$
28 *
29 * @author René Fritz <r.fritz@colorcube.de>
30 */
31 /**
32 * [CLASS/FUNCTION INDEX of SCRIPT]
33 *
34 *
35 *
36 * 85: class t3lib_exec
37 * 95: function checkCommand($cmd, $handler='')
38 * 166: function getCommand($cmd, $handler='', $handlerOpt='')
39 * 199: function addPaths($paths)
40 * 211: function getPaths($addInvalid=false)
41 * 237: function _init()
42 * 259: function _initPaths($paths='')
43 * 312: function _getConfiguredApps()
44 * 339: function _getPaths()
45 * 400: function _fixPath($path)
46 *
47 * TOTAL FUNCTIONS: 9
48 * (This index is automatically created/updated by the extension "extdeveval")
49 *
50 */
51
52
53
54
55
56 /**
57 * returns exec command for a program
58 * or false
59 *
60 * This class is meant to be used without instance:
61 * $cmd = t3lib_exec::getCommand ('awstats','perl');
62 *
63 * The data of this class is hold in a global variable. Doing it this way the setup is cached.
64 * That means if a program is found once it don't have to be searched again.
65 *
66 * user functions:
67 *
68 * addPaths() could be used to extend the search paths
69 * getCommand() get a command string
70 * checkCommand() returns true if a command is available
71 *
72 * Search paths that are included:
73 * $TYPO3_CONF_VARS['GFX']['im_path_lzw'] or $TYPO3_CONF_VARS['GFX']['im_path']
74 * $TYPO3_CONF_VARS['SYS']['binPath']
75 * $GLOBALS['_SERVER']['PATH']
76 * '/usr/bin/,/usr/local/bin/' on Unix
77 *
78 * binaries can be preconfigured with
79 * $TYPO3_CONF_VARS['SYS']['binSetup']
80 *
81 * @author René Fritz <r.fritz@colorcube.de>
82 * @package TYPO3
83 * @subpackage t3lib
84 */
85 class t3lib_exec {
86
87 /**
88 * Checks if a command is valid or not
89 * updates global vars
90 *
91 * @param string the command that should be executed. eg: "convert"
92 * @param string executer for the command. eg: "perl"
93 * @return boolean false if cmd is not found, or -1 if the handler is not found
94 */
95 function checkCommand($cmd, $handler='') {
96 global $T3_VAR;
97
98 if (!t3lib_exec::_init()) {
99 return false;
100 }
101
102
103 if ($handler && !t3lib_exec::checkCommand($handler)) {
104 return -1;
105 }
106 // already checked and valid
107 if ($T3_VAR['t3lib_exec']['apps'][$cmd]['valid']) {
108 return true;
109 }
110 // is set but was (above) not true
111 if (isset($T3_VAR['t3lib_exec']['apps'][$cmd]['valid'])) {
112 return false;
113 }
114
115 foreach($T3_VAR['t3lib_exec']['paths'] as $path => $validPath) {
116 // ignore invalid (false) paths
117 if ($validPath) {
118 if (TYPO3_OS=='WIN') {
119 if (@is_file($path.$cmd)) {
120 $T3_VAR['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
121 $T3_VAR['t3lib_exec']['apps'][$cmd]['path'] = $path;
122 $T3_VAR['t3lib_exec']['apps'][$cmd]['valid'] = true;
123 return true;
124 }
125 if (@is_file($path.$cmd.'.exe')) {
126 $T3_VAR['t3lib_exec']['apps'][$cmd]['app'] = $cmd.'.exe';
127 $T3_VAR['t3lib_exec']['apps'][$cmd]['path'] = $path;
128 $T3_VAR['t3lib_exec']['apps'][$cmd]['valid'] = true;
129 return true;
130 }
131 } else { // UNIX
132 if (@is_executable($path.$cmd)) {
133 $T3_VAR['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
134 $T3_VAR['t3lib_exec']['apps'][$cmd]['path'] = $path;
135 $T3_VAR['t3lib_exec']['apps'][$cmd]['valid'] = true;
136 return true;
137 }
138 }
139 }
140 }
141
142 // try to get the executable with the command 'which'. It do the same like already done, but maybe on other paths??
143 if (TYPO3_OS!='WIN') {
144 $cmd = @exec ('which '.$cmd);
145
146 if (@is_executable($cmd)) {
147 $T3_VAR['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
148 $T3_VAR['t3lib_exec']['apps'][$cmd]['path'] = dirname($cmd).'/';
149 $T3_VAR['t3lib_exec']['apps'][$cmd]['valid'] = true;
150 return true;
151 }
152 }
153
154 return false;
155 }
156
157
158 /**
159 * Returns a command string for exec(), system()
160 *
161 * @param string the command that should be executed. eg: "convert"
162 * @param string handler (executor) for the command. eg: "perl"
163 * @param string options for the handler, like '-w' for "perl"
164 * @return mixed returns command string, or false if cmd is not found, or -1 if the handler is not found
165 */
166 function getCommand($cmd, $handler='', $handlerOpt='') {
167 global $T3_VAR;
168
169 if (!t3lib_exec::_init()) {
170 return false;
171 }
172
173 // handler
174 if ($handler) {
175 $handler = t3lib_exec::getCommand($handler);
176
177 if (!$handler) {
178 return -1;
179 }
180 $handler .= ' '.$handlerOpt.' ';
181 }
182
183 // command
184 if (!t3lib_exec::checkCommand($cmd)) {
185 return false;
186 }
187 $cmd = $T3_VAR['t3lib_exec']['apps'][$cmd]['path'].$T3_VAR['t3lib_exec']['apps'][$cmd]['app'].' ';
188
189 return trim($handler.$cmd);
190 }
191
192
193 /**
194 * Extend the preset paths. This way an extension can install an executable and provide the path to t3lib_exec.
195 *
196 * @param string comma seperated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
197 * @return void
198 */
199 function addPaths($paths) {
200 t3lib_exec::_initPaths($paths);
201 }
202
203
204
205 /**
206 * Returns an array of search paths
207 *
208 * @param boolean If set the array contains invalid path too. Then the key is the path and the value is empty
209 * @return array Array of search paths (empty if exec is disabled)
210 */
211 function getPaths($addInvalid=false) {
212 global $T3_VAR;
213
214 if (!t3lib_exec::_init()) {
215 return array();
216 }
217
218 $paths = $T3_VAR['t3lib_exec']['paths'];
219 if(!$addInvalid) {
220
221 foreach($paths as $path => $validPath) {
222 if(!$validPath) {
223 unset($paths);
224 }
225 }
226 }
227 return $paths;
228 }
229
230
231 /**
232 * Initialization, internal
233 *
234 * @return void
235 * @internal
236 */
237 function _init() {
238 global $T3_VAR, $TYPO3_CONF_VARS;
239
240 if ($TYPO3_CONF_VARS['BE']['disable_exec_function']) {
241 return false;
242 }
243 if (!$T3_VAR['t3lib_exec']['init']) {
244 t3lib_exec::_initPaths();
245 $T3_VAR['t3lib_exec']['apps'] = t3lib_exec::_getConfiguredApps();;
246 $T3_VAR['t3lib_exec']['init'] = true;
247 }
248 return true;
249 }
250
251
252 /**
253 * Init and extend the preset paths with own
254 *
255 * @param string Comma seperated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
256 * @return void
257 * @internal
258 */
259 function _initPaths($paths='') {
260 global $T3_VAR;
261
262 $doCeck=false;
263
264 // init global paths array if not already done
265 if (!is_array($T3_VAR['t3lib_exec']['paths'])) {
266 $T3_VAR['t3lib_exec']['paths'] = t3lib_exec::_getPaths();
267 $doCeck=true;
268 }
269 // merge the submitted paths array to the global
270 if ($paths) {
271 $paths = t3lib_div::trimExplode(',',$paths,1);
272 if (is_array($paths)) {
273 foreach($paths as $path) {
274 // make absolute path of relative
275 if (!preg_match('#^/#',$path)) {
276 $path = PATH_site.$path;
277 }
278 if (!isset($T3_VAR['t3lib_exec']['paths'][$path])) {
279 if (@is_dir($path)) {
280 $T3_VAR['t3lib_exec']['paths'][$path] = $path;
281 $T3_VAR['t3lib_exec']['allPaths'].=','.$path;
282 // $doCeck=true; just done
283 } else {
284 $T3_VAR['t3lib_exec']['paths'][$path] = false;
285 }
286 }
287 }
288 }
289 }
290 // check if new paths are invalid
291 if ($doCeck) {
292 $T3_VAR['t3lib_exec']['allPaths']='';
293 foreach($T3_VAR['t3lib_exec']['paths'] as $path => $valid) {
294 // ignore invalid (false) paths
295 if ($valid AND !@is_dir($path)) {
296 $T3_VAR['t3lib_exec']['paths'][$path] = false;
297 }
298 if ($path = $T3_VAR['t3lib_exec']['paths'][$path]) {
299 $T3_VAR['t3lib_exec']['allPaths'].=','.$path;
300 }
301 }
302 }
303 }
304
305
306 /**
307 * Processes and returns the paths from $TYPO3_CONF_VARS['SYS']['binSetup']
308 *
309 * @return array Array of commands and path
310 * @internal
311 */
312 function _getConfiguredApps() {
313 global $TYPO3_CONF_VARS;
314
315 $cmdArr = array();
316
317 if ($TYPO3_CONF_VARS['SYS']['binSetup']) {
318 $pathSetup = implode("\n", t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['SYS']['binSetup'],1));
319 $pathSetup = t3lib_div::trimExplode("\n",$pathSetup,1);
320 foreach($pathSetup as $val) {
321 list($cmd, $cmdPath) = t3lib_div::trimExplode('=',$val,1);
322
323 $cmdArr[$cmd]['app'] = basename($cmdPath);
324 $cmdArr[$cmd]['path'] = dirname($cmdPath).'/';
325 $cmdArr[$cmd]['valid'] = true;
326 }
327 }
328
329 return $cmdArr;
330 }
331
332
333 /**
334 * Set the search paths from different sources, internal
335 *
336 * @return array Array of absolute paths (keys and values are equal)
337 * @internal
338 */
339 function _getPaths() {
340 global $T3_VAR, $TYPO3_CONF_VARS;
341
342 $pathsArr = array();
343 $sysPathArr = array();
344
345 // image magick paths first
346 // im_path_lzw take precedence over im_path
347 if ($imPath = ($TYPO3_CONF_VARS['GFX']['im_path_lzw'] ? $TYPO3_CONF_VARS['GFX']['im_path_lzw'] : $TYPO3_CONF_VARS['GFX']['im_path'])) {
348 $imPath = t3lib_exec::_fixPath($imPath);
349 $pathsArr[$imPath] = $imPath;
350 }
351
352 // add configured paths
353 if ($TYPO3_CONF_VARS['SYS']['binPath']) {
354 $sysPath = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['SYS']['binPath'],1);
355 foreach($sysPath as $val) {
356 $val = t3lib_exec::_fixPath($val);
357 $sysPathArr[$val]=$val;
358 }
359 }
360
361
362 // add path from environment
363 // TODO: how does this work for WIN
364 if ($GLOBALS['_SERVER']['PATH']) {
365 $sep = (TYPO3_OS=='WIN') ? ';' : ':';
366 $envPath = t3lib_div::trimExplode($sep,$GLOBALS['_SERVER']['PATH'],1);
367 foreach($envPath as $val) {
368 $val = t3lib_exec::_fixPath($val);
369 $sysPathArr[$val]=$val;
370 }
371 }
372
373 if (TYPO3_OS=='WIN') {
374 // TODO: add the most common paths for WIN
375 $sysPathArr = array_merge($sysPathArr, array (
376 '/usr/bin/' => '/usr/bin/',
377 '/perl/bin/' => '/perl/bin/',
378 ));
379 } else { // UNIX
380 $sysPathArr = array_merge($sysPathArr, array (
381 '/usr/bin/' => '/usr/bin/',
382 '/usr/local/bin/' => '/usr/local/bin/',
383 ));
384 }
385
386
387 $pathsArr = array_merge($pathsArr, $sysPathArr);
388
389 return $pathsArr;
390 }
391
392
393 /**
394 * Set a path to the right format
395 *
396 * @param string Input path
397 * @return string Output path
398 * @internal
399 */
400 function _fixPath($path) {
401 return str_replace ('//','/',$path.'/');
402 }
403 }
404
405 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']) {
406 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
407 }
408 ?>