-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomposer_script.php
More file actions
203 lines (170 loc) · 7.1 KB
/
Copy pathcomposer_script.php
File metadata and controls
203 lines (170 loc) · 7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
use Composer\Script\Event;
use Composer\Util\HttpDownloader;
/**
* One-off Composer script helper for GridPHP demo project.
* Loaded via "classmap" autoload (see composer.json), no namespace,
* so it can live standalone at the project root.
*
* NOTE: cleanup() deletes this file. Only wire cleanup() into
* post-create-project-cmd (a one-time event), never into
* post-install-cmd / post-update-cmd, or later `composer update`
* runs will fail trying to call a class that no longer exists.
*/
class ComposerScript
{
private const FILES_TO_FETCH = [
'https://www.gridphp.com/secure/free/jqgrid_dist.phps' => __DIR__ . '/lib/inc/jqgrid_dist.php',
'https://www.gridphp.com/secure/free/ai_grid.phps' => __DIR__ . '/lib/inc/ai/ai_grid.php',
];
private const CONFIG_SAMPLE = __DIR__ . '/config.sample.php';
private const CONFIG_TARGET = __DIR__ . '/config.php';
/**
* Fetch all registered remote files over HTTP using Composer's Downloader.
*/
public static function fetchCoreFiles(Event $event): void
{
$io = $event->getIO();
try {
$downloader = new HttpDownloader($io, $event->getComposer()->getConfig());
} catch (\Exception $e) {
$io->writeError('<error>GridPHP: failed to initialize downloader - ' . $e->getMessage() . '</error>');
exit(1);
}
foreach (self::FILES_TO_FETCH as $remoteUrl => $targetPath) {
try {
$content = $downloader->get($remoteUrl)->getBody();
} catch (\Exception $e) {
$io->writeError("<error>GridPHP: failed to fetch file from $remoteUrl - " . $e->getMessage() . "</error>");
exit(1);
}
if ($content === null || trim($content) === '') {
$io->writeError("<error>GridPHP: empty response returned from $remoteUrl</error>");
exit(1);
}
// Ensure destination directory structure exists (e.g., /lib/inc/ai/)
$directory = dirname($targetPath);
if (!is_dir($directory)) {
if (!@mkdir($directory, 0755, true) && !is_dir($directory)) {
$io->writeError("<error>GridPHP: failed to create directory: $directory</error>");
return;
}
}
// Write content to target file
$bytes = @file_put_contents($targetPath, $content);
if ($bytes === false || $bytes !== strlen($content)) {
$io->writeError("<error>GridPHP: could not write file to $targetPath</error>");
return;
}
@chmod($targetPath, 0644);
}
$io->write("<info>GridPHP: core libs successfully installed.</info>");
}
/**
* Give the sample-db folder + file write access so the web server
* (whatever user it runs as) can create/write the SQLite database.
*/
public static function fixDbPermissions($io): void
{
$dbDir = __DIR__ . '/demos/sample-db';
$dbFile = $dbDir . '/database.db';
if (!is_dir($dbDir)) {
$io->writeError('<error>GridPHP: ' . $dbDir . ' does not exist, skipping permission fix.</error>');
return;
}
@chmod($dbDir, 0777);
if (file_exists($dbFile)) {
@chmod($dbFile, 0666);
}
$io->write('<info>GridPHP: demos/sample-db permissions set for write access.</info>');
}
/**
* Detect SQLite support, rename config.sample.php -> config.php,
* and swap in SQLite connection placeholders.
*/
public static function setupConfig(Event $event): void
{
$io = $event->getIO();
$hasSqlite = extension_loaded('pdo_sqlite') || extension_loaded('sqlite3');
if ($hasSqlite) {
if (!file_exists(self::CONFIG_SAMPLE)) {
$io->writeError('<error>GridPHP: ' . self::CONFIG_SAMPLE . ' not found, skipping config setup.</error>');
return;
}
if (file_exists(self::CONFIG_TARGET)) {
$io->write('<comment>GridPHP: config.php already exists, leaving it untouched.</comment>');
return;
}
$contents = file_get_contents(self::CONFIG_SAMPLE);
if ($contents === false) {
$io->writeError('<error>GridPHP: could not read config.sample.php</error>');
return;
}
$replacements = [
'{{dbtype}}' => 'sqlite3',
'"{{dbhost}}"' => "dirname(__FILE__).'/demos/sample-db/database.db'",
'{{dbuser}}' => '',
'{{dbpass}}' => '',
'{{dbname}}' => '',
'{{apikey}}' => '',
];
$contents = strtr($contents, $replacements);
$bytes = @file_put_contents(self::CONFIG_TARGET, $contents);
if ($bytes === false) {
$io->writeError('<error>GridPHP: could not write config.php</error>');
return;
}
@chmod(self::CONFIG_TARGET, 0644);
$io->write('<info>GridPHP: config.php created with SQLite defaults.</info>');
// fix db permissions
self::fixDbPermissions($io);
}
}
/**
* Print a success banner after `composer create-project` finishes.
* PHP re-implementation of the shell one-liner, kept as a script method
* so it's portable across OSes without relying on `@php -r '...'`.
*/
public static function showSuccessBanner(Event $event): void
{
$isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
$fg = $isWindows ? '' : "\033[37m";
$bg = $isWindows ? '' : "\033[44m";
$rs = $isWindows ? '' : "\033[0m";
$title = 'GridPHP Demos Installed Successfully!';
$lines = [
'To view all interactive demos locally, execute:',
'',
'👉 php -S localhost:8000',
'',
'Then open your browser and navigate to http://localhost:8000',
];
$width = mb_strlen($title) + 4;
foreach ($lines as $line) {
$width = max($width, mb_strlen($line) + 2);
}
$bannerText = ' ' . $title . ' ';
$padded = str_pad($bannerText, $width, ' ', STR_PAD_BOTH);
echo "\n" . $fg . $bg . $padded . $rs . "\n\n";
foreach ($lines as $line) {
echo ' ' . $line . "\n";
}
echo "\n";
}
/**
* Remove this helper script once initial project setup is complete.
* Intended for post-create-project-cmd ONLY (a one-time event) —
* do not attach to post-install-cmd/post-update-cmd, since a future
* `composer update` would then fail looking for a deleted class.
*/
public static function cleanup(Event $event): void
{
$io = $event->getIO();
$self = __FILE__;
if (@unlink($self)) {
$io->write('<info>GridPHP: removed composer_script.php (setup complete).</info>');
} else {
$io->writeError('<comment>GridPHP: could not remove composer_script.php automatically, you can delete it manually.</comment>');
}
}
}