Completed
Push — master ( 509111...bb227c )
by Igor
02:24
created

c3.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
// @codingStandardsIgnoreFile
3
// @codeCoverageIgnoreStart
4
5
/**
6
 * C3 - Codeception Code Coverage
7
 *
8
 * @author tiger
9
 */
10
11
// $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG'] = 1;
12
13
if (isset($_COOKIE['CODECEPTION_CODECOVERAGE'])) {
14
    $cookie = json_decode($_COOKIE['CODECEPTION_CODECOVERAGE'], true);
15
16
    // fix for improperly encoded JSON in Code Coverage cookie with WebDriver.
17
    // @see https://github.com/Codeception/Codeception/issues/874
18
    if (!is_array($cookie)) {
19
        $cookie = json_decode($cookie, true);
20
    }
21
22
    if ($cookie) {    
23
        foreach ($cookie as $key => $value) {
24
            $_SERVER["HTTP_X_CODECEPTION_".strtoupper($key)] = $value;
25
        }
26
    }
27
}
28
29
if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE', $_SERVER)) {
30
    return;
31
}
32
33
if (!function_exists('__c3_error')) {
34
    function __c3_error($message)
35
    {
36
/*        file_put_contents(C3_CODECOVERAGE_MEDIATE_STORAGE . DIRECTORY_SEPARATOR . 'error.txt', $message);
37
        if (!headers_sent()) {
38
            header('X-Codeception-CodeCoverage-Error: ' . str_replace("\n", ' ', $message), true, 500);
39
        }*/
40
        setcookie('CODECEPTION_CODECOVERAGE_ERROR', $message);
41
    }
42
}
43
44
// Autoload Codeception classes
45
if (!class_exists('\\Codeception\\Codecept')) {
46
    if (stream_resolve_include_path(__DIR__ . '/vendor/autoload.php')) {
47
        require_once __DIR__ . '/vendor/autoload.php';
48
    } elseif (file_exists(__DIR__ . '/codecept.phar')) {
49
        require_once 'phar://'.__DIR__ . '/codecept.phar/autoload.php';
50
    } elseif (stream_resolve_include_path('Codeception/autoload.php')) {
51
        require_once 'Codeception/autoload.php';
52
    } else {
53
        __c3_error('Codeception is not loaded. Please check that either PHAR or Composer or PEAR package can be used');
54
    }
55
}
56
57
// Load Codeception Config
58
$config_file = realpath(__DIR__) . DIRECTORY_SEPARATOR . 'codeception.yml';
59
if (isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_CONFIG'])) {
60
    $config_file = realpath(__DIR__) . DIRECTORY_SEPARATOR . $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_CONFIG'];
61
}
62
if (!file_exists($config_file)) {
63
    __c3_error(sprintf("Codeception config file '%s' not found", $config_file));
64
}
65
try {
66
    \Codeception\Configuration::config($config_file);
67
} catch (\Exception $e) {
68
    __c3_error($e->getMessage());
69
}
70
71
if (!defined('C3_CODECOVERAGE_MEDIATE_STORAGE')) {
72
73
    // workaround for 'zend_mm_heap corrupted' problem
74
    gc_disable();
75
76
    if ((integer)ini_get('memory_limit') < 384) {
77
        ini_set('memory_limit', '384M');
78
    }
79
80
    define('C3_CODECOVERAGE_MEDIATE_STORAGE', Codeception\Configuration::logDir() . 'c3tmp');
81
    define('C3_CODECOVERAGE_PROJECT_ROOT', Codeception\Configuration::projectDir());
82
    define('C3_CODECOVERAGE_TESTNAME', $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE']);
83
84
    function __c3_build_html_report(PHP_CodeCoverage $codeCoverage, $path)
85
    {
86
        $writer = new PHP_CodeCoverage_Report_HTML();
87
        $writer->process($codeCoverage, $path . 'html');
88
89
        if (file_exists($path . '.tar')) {
90
            unlink($path . '.tar');
91
        }
92
93
        $phar = new PharData($path . '.tar');
94
        $phar->setSignatureAlgorithm(Phar::SHA1);
95
        $files = $phar->buildFromDirectory($path . 'html');
96
        array_map('unlink', $files);
97
98
        if (in_array('GZ', Phar::getSupportedCompression())) {
99
            if (file_exists($path . '.tar.gz')) {
100
                unlink($path . '.tar.gz');
101
            }
102
103
            $phar->compress(\Phar::GZ);
104
105
            // close the file so that we can rename it
106
            unset($phar);
107
108
            unlink($path . '.tar');
109
            rename($path . '.tar.gz', $path . '.tar');
110
        }
111
112
        return $path . '.tar';
113
    }
114
115
    function __c3_build_clover_report(PHP_CodeCoverage $codeCoverage, $path)
116
    {
117
        $writer = new PHP_CodeCoverage_Report_Clover();
118
        $writer->process($codeCoverage, $path . '.clover.xml');
119
120
        return $path . '.clover.xml';
121
    }
122
123
    function __c3_send_file($filename)
124
    {
125
        if (!headers_sent()) {
126
            readfile($filename);
127
        }
128
129
        return __c3_exit();
130
    }
131
132
    /**
133
     * @param $filename
134
     * @return null|PHP_CodeCoverage
135
     */
136
    function __c3_factory($filename)
137
    {
138
        $phpCoverage = is_readable($filename)
139
            ? unserialize(file_get_contents($filename))
140
            : new PHP_CodeCoverage();
141
142
143
        if (isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'])) {
144
            $suite = $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'];
145
            try {
146
                $settings = \Codeception\Configuration::suiteSettings($suite, \Codeception\Configuration::config());
147
            } catch (Exception $e) {
148
                __c3_error($e->getMessage());
149
            }
150
        } else {
151
            $settings = \Codeception\Configuration::config();
152
        }
153
154
        try {
155
            \Codeception\Coverage\Filter::setup($phpCoverage)
156
                ->whiteList($settings)
157
                ->blackList($settings);
158
        } catch (Exception $e) {
159
            __c3_error($e->getMessage());
160
        }
161
162
        return $phpCoverage;
163
    }
164
165
    function __c3_exit()
166
    {
167
        if (!isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG'])) {
168
            exit;
169
        }
170
        return null;
171
    }
172
173
    function __c3_clear()
174
    {
175
        \Codeception\Util\FileSystem::doEmptyDir(C3_CODECOVERAGE_MEDIATE_STORAGE);
176
    }
177
}
178
179
if (!is_dir(C3_CODECOVERAGE_MEDIATE_STORAGE)) {
180
    if (mkdir(C3_CODECOVERAGE_MEDIATE_STORAGE, 0777, true) === false) {
181
        __c3_error('Failed to create directory "' . C3_CODECOVERAGE_MEDIATE_STORAGE . '"');
182
    }
183
}
184
185
// evaluate base path for c3-related files
186
$path = realpath(C3_CODECOVERAGE_MEDIATE_STORAGE) . DIRECTORY_SEPARATOR . 'codecoverage';
187
188
$requested_c3_report = (strpos($_SERVER['REQUEST_URI'], 'c3/report') !== false);
189
190
$complete_report = $current_report = $path . '.serialized';
191
if ($requested_c3_report) {
192
    set_time_limit(0);
193
194
    $route = ltrim(strrchr($_SERVER['REQUEST_URI'], '/'), '/');
195
196
    if ($route == 'clear') {
197
        __c3_clear();
198
        return __c3_exit();
199
    }
200
201
    $codeCoverage = __c3_factory($complete_report);
202
203
    switch ($route) {
204 View Code Duplication
        case 'html':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
205
            try {
206
                __c3_send_file(__c3_build_html_report($codeCoverage, $path));
0 ignored issues
show
It seems like $codeCoverage defined by __c3_factory($complete_report) on line 201 can be null; however, __c3_build_html_report() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
207
            } catch (Exception $e) {
208
                __c3_error($e->getMessage());
209
            }
210
            return __c3_exit();
211 View Code Duplication
        case 'clover':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
            try {
213
                __c3_send_file(__c3_build_clover_report($codeCoverage, $path));
0 ignored issues
show
It seems like $codeCoverage defined by __c3_factory($complete_report) on line 201 can be null; however, __c3_build_clover_report() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
214
            } catch (Exception $e) {
215
                __c3_error($e->getMessage());
216
            }
217
            return __c3_exit();
218
        case 'serialized':
219
            try {
220
                __c3_send_file($complete_report);
221
            } catch (Exception $e) {
222
                __c3_error($e->getMessage());
223
            }
224
            return __c3_exit();
225
    }
226
227
} else {
228
    $codeCoverage = __c3_factory($current_report);
229
    $codeCoverage->start(C3_CODECOVERAGE_TESTNAME);
230
    if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG', $_SERVER)) { 
231
        register_shutdown_function(
232
            function () use ($codeCoverage, $current_report) {
233
                $codeCoverage->stop();
234
                file_put_contents($current_report, serialize($codeCoverage));
235
            }
236
        );
237
    }
238
}
239
240
// @codeCoverageIgnoreEnd