Blame view

src/Console/Installer.php 6.5 KB
6c4edfa3   Alexandre   First Commit LabI...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link      http://cakephp.org CakePHP(tm) Project
 * @since     3.0.0
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Console;

use Composer\Script\Event;
use Exception;

/**
 * Provides installation hooks for when this application is installed via
63c3cb16   epallier   Nombreux petits b...
22
23
 * composer.
 * Customize this class to suit your needs.
6c4edfa3   Alexandre   First Commit LabI...
24
25
26
27
28
29
30
 */
class Installer
{

    /**
     * Does some routine installation tasks so people don't have to.
     *
63c3cb16   epallier   Nombreux petits b...
31
32
     * @param \Composer\Script\Event $event
     *            The composer event object.
6c4edfa3   Alexandre   First Commit LabI...
33
34
35
36
37
38
     * @throws \Exception Exception raised by validator.
     * @return void
     */
    public static function postInstall(Event $event)
    {
        $io = $event->getIO();
63c3cb16   epallier   Nombreux petits b...
39
        
6c4edfa3   Alexandre   First Commit LabI...
40
        $rootDir = dirname(dirname(__DIR__));
63c3cb16   epallier   Nombreux petits b...
41
        
6c4edfa3   Alexandre   First Commit LabI...
42
43
        static::createAppConfig($rootDir, $io);
        static::createWritableDirectories($rootDir, $io);
63c3cb16   epallier   Nombreux petits b...
44
        
6c4edfa3   Alexandre   First Commit LabI...
45
46
47
        // ask if the permissions should be changed
        if ($io->isInteractive()) {
            $validator = function ($arg) {
63c3cb16   epallier   Nombreux petits b...
48
49
50
51
52
53
                if (in_array($arg, [
                    'Y',
                    'y',
                    'N',
                    'n'
                ])) {
6c4edfa3   Alexandre   First Commit LabI...
54
55
56
57
                    return $arg;
                }
                throw new Exception('This is not a valid answer. Please choose Y or n.');
            };
63c3cb16   epallier   Nombreux petits b...
58
59
60
61
62
63
            $setFolderPermissions = $io->askAndValidate('<info>Set Folder Permissions ? (Default to Y)</info> [<comment>Y,n</comment>]? ', $validator, 10, 'Y');
            
            if (in_array($setFolderPermissions, [
                'Y',
                'y'
            ])) {
6c4edfa3   Alexandre   First Commit LabI...
64
65
66
67
68
                static::setFolderPermissions($rootDir, $io);
            }
        } else {
            static::setFolderPermissions($rootDir, $io);
        }
63c3cb16   epallier   Nombreux petits b...
69
        
6c4edfa3   Alexandre   First Commit LabI...
70
        static::setSecuritySalt($rootDir, $io);
63c3cb16   epallier   Nombreux petits b...
71
        
6c4edfa3   Alexandre   First Commit LabI...
72
73
74
75
76
77
78
79
        if (class_exists('\Cake\Codeception\Console\Installer')) {
            \Cake\Codeception\Console\Installer::customizeCodeceptionBinary($event);
        }
    }

    /**
     * Create the config/app.php file if it does not exist.
     *
63c3cb16   epallier   Nombreux petits b...
80
81
82
83
     * @param string $dir
     *            The application's root directory.
     * @param \Composer\IO\IOInterface $io
     *            IO interface to write to console.
6c4edfa3   Alexandre   First Commit LabI...
84
85
86
87
88
89
     * @return void
     */
    public static function createAppConfig($dir, $io)
    {
        $appConfig = $dir . '/config/app.php';
        $defaultConfig = $dir . '/config/app.default.php';
63c3cb16   epallier   Nombreux petits b...
90
        if (! file_exists($appConfig)) {
6c4edfa3   Alexandre   First Commit LabI...
91
92
93
94
95
96
97
98
            copy($defaultConfig, $appConfig);
            $io->write('Created `config/app.php` file');
        }
    }

    /**
     * Create the `logs` and `tmp` directories.
     *
63c3cb16   epallier   Nombreux petits b...
99
100
101
102
     * @param string $dir
     *            The application's root directory.
     * @param \Composer\IO\IOInterface $io
     *            IO interface to write to console.
6c4edfa3   Alexandre   First Commit LabI...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
     * @return void
     */
    public static function createWritableDirectories($dir, $io)
    {
        $paths = [
            'logs',
            'tmp',
            'tmp/cache',
            'tmp/cache/models',
            'tmp/cache/persistent',
            'tmp/cache/views',
            'tmp/sessions',
            'tmp/tests'
        ];
63c3cb16   epallier   Nombreux petits b...
117
        
6c4edfa3   Alexandre   First Commit LabI...
118
119
        foreach ($paths as $path) {
            $path = $dir . '/' . $path;
63c3cb16   epallier   Nombreux petits b...
120
            if (! file_exists($path)) {
6c4edfa3   Alexandre   First Commit LabI...
121
122
123
124
125
126
127
128
129
130
131
                mkdir($path);
                $io->write('Created `' . $path . '` directory');
            }
        }
    }

    /**
     * Set globally writable permissions on the "tmp" and "logs" directory.
     *
     * This is not the most secure default, but it gets people up and running quickly.
     *
63c3cb16   epallier   Nombreux petits b...
132
133
134
135
     * @param string $dir
     *            The application's root directory.
     * @param \Composer\IO\IOInterface $io
     *            IO interface to write to console.
6c4edfa3   Alexandre   First Commit LabI...
136
137
138
139
140
141
142
143
144
145
146
     * @return void
     */
    public static function setFolderPermissions($dir, $io)
    {
        // Change the permissions on a path and output the results.
        $changePerms = function ($path, $perms, $io) {
            // Get permission bits from stat(2) result.
            $currentPerms = fileperms($path) & 0777;
            if (($currentPerms & $perms) == $perms) {
                return;
            }
63c3cb16   epallier   Nombreux petits b...
147
            
6c4edfa3   Alexandre   First Commit LabI...
148
149
150
151
152
153
154
            $res = chmod($path, $currentPerms | $perms);
            if ($res) {
                $io->write('Permissions set on ' . $path);
            } else {
                $io->write('Failed to set permissions on ' . $path);
            }
        };
63c3cb16   epallier   Nombreux petits b...
155
        
6c4edfa3   Alexandre   First Commit LabI...
156
        $walker = function ($dir, $perms, $io) use (&$walker, $changePerms) {
63c3cb16   epallier   Nombreux petits b...
157
158
159
160
            $files = array_diff(scandir($dir), [
                '.',
                '..'
            ]);
6c4edfa3   Alexandre   First Commit LabI...
161
162
            foreach ($files as $file) {
                $path = $dir . '/' . $file;
63c3cb16   epallier   Nombreux petits b...
163
164
                
                if (! is_dir($path)) {
6c4edfa3   Alexandre   First Commit LabI...
165
166
                    continue;
                }
63c3cb16   epallier   Nombreux petits b...
167
                
6c4edfa3   Alexandre   First Commit LabI...
168
169
170
171
                $changePerms($path, $perms, $io);
                $walker($path, $perms, $io);
            }
        };
63c3cb16   epallier   Nombreux petits b...
172
        
6c4edfa3   Alexandre   First Commit LabI...
173
174
175
176
177
178
179
180
181
        $worldWritable = bindec('0000000111');
        $walker($dir . '/tmp', $worldWritable, $io);
        $changePerms($dir . '/tmp', $worldWritable, $io);
        $changePerms($dir . '/logs', $worldWritable, $io);
    }

    /**
     * Set the security.salt value in the application's config file.
     *
63c3cb16   epallier   Nombreux petits b...
182
183
184
185
     * @param string $dir
     *            The application's root directory.
     * @param \Composer\IO\IOInterface $io
     *            IO interface to write to console.
6c4edfa3   Alexandre   First Commit LabI...
186
187
188
189
190
191
     * @return void
     */
    public static function setSecuritySalt($dir, $io)
    {
        $config = $dir . '/config/app.php';
        $content = file_get_contents($config);
63c3cb16   epallier   Nombreux petits b...
192
        
6c4edfa3   Alexandre   First Commit LabI...
193
194
        $newKey = hash('sha256', $dir . php_uname() . microtime(true));
        $content = str_replace('__SALT__', $newKey, $content, $count);
63c3cb16   epallier   Nombreux petits b...
195
        
6c4edfa3   Alexandre   First Commit LabI...
196
197
198
199
        if ($count == 0) {
            $io->write('No Security.salt placeholder to replace.');
            return;
        }
63c3cb16   epallier   Nombreux petits b...
200
        
6c4edfa3   Alexandre   First Commit LabI...
201
202
203
204
205
206
207
208
        $result = file_put_contents($config, $content);
        if ($result) {
            $io->write('Updated Security.salt value in config/app.php');
            return;
        }
        $io->write('Unable to update Security.salt value.');
    }
}