Issues (67)

src/Package/PHP/Package.php (3 issues)

1
<?php
2
3
/*
4
 * Pickle
5
 *
6
 *
7
 * @license
8
 *
9
 * New BSD License
10
 *
11
 * Copyright © 2015-2015, Pickle community. All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *     * Redistributions of source code must retain the above copyright
16
 *       notice, this list of conditions and the following disclaimer.
17
 *     * Redistributions in binary form must reproduce the above copyright
18
 *       notice, this list of conditions and the following disclaimer in the
19
 *       documentation and/or other materials provided with the distribution.
20
 *     * Neither the name of the Hoa nor the names of its contributors may be
21
 *       used to endorse or promote products derived from this software without
22
 *       specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 */
36
37
namespace Pickle\Package\PHP;
38
39
use CallbackFilterIterator;
40
use Exception;
41
use Pickle\Base\Abstracts;
42
use Pickle\Base\Util\GitIgnore;
43
use RecursiveDirectoryIterator;
44
use RecursiveIteratorIterator;
45
46
class Package extends Abstracts\Package implements \Pickle\Base\Interfaces\Package
47
{
48
    /**
49
     * @var string Package's root directory
50
     */
51
    protected $path;
52
53
    /**
54
     * Get the package's root directory.
55
     *
56
     * @return string
57
     */
58
    public function getRootDir()
59
    {
60 1
        return $this->path;
61
    }
62
63
    /**
64
     * Get the package's root directory.
65
     *
66
     * @return string
67
     */
68
    public function getSourceDir()
69
    {
70 1
        $path = $this->getRootDir();
71 1
        $release = $path . DIRECTORY_SEPARATOR . $this->getPrettyName() . '-' . $this->getPrettyVersion();
72
73 1
        if (is_dir($release)) {
74 1
            $path = $release;
75
        }
76
77
        /* Do subdir search */
78 1
        if (!$this->extConfigIsIn($path)) {
79 1
            $path = $this->locateSourceDirByExtConfig($path);
80
81 1
            if ($path === null) {
82
                throw new Exception('config*.(m4|w32) not found');
83
            }
84
        }
85
86 1
        return $path;
87
    }
88
89
    /**
90
     * Set the package's source directory, containing config.m4/config.w32.
91
     *
92
     * @param string $path
93
     */
94
    public function setRootDir($path)
95
    {
96 1
        $this->path = $path;
97 1
    }
98
99
    public function setStability($stability)
100
    {
101
        $this->stability = $stability;
102
    }
103
104
    /**
105
     * @return array
106
     */
107
    public function getConfigureOptions()
108
    {
109 1
        $options = [];
110
111 1
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
112 1
            $config_file = $this->getSourceDir() . '/config.w32';
113
114 1
            if (!file_exists($config_file)) {
115
                throw new Exception('cnofig.w32 not found');
116
            }
117
118 1
            $config = file_get_contents($config_file);
119
120 1
            $options = array_merge(
121 1
                $this->fetchArgWindows('ARG_WITH', $config),
122 1
                $this->fetchArgWindows('ARG_ENABLE', $config)
123
            );
124
        } else {
125 1
            $configs = glob($this->getSourceDir() . '/' . 'config*.m4');
126
127 1
            if (!empty($configs)) {
128 1
                foreach ($configs as $config) {
129 1
                    $options = array_merge($options, $this->getConfigureOptionsFromFile($config));
130
                }
131
            }
132
        }
133
134 1
        return $options;
135
    }
136
137
    public function getConfigureOptionsFromFile($file)
138
    {
139 1
        $config = file_get_contents($file);
140
141 1
        return array_merge(
142 1
            $this->fetchArg('PHP_ARG_WITH', $config),
143 1
            $this->fetchArgAc('AC_ARG_WITH', $config),
144 1
            $this->fetchArg('PHP_ARG_ENABLE', $config),
145 1
            $this->fetchArgAc('AC_ARG_ENABLE', $config)
146
        );
147
    }
148
149
    /**
150
     * Get files, will not return gitignore files.
151
     *
152
     * @return CallbackFilterIterator
153
     */
154
    public function getFiles()
155
    {
156
        return new CallbackFilterIterator(
157
            new RecursiveIteratorIterator(
158
                new RecursiveDirectoryIterator($this->getSourceDir())
159
            ),
160
            new GitIgnore($this)
161
        );
162
    }
163
164
    public function getVersionFromHeader()
165
    {
166
        $headers = glob($this->path . DIRECTORY_SEPARATOR . '*.h');
167
        $version_define = 'PHP_' . strtoupper($this->getSimpleName()) . '_VERSION';
168
        foreach ($headers as $header) {
169
            $contents = @file_get_contents($header);
170
            if (!$contents) {
171
                throw new Exception("Cannot read header <{$header}>");
172
            }
173
            $pos_version = strpos($contents, $version_define);
174
            if ($pos_version !== false) {
175
                $nl = strpos($contents, "\n", $pos_version);
176
                $version_line = trim(substr($contents, $pos_version, $nl - $pos_version));
177
                [$version_define, $version] = explode(' ', $version_line);
178
                $version = trim(str_replace('"', '', $version));
179
                break;
180
            }
181
        }
182
        if (empty($version)) {
183
            throw new Exception('No ' . $version_define . ' can be found');
184
        }
185
186
        return [trim($version_define), $version];
187
    }
188
189
    /**
190
     * @param string $which
191
     * @param string $config
192
     *
193
     * @return array
194
     */
195
    protected function fetchArgWindows($which, $config)
196
    {
197 1
        $next = 0;
198 1
        $options = [];
199 1
        $type = strpos($which, 'ENABLE') !== false ? 'enable' : 'with';
200 1
        while (false !== ($s = strpos($config, $which, $next))) {
201 1
            $s = strpos($config, '(', $s);
202 1
            $e = strpos($config, ')', $s + 1);
203 1
            $option = substr($config, $s + 1, $e - $s);
204
205 1
            $elems = explode(',', $option);
206 1
            array_walk($elems, function (&$a) {
207 1
                $a = str_replace([')', "'"], ['', ''], $a);
208 1
                $a = trim($a);
209 1
            });
210
211 1
            @[$name, $prompt, $default] = $elems;
212 1
            $name = str_replace('"', '', $name);
213 1
            $options[$name] = (object) [
214 1
                'prompt' => $prompt,
215 1
                'type' => $type,
216 1
                'default' => $default,
217
            ];
218 1
            $next = $e + 1;
219
        }
220
221 1
        return $options;
222
    }
223
224
    protected function isWithOrEnable($option, $type)
225
    {
226 1
        if ($type == 'enable') {
227 1
            $default = (strpos($option, '-disable-') !== false) ? true : false;
228 1
        } elseif ($type == 'with') {
229 1
            $default = (strpos($option, '-without-') !== false) ? true : false;
230
        }
231 1
        return $default;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $default does not seem to be defined for all execution paths leading up to this point.
Loading history...
232
    }
233
234
    /**
235
     * @param string $which
236
     * @param string $config
237
     *
238
     * @return array
239
     */
240
    protected function fetchArgAc($which, $config)
241
    {
242 1
        $next = 0;
243 1
        $options = [];
244 1
        $type = strpos($which, 'ENABLE') !== false ? 'enable' : 'with';
245 1
        while (false !== ($s = strpos($config, $which, $next))) {
246 1
            $default = true;
0 ignored issues
show
The assignment to $default is dead and can be removed.
Loading history...
247 1
            $s = strpos($config, '(', $s);
248 1
            $e = strpos($config, ')', $s + 1);
249 1
            $option = substr($config, $s + 1, $e - $s);
250
251 1
            $default = $this->isWithOrEnable($option, $type);
252 1
            [$name, $desc] = explode(',', $option);
253
254 1
            $desc = preg_replace('/\s+/', ' ', trim($desc));
255 1
            $desc = trim(substr($desc, 1, strlen($desc) - 2));
256 1
            $s_a = strpos($desc, ' ');
257 1
            $desc = trim(substr($desc, $s_a));
258
259 1
            $options[$name] = (object) [
260 1
                'prompt' => $desc,
261 1
                'type' => $type,
262 1
                'default' => $default,
263
            ];
264
265 1
            $next = $e + 1;
266
        }
267
268 1
        return $options;
269
    }
270
271
    /**
272
     * @param string $which
273
     * @param string $config
274
     *
275
     * @return array
276
     */
277
    protected function fetchArg($which, $config)
278
    {
279 1
        $next = 0;
280 1
        $options = [];
281
282 1
        $type = strpos($which, 'ENABLE') !== false ? 'enable' : 'with';
283 1
        while (false !== ($s = strpos($config, $which, $next))) {
284 1
            $default = 'y';
0 ignored issues
show
The assignment to $default is dead and can be removed.
Loading history...
285 1
            $s = strpos($config, '(', $s);
286 1
            $e = strpos($config, ')', $s + 1);
287 1
            $option = substr($config, $s + 1, $e - $s);
288
289 1
            [$name, $desc] = explode(',', $option);
290
291
            /* Description can be part of the 3rd argument */
292 1
            if (empty($desc) || $desc === '[]') {
293 1
                [$name, , $desc] = explode(',', $option);
294 1
                $desc = preg_replace('/\s+/', ' ', trim($desc));
295 1
                $desc = trim(substr($desc, 1, strlen($desc) - 2));
296 1
                $desc = trim(str_replace(['[', ']'], ['', ''], $desc));
297 1
                $s_a = strpos($desc, ' ');
298 1
                $desc = trim(substr($desc, $s_a));
299
            }
300
301 1
            $default = $this->isWithOrEnable($option, $type);
302 1
            $name = str_replace(['[', ']'], ['', ''], $name);
303 1
            $options[$name] = (object) [
304 1
                'prompt' => trim($desc),
305 1
                'type' => $type,
306 1
                'default' => $default,
307
            ];
308 1
            $next = $e + 1;
309
        }
310
311 1
        return $options;
312
    }
313
314
    protected function extConfigIsIn($path)
315
    {
316 1
        if (defined('PHP_WINDOWS_VERSION_MAJOR') !== false) {
317 1
            return file_exists(realpath($path) . DIRECTORY_SEPARATOR . 'config.w32');
318
        }
319 1
        $r = glob("{$path}/config*.m4");
320
321 1
        return is_array($r) && !empty($r);
322
    }
323
324
    protected function locateSourceDirByExtConfig($path)
325
    {
326 1
        $it = new RecursiveIteratorIterator(
327 1
            new RecursiveDirectoryIterator($path),
328 1
            RecursiveIteratorIterator::SELF_FIRST
329
        );
330
331 1
        foreach ($it as $fl_obj) {
332 1
            if ($fl_obj->isFile() && preg_match(',config*.(m4|w32),', $fl_obj->getBasename())) {
333 1
                return $fl_obj->getPath();
334
            }
335
        }
336
    }
337
}
338
339
/* vim: set tabstop=4 shiftwidth=4 expandtab: fdm=marker */
340