Passed
Push — master ( 24a8ac...ec7ab5 )
by Théo
02:56
created

PhpSettingsHandler::restart()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box;
16
17
use Composer\XdebugHandler\Process;
18
use Composer\XdebugHandler\XdebugHandler;
19
use Psr\Log\LoggerInterface;
20
use const PHP_EOL;
21
use function function_exists;
22
use function getenv;
23
use function ini_get;
24
use function KevinGH\Box\FileSystem\append_to_file;
25
use function sprintf;
26
use function trim;
27
28
/**
29
 * @private
30
 */
31
final class PhpSettingsHandler extends XdebugHandler
32
{
33
    private $logger;
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function __construct(LoggerInterface $logger)
39
    {
40
        parent::__construct('box', '--ansi');
41
42
        $this->setLogger($logger);
43
        $this->logger = $logger;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function check(): void
50
    {
51
        parent::check();
52
53
        if (self::getRestartSettings()) {
54
            Process::setEnv('PHPRC', XdebugHandler::getRestartSettings()['tmpIni']);
55
            Process::setEnv('PHP_INI_SCAN_DIR', '');
56
        }
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    protected function requiresRestart($isLoaded)
63
    {
64
        return null === self::getRestartSettings();
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    protected function restart($command): void
71
    {
72
        if (function_exists('ini_get')) {
73
            // Disable phar.readonly if set
74
            $this->disablePharReadonly();
75
76
            // Bump the memory limit if necessary
77
            $this->bumpMemoryLimit();
78
        }
79
80
        parent::restart($command);
81
    }
82
83
    private function disablePharReadonly(): void
84
    {
85
        if (ini_get('phar.readonly')) {
86
            append_to_file($this->tmpIni, 'phar.readonly=0'.PHP_EOL);
1 ignored issue
show
Bug introduced by
It seems like $this->tmpIni can also be of type null; however, parameter $filename of KevinGH\Box\FileSystem\append_to_file() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
            append_to_file(/** @scrutinizer ignore-type */ $this->tmpIni, 'phar.readonly=0'.PHP_EOL);
Loading history...
87
88
            $this->logger->debug('Configured `phar.readonly=0`');
89
        }
90
    }
91
92
    /**
93
     * @see https://github.com/composer/composer/blob/34c371f5f23e25eb9aa54ccc65136cf50930612e/bin/composer#L20-L50
94
     */
95
    private function bumpMemoryLimit(): void
96
    {
97
        $memoryLimit = trim(ini_get('memory_limit'));
98
        $memoryLimitInBytes = '-1' === $memoryLimit ? '-1' : memory_to_bytes($memoryLimit);
99
100
        $boxMemoryLimit = getenv(BOX_MEMORY_LIMIT);
101
102
        if (false === $boxMemoryLimit) {
103
            $boxMemoryLimitInBytes = false;
104
        } elseif ('-1' === $boxMemoryLimit) {
105
            $boxMemoryLimitInBytes = '-1';
106
        } else {
107
            $boxMemoryLimitInBytes = memory_to_bytes($boxMemoryLimit);
108
        }
109
110
        // Increase memory_limit if it is lower than 500MB
111
        if (false === $boxMemoryLimitInBytes && '-1' !== $memoryLimitInBytes && $memoryLimitInBytes < 1024 * 1024 * 512) {
112
            append_to_file($this->tmpIni, 'memory_limit=512M'.PHP_EOL);
1 ignored issue
show
Bug introduced by
It seems like $this->tmpIni can also be of type null; however, parameter $filename of KevinGH\Box\FileSystem\append_to_file() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
            append_to_file(/** @scrutinizer ignore-type */ $this->tmpIni, 'memory_limit=512M'.PHP_EOL);
Loading history...
113
114
            $this->logger->debug(
115
                sprintf(
116
                    'Bumped the memory limit from "%s" to "%s"',
117
                    $memoryLimit,
118
                    '512M'
119
                )
120
            );
121
        }
122
123
        // Set user defined memory limit
124
        if ($boxMemoryLimitInBytes && $memoryLimitInBytes !== $boxMemoryLimitInBytes) {
125
            append_to_file($this->tmpIni, 'memory_limit='.$boxMemoryLimitInBytes.PHP_EOL);
126
127
            $this->logger->debug(
128
                sprintf(
129
                    'Bumped the memory limit from "%s" to %s="%s"',
130
                    $memoryLimit,
131
                    BOX_MEMORY_LIMIT,
132
                    $boxMemoryLimit
133
                )
134
            );
135
        }
136
    }
137
}
138