adding example apps, fixing powerup issues
[feisty_meow.git] / production / example_apps / zippy_maps / src / Console / Installer.php
1 <?php
2 /**
3  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5  *
6  * Licensed under The MIT License
7  * For full copyright and license information, please see the LICENSE.txt
8  * Redistributions of files must retain the above copyright notice.
9  *
10  * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11  * @link      http://cakephp.org CakePHP(tm) Project
12  * @since     3.0.0
13  * @license   http://www.opensource.org/licenses/mit-license.php MIT License
14  */
15 namespace App\Console;
16
17 use Cake\Utility\Security;
18 use Composer\Script\Event;
19 use Exception;
20
21 /**
22  * Provides installation hooks for when this application is installed via
23  * composer. Customize this class to suit your needs.
24  */
25 class Installer
26 {
27
28     /**
29      * Does some routine installation tasks so people don't have to.
30      *
31      * @param \Composer\Script\Event $event The composer event object.
32      * @throws \Exception Exception raised by validator.
33      * @return void
34      */
35     public static function postInstall(Event $event)
36     {
37         $io = $event->getIO();
38
39         $rootDir = dirname(dirname(__DIR__));
40
41         static::createAppConfig($rootDir, $io);
42         static::createWritableDirectories($rootDir, $io);
43
44         // ask if the permissions should be changed
45         if ($io->isInteractive()) {
46             $validator = function ($arg) {
47                 if (in_array($arg, ['Y', 'y', 'N', 'n'])) {
48                     return $arg;
49                 }
50                 throw new Exception('This is not a valid answer. Please choose Y or n.');
51             };
52             $setFolderPermissions = $io->askAndValidate(
53                 '<info>Set Folder Permissions ? (Default to Y)</info> [<comment>Y,n</comment>]? ',
54                 $validator,
55                 10,
56                 'Y'
57             );
58
59             if (in_array($setFolderPermissions, ['Y', 'y'])) {
60                 static::setFolderPermissions($rootDir, $io);
61             }
62         } else {
63             static::setFolderPermissions($rootDir, $io);
64         }
65
66         static::setSecuritySalt($rootDir, $io);
67
68         if (class_exists('\Cake\Codeception\Console\Installer')) {
69             \Cake\Codeception\Console\Installer::customizeCodeceptionBinary($event);
70         }
71     }
72
73     /**
74      * Create the config/app.php file if it does not exist.
75      *
76      * @param string $dir The application's root directory.
77      * @param \Composer\IO\IOInterface $io IO interface to write to console.
78      * @return void
79      */
80     public static function createAppConfig($dir, $io)
81     {
82         $appConfig = $dir . '/config/app.php';
83         $defaultConfig = $dir . '/config/app.default.php';
84         if (!file_exists($appConfig)) {
85             copy($defaultConfig, $appConfig);
86             $io->write('Created `config/app.php` file');
87         }
88     }
89
90     /**
91      * Create the `logs` and `tmp` directories.
92      *
93      * @param string $dir The application's root directory.
94      * @param \Composer\IO\IOInterface $io IO interface to write to console.
95      * @return void
96      */
97     public static function createWritableDirectories($dir, $io)
98     {
99         $paths = [
100             'logs',
101             'tmp',
102             'tmp/cache',
103             'tmp/cache/models',
104             'tmp/cache/persistent',
105             'tmp/cache/views',
106             'tmp/sessions',
107             'tmp/tests'
108         ];
109
110         foreach ($paths as $path) {
111             $path = $dir . '/' . $path;
112             if (!file_exists($path)) {
113                 mkdir($path);
114                 $io->write('Created `' . $path . '` directory');
115             }
116         }
117     }
118
119     /**
120      * Set globally writable permissions on the "tmp" and "logs" directory.
121      *
122      * This is not the most secure default, but it gets people up and running quickly.
123      *
124      * @param string $dir The application's root directory.
125      * @param \Composer\IO\IOInterface $io IO interface to write to console.
126      * @return void
127      */
128     public static function setFolderPermissions($dir, $io)
129     {
130         // Change the permissions on a path and output the results.
131         $changePerms = function ($path, $perms, $io) {
132             // Get permission bits from stat(2) result.
133             $currentPerms = fileperms($path) & 0777;
134             if (($currentPerms & $perms) == $perms) {
135                 return;
136             }
137
138             $res = chmod($path, $currentPerms | $perms);
139             if ($res) {
140                 $io->write('Permissions set on ' . $path);
141             } else {
142                 $io->write('Failed to set permissions on ' . $path);
143             }
144         };
145
146         $walker = function ($dir, $perms, $io) use (&$walker, $changePerms) {
147             $files = array_diff(scandir($dir), ['.', '..']);
148             foreach ($files as $file) {
149                 $path = $dir . '/' . $file;
150
151                 if (!is_dir($path)) {
152                     continue;
153                 }
154
155                 $changePerms($path, $perms, $io);
156                 $walker($path, $perms, $io);
157             }
158         };
159
160         $worldWritable = bindec('0000000111');
161         $walker($dir . '/tmp', $worldWritable, $io);
162         $changePerms($dir . '/tmp', $worldWritable, $io);
163         $changePerms($dir . '/logs', $worldWritable, $io);
164     }
165
166     /**
167      * Set the security.salt value in the application's config file.
168      *
169      * @param string $dir The application's root directory.
170      * @param \Composer\IO\IOInterface $io IO interface to write to console.
171      * @return void
172      */
173     public static function setSecuritySalt($dir, $io)
174     {
175         $config = $dir . '/config/app.php';
176         $content = file_get_contents($config);
177
178         $newKey = hash('sha256', Security::randomBytes(64));
179         $content = str_replace('__SALT__', $newKey, $content, $count);
180
181         if ($count == 0) {
182             $io->write('No Security.salt placeholder to replace.');
183
184             return;
185         }
186
187         $result = file_put_contents($config, $content);
188         if ($result) {
189             $io->write('Updated Security.salt value in config/app.php');
190
191             return;
192         }
193         $io->write('Unable to update Security.salt value.');
194     }
195 }