Compiler::getStub()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 0
1
<?php
2
3
namespace AlreadyExtract;
4
5
use Symfony\Component\Finder\Finder;
6
7
/**
8
 * Inspired By Composer Compiler class
9
 * @package AlreadyExtract
10
 */
11
class Compiler
12
{
13
    public function compile($pharFile = 'already-extract.phar')
14
    {
15
        if (file_exists($pharFile)) {
16
            unlink($pharFile);
17
        }
18
19
        $phar = new \Phar($pharFile, 0, 'already-extract.phar');
20
        $phar->setSignatureAlgorithm(\Phar::SHA1);
21
22
        $phar->startBuffering();
23
24
        $finder = new Finder();
25
        $finder->files()
26
            ->ignoreVCS(true)
27
            ->name('*.php')
28
            ->notName('Compiler.php')
29
            ->in(__DIR__ . '/..')
30
        ;
31
32
        foreach ($finder as $file) {
33
            $this->addFile($phar, $file);
34
        }
35
36
        $finder = new Finder();
37
        $finder->files()
38
            ->ignoreVCS(true)
39
            ->name('*.php')
40
            ->exclude('Tests')
41
            ->in(__DIR__ . '/../../vendor/symfony/')
42
        ;
43
44
        foreach ($finder as $file) {
45
            $this->addFile($phar, $file);
46
        }
47
48
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/autoload.php'));
49
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_namespaces.php'));
50
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_psr4.php'));
51
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_classmap.php'));
52
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/autoload_real.php'));
53
        $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/composer/ClassLoader.php'));
54
        $this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/include_paths.php'));
55
56
        $this->addAlreadyExtractBin($phar);
57
        $phar->setStub($this->getStub());
58
59
        $phar->stopBuffering();
60
61
        unset($phar);
62
    }
63
64
    private function addFile($phar, $file)
65
    {
66
        $path = strtr(str_replace(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR, '', $file->getRealPath()), '\\', '/');
67
68
        $content = file_get_contents($file);
69
        $content = $this->stripWhitespace($content);
70
71
        $phar->addFromString($path, $content);
72
    }
73
74
    private function addAlreadyExtractBin($phar)
75
    {
76
        $content = file_get_contents(__DIR__ . '/../../bin/already-extract');
77
        $content = preg_replace('{^#!/usr/bin/env php\s*}', '', $content);
78
        $phar->addFromString('bin/already-extract', $content);
79
    }
80
81
    private function getStub()
82
    {
83
        $stub = <<<'EOF'
84
#!/usr/bin/env php
85
<?php
86
87
Phar::mapPhar('already-extract.phar');
88
89
EOF;
90
91
        return $stub . <<<'EOF'
92
require 'phar://already-extract.phar/bin/already-extract';
93
94
__HALT_COMPILER();
95
EOF;
96
    }
97
98
    /**
99
     * Removes whitespace from a PHP source string while preserving line numbers.
100
     *
101
     * @param  string $source A PHP string
102
     * @return string The PHP string with the whitespace removed
103
     */
104
    private function stripWhitespace($source)
105
    {
106
        if (!function_exists('token_get_all')) {
107
            return $source;
108
        }
109
110
        $output = '';
111
        foreach (token_get_all($source) as $token) {
112
            if (is_string($token)) {
113
                $output .= $token;
114
            } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
115
                $output .= str_repeat("\n", substr_count($token[1], "\n"));
116
            } elseif (T_WHITESPACE === $token[0]) {
117
                // reduce wide spaces
118
                $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
119
                // normalize newlines to \n
120
                $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
121
                // trim leading spaces
122
                $whitespace = preg_replace('{\n +}', "\n", $whitespace);
123
                $output .= $whitespace;
124
            } else {
125
                $output .= $token[1];
126
            }
127
        }
128
129
        return $output;
130
    }
131
}
132