xref: /plugin/combo/vendor/symfony/process/ExecutableFinder.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau
3*04fd306cSNickeau/*
4*04fd306cSNickeau * This file is part of the Symfony package.
5*04fd306cSNickeau *
6*04fd306cSNickeau * (c) Fabien Potencier <fabien@symfony.com>
7*04fd306cSNickeau *
8*04fd306cSNickeau * For the full copyright and license information, please view the LICENSE
9*04fd306cSNickeau * file that was distributed with this source code.
10*04fd306cSNickeau */
11*04fd306cSNickeau
12*04fd306cSNickeaunamespace Symfony\Component\Process;
13*04fd306cSNickeau
14*04fd306cSNickeau/**
15*04fd306cSNickeau * Generic executable finder.
16*04fd306cSNickeau *
17*04fd306cSNickeau * @author Fabien Potencier <fabien@symfony.com>
18*04fd306cSNickeau * @author Johannes M. Schmitt <schmittjoh@gmail.com>
19*04fd306cSNickeau */
20*04fd306cSNickeauclass ExecutableFinder
21*04fd306cSNickeau{
22*04fd306cSNickeau    private $suffixes = ['.exe', '.bat', '.cmd', '.com'];
23*04fd306cSNickeau
24*04fd306cSNickeau    /**
25*04fd306cSNickeau     * Replaces default suffixes of executable.
26*04fd306cSNickeau     */
27*04fd306cSNickeau    public function setSuffixes(array $suffixes)
28*04fd306cSNickeau    {
29*04fd306cSNickeau        $this->suffixes = $suffixes;
30*04fd306cSNickeau    }
31*04fd306cSNickeau
32*04fd306cSNickeau    /**
33*04fd306cSNickeau     * Adds new possible suffix to check for executable.
34*04fd306cSNickeau     */
35*04fd306cSNickeau    public function addSuffix(string $suffix)
36*04fd306cSNickeau    {
37*04fd306cSNickeau        $this->suffixes[] = $suffix;
38*04fd306cSNickeau    }
39*04fd306cSNickeau
40*04fd306cSNickeau    /**
41*04fd306cSNickeau     * Finds an executable by name.
42*04fd306cSNickeau     *
43*04fd306cSNickeau     * @param string      $name      The executable name (without the extension)
44*04fd306cSNickeau     * @param string|null $default   The default to return if no executable is found
45*04fd306cSNickeau     * @param array       $extraDirs Additional dirs to check into
46*04fd306cSNickeau     *
47*04fd306cSNickeau     * @return string|null
48*04fd306cSNickeau     */
49*04fd306cSNickeau    public function find(string $name, string $default = null, array $extraDirs = [])
50*04fd306cSNickeau    {
51*04fd306cSNickeau        if (ini_get('open_basedir')) {
52*04fd306cSNickeau            $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
53*04fd306cSNickeau            $dirs = [];
54*04fd306cSNickeau            foreach ($searchPath as $path) {
55*04fd306cSNickeau                // Silencing against https://bugs.php.net/69240
56*04fd306cSNickeau                if (@is_dir($path)) {
57*04fd306cSNickeau                    $dirs[] = $path;
58*04fd306cSNickeau                } else {
59*04fd306cSNickeau                    if (basename($path) == $name && @is_executable($path)) {
60*04fd306cSNickeau                        return $path;
61*04fd306cSNickeau                    }
62*04fd306cSNickeau                }
63*04fd306cSNickeau            }
64*04fd306cSNickeau        } else {
65*04fd306cSNickeau            $dirs = array_merge(
66*04fd306cSNickeau                explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
67*04fd306cSNickeau                $extraDirs
68*04fd306cSNickeau            );
69*04fd306cSNickeau        }
70*04fd306cSNickeau
71*04fd306cSNickeau        $suffixes = [''];
72*04fd306cSNickeau        if ('\\' === \DIRECTORY_SEPARATOR) {
73*04fd306cSNickeau            $pathExt = getenv('PATHEXT');
74*04fd306cSNickeau            $suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
75*04fd306cSNickeau        }
76*04fd306cSNickeau        foreach ($suffixes as $suffix) {
77*04fd306cSNickeau            foreach ($dirs as $dir) {
78*04fd306cSNickeau                if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
79*04fd306cSNickeau                    return $file;
80*04fd306cSNickeau                }
81*04fd306cSNickeau            }
82*04fd306cSNickeau        }
83*04fd306cSNickeau
84*04fd306cSNickeau        return $default;
85*04fd306cSNickeau    }
86*04fd306cSNickeau}
87