Skip to content

Commit 8c29f72

Browse files
committed
Sync Installer with the example cake app
Ref: https://github.com/cakephp/app/blob/5.x/src/Console/Installer.php
1 parent 61dc7e7 commit 8c29f72

2 files changed

Lines changed: 80 additions & 72 deletions

File tree

phpstan-baseline.neon

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
parameters:
22
ignoreErrors:
3-
-
4-
message: '#^Parameter \#3 \$subject of function str_replace expects array\<string\>\|string, string\|false given\.$#'
5-
identifier: argument.type
6-
count: 2
7-
path: src/Console/Installer.php
8-
93
-
104
message: '#^Method App\\Controller\\Component\\GithubApiComponent\:\:apiRequest\(\) has parameter \$data with no value type specified in iterable type array\.$#'
115
identifier: missingType.iterableValue

src/Console/Installer.php

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?php
2+
declare(strict_types=1);
3+
24
/**
35
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
46
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
@@ -14,25 +16,28 @@
1416
*/
1517
namespace App\Console;
1618

17-
if (! defined('STDIN')) {
19+
if (!defined('STDIN')) {
1820
define('STDIN', fopen('php://stdin', 'r'));
1921
}
2022

23+
use Cake\Codeception\Console\Installer as CodeceptionInstaller;
2124
use Cake\Utility\Security;
25+
use Composer\IO\IOInterface;
2226
use Composer\Script\Event;
2327
use Exception;
2428

2529
/**
26-
* Provides installation hooks for when this application is installed via
30+
* Provides installation hooks for when this application is installed through
2731
* composer. Customize this class to suit your needs.
2832
*/
2933
class Installer
3034
{
31-
3235
/**
3336
* An array of directories to be made writable
37+
*
38+
* @var list<string>
3439
*/
35-
const WRITABLE_DIRS = [
40+
public const WRITABLE_DIRS = [
3641
'logs',
3742
'tmp',
3843
'tmp/cache',
@@ -50,74 +55,52 @@ class Installer
5055
* @throws \Exception Exception raised by validator.
5156
* @return void
5257
*/
53-
public static function postInstall(Event $event)
58+
public static function postInstall(Event $event): void
5459
{
5560
$io = $event->getIO();
5661

57-
$rootDir = dirname(dirname(__DIR__));
62+
$rootDir = dirname(__DIR__, 2);
5863

59-
static::createAppConfig($rootDir, $io);
64+
static::createAppLocalConfig($rootDir, $io);
6065
static::createWritableDirectories($rootDir, $io);
6166

62-
// ask if the permissions should be changed
63-
if ($io->isInteractive()) {
64-
$validator = function ($arg) {
65-
if (in_array($arg, ['Y', 'y', 'N', 'n'])) {
66-
return $arg;
67-
}
68-
throw new Exception('This is not a valid answer. Please choose Y or n.');
69-
};
70-
$setFolderPermissions = $io->askAndValidate(
71-
'<info>Set Folder Permissions ? (Default to Y)</info> [<comment>Y,n</comment>]? ',
72-
$validator,
73-
10,
74-
'Y'
75-
);
76-
77-
if (in_array($setFolderPermissions, ['Y', 'y'])) {
78-
static::setFolderPermissions($rootDir, $io);
79-
}
80-
} else {
81-
static::setFolderPermissions($rootDir, $io);
82-
}
83-
67+
static::setFolderPermissions($rootDir, $io);
8468
static::setSecuritySalt($rootDir, $io);
8569

86-
$class = 'Cake\Codeception\Console\Installer';
87-
if (class_exists($class)) {
88-
$class::customizeCodeceptionBinary($event);
70+
if (class_exists(CodeceptionInstaller::class)) {
71+
CodeceptionInstaller::customizeCodeceptionBinary($event);
8972
}
9073
}
9174

9275
/**
93-
* Create the config/app.php file if it does not exist.
76+
* Create config/app_local.php file if it does not exist.
9477
*
95-
* @param string $dir The application's root directory.
96-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
78+
* @param string $dir The application's root directory.
79+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
9780
* @return void
9881
*/
99-
public static function createAppConfig($dir, $io)
82+
public static function createAppLocalConfig(string $dir, IOInterface $io): void
10083
{
101-
$appConfig = $dir . '/config/app.php';
102-
$defaultConfig = $dir . '/config/app.default.php';
103-
if (! file_exists($appConfig)) {
104-
copy($defaultConfig, $appConfig);
105-
$io->write('Created `config/app.php` file');
84+
$appLocalConfig = $dir . '/config/app_local.php';
85+
$appLocalConfigTemplate = $dir . '/config/app_local.example.php';
86+
if (!file_exists($appLocalConfig)) {
87+
copy($appLocalConfigTemplate, $appLocalConfig);
88+
$io->write('Created `config/app_local.php` file');
10689
}
10790
}
10891

10992
/**
11093
* Create the `logs` and `tmp` directories.
11194
*
112-
* @param string $dir The application's root directory.
113-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
95+
* @param string $dir The application's root directory.
96+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
11497
* @return void
11598
*/
116-
public static function createWritableDirectories($dir, $io)
99+
public static function createWritableDirectories(string $dir, IOInterface $io): void
117100
{
118101
foreach (static::WRITABLE_DIRS as $path) {
119102
$path = $dir . '/' . $path;
120-
if (! file_exists($path)) {
103+
if (!file_exists($path)) {
121104
mkdir($path);
122105
$io->write('Created `' . $path . '` directory');
123106
}
@@ -129,14 +112,34 @@ public static function createWritableDirectories($dir, $io)
129112
*
130113
* This is not the most secure default, but it gets people up and running quickly.
131114
*
132-
* @param string $dir The application's root directory.
133-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
115+
* @param string $dir The application's root directory.
116+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
134117
* @return void
135118
*/
136-
public static function setFolderPermissions($dir, $io)
119+
public static function setFolderPermissions(string $dir, IOInterface $io): void
137120
{
121+
// ask if the permissions should be changed
122+
if ($io->isInteractive()) {
123+
$validator = function (string $arg): string {
124+
if (in_array($arg, ['Y', 'y', 'N', 'n'])) {
125+
return $arg;
126+
}
127+
throw new Exception('This is not a valid answer. Please choose Y or n.');
128+
};
129+
$setFolderPermissions = $io->askAndValidate(
130+
'<info>Set Folder Permissions ? (Default to Y)</info> [<comment>Y,n</comment>]? ',
131+
$validator,
132+
10,
133+
'Y',
134+
);
135+
136+
if (in_array($setFolderPermissions, ['n', 'N'])) {
137+
return;
138+
}
139+
}
140+
138141
// Change the permissions on a path and output the results.
139-
$changePerms = function ($path) use ($io) {
142+
$changePerms = function (string $path) use ($io): void {
140143
$currentPerms = fileperms($path) & 0777;
141144
$worldWritable = $currentPerms | 0007;
142145
if ($worldWritable == $currentPerms) {
@@ -151,12 +154,12 @@ public static function setFolderPermissions($dir, $io)
151154
}
152155
};
153156

154-
$walker = function ($dir) use (&$walker, $changePerms) {
155-
$files = array_diff(scandir($dir), ['.', '..']);
157+
$walker = function (string $dir) use (&$walker, $changePerms): void {
158+
$files = array_diff(scandir($dir) ?: [], ['.', '..']);
156159
foreach ($files as $file) {
157160
$path = $dir . '/' . $file;
158161

159-
if (! is_dir($path)) {
162+
if (!is_dir($path)) {
160163
continue;
161164
}
162165

@@ -173,29 +176,34 @@ public static function setFolderPermissions($dir, $io)
173176
/**
174177
* Set the security.salt value in the application's config file.
175178
*
176-
* @param string $dir The application's root directory.
177-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
179+
* @param string $dir The application's root directory.
180+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
178181
* @return void
179182
*/
180-
public static function setSecuritySalt($dir, $io)
183+
public static function setSecuritySalt(string $dir, IOInterface $io): void
181184
{
182185
$newKey = hash('sha256', Security::randomBytes(64));
183-
static::setSecuritySaltInFile($dir, $io, $newKey, 'app.php');
186+
static::setSecuritySaltInFile($dir, $io, $newKey, 'app_local.php');
184187
}
185188

186189
/**
187190
* Set the security.salt value in a given file
188191
*
189-
* @param string $dir The application's root directory.
190-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
191-
* @param string $newKey key to set in the file
192-
* @param string $file A path to a file relative to the application's root
192+
* @param string $dir The application's root directory.
193+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
194+
* @param string $newKey key to set in the file
195+
* @param string $file A path to a file relative to the application's root
193196
* @return void
194197
*/
195-
public static function setSecuritySaltInFile($dir, $io, $newKey, $file)
198+
public static function setSecuritySaltInFile(string $dir, IOInterface $io, string $newKey, string $file): void
196199
{
197200
$config = $dir . '/config/' . $file;
198201
$content = file_get_contents($config);
202+
if ($content === false) {
203+
$io->write('Config file not readable or not found: config/' . $file);
204+
205+
return;
206+
}
199207

200208
$content = str_replace('__SALT__', $newKey, $content, $count);
201209

@@ -217,16 +225,22 @@ public static function setSecuritySaltInFile($dir, $io, $newKey, $file)
217225
/**
218226
* Set the APP_NAME value in a given file
219227
*
220-
* @param string $dir The application's root directory.
221-
* @param \Composer\IO\IOInterface $io IO interface to write to console.
222-
* @param string $appName app name to set in the file
223-
* @param string $file A path to a file relative to the application's root
228+
* @param string $dir The application's root directory.
229+
* @param \Composer\IO\IOInterface $io IO interface to write to console.
230+
* @param string $appName app name to set in the file
231+
* @param string $file A path to a file relative to the application's root
224232
* @return void
225233
*/
226-
public static function setAppNameInFile($dir, $io, $appName, $file)
234+
public static function setAppNameInFile(string $dir, IOInterface $io, string $appName, string $file): void
227235
{
228236
$config = $dir . '/config/' . $file;
229237
$content = file_get_contents($config);
238+
if ($content === false) {
239+
$io->write('Config file not readable or not found: config/' . $file);
240+
241+
return;
242+
}
243+
230244
$content = str_replace('__APP_NAME__', $appName, $content, $count);
231245

232246
if ($count == 0) {

0 commit comments

Comments
 (0)