1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Tamedevelopers \Support \Capsule ;
6+
7+ use Tamedevelopers \Support \Env ;
8+ use Tamedevelopers \Support \Str ;
9+ use Tamedevelopers \Support \Constant ;
10+ use Tamedevelopers \Support \Capsule \Logger ;
11+
12+
13+ class CommandHelper
14+ {
15+ /**
16+ * The database connector instance.
17+ * @var \Tamedevelopers\Database\Connectors\Connector|null
18+ */
19+ protected $ conn ;
20+
21+ /**
22+ * Constructor
23+ * @param \Tamedevelopers\Database\Connectors\Connector|null $conn
24+ */
25+ public function __construct ($ conn = null )
26+ {
27+ $ this ->conn = $ conn ;
28+ }
29+
30+ /**
31+ * Check if database connection is successful.
32+ * @param \Tamedevelopers\Database\Connectors\Connector $conn
33+ */
34+ protected function checkConnection ($ conn ): void
35+ {
36+ $ checkConnection = $ conn ->dbConnection ();
37+
38+ if ($ checkConnection ['status ' ] != Constant::STATUS_200 ){
39+ $ this ->error ($ checkConnection ['message ' ]);
40+ exit ();
41+ }
42+ }
43+
44+ /**
45+ * Check if the command should be forced when running in production.
46+ */
47+ protected function forceChecker ($ options = []): void
48+ {
49+ $ force = isset ($ options ['force ' ]) || isset ($ options ['f ' ]);
50+
51+ if ($ this ->isProductionEnv ()) {
52+ if (!$ force ) {
53+ $ this ->error ("You are in production! Use [--force|-f] flag, to run this command. " );
54+ exit (1 );
55+ }
56+ }
57+ }
58+
59+ /**
60+ * Extracts the flag types from option keys like "drop-types" or "drop-views".
61+ */
62+ protected function getFlagTypes ($ options = []): array
63+ {
64+ $ types = [];
65+ foreach ($ options as $ key => $ value ) {
66+ if (strpos ($ key , 'drop- ' ) === 0 && $ value ) {
67+ $ types [] = substr ($ key , strlen ('drop- ' )); // get the part after "drop-"
68+ }
69+ }
70+ return $ types ;
71+ }
72+
73+ /**
74+ * Determine if the current environment is production.
75+ */
76+ protected function isProductionEnv (): bool
77+ {
78+ $ env = Env::env ('APP_ENV ' );
79+ $ productionAliases = ['prod ' , 'production ' , 'live ' ];
80+
81+ return in_array (Str::lower ($ env ), $ productionAliases , true );
82+ }
83+
84+ /**
85+ * Get a specific option value from options array.
86+ * Example: getOption($options, 'force', false)
87+ */
88+ protected function getOption (array $ options , string $ key , $ default = null )
89+ {
90+ return $ options [$ key ] ?? $ default ;
91+ }
92+
93+ /**
94+ * Check if an option/flag exists and is truthy.
95+ */
96+ protected function hasOption (array $ options , string $ key ): bool
97+ {
98+ return !empty ($ options [$ key ]);
99+ }
100+
101+ /**
102+ * Prompt the user for confirmation (y/n).
103+ */
104+ protected function confirm (string $ question , bool $ default = false ): bool
105+ {
106+ $ yesNo = $ default ? 'Y/n ' : 'y/N ' ;
107+ $ answer = readline ("{$ question } [ {$ yesNo }]: " );
108+
109+ if (empty ($ answer )) {
110+ return $ default ;
111+ }
112+
113+ return in_array (Str::lower ($ answer ), ['y ' , 'yes ' ], true );
114+ }
115+
116+ /**
117+ * Prompt the user for free text input.
118+ */
119+ protected function ask (string $ question , string $ default = '' ): string
120+ {
121+ $ answer = readline ("{$ question } " );
122+ return $ answer !== '' ? $ answer : $ default ;
123+ }
124+
125+ /**
126+ * Display a simple progress bar.
127+ * This implementation writes directly to STDOUT using a carriage return (\r),
128+ * which updates the same line reliably in Windows CMD and Unix terminals.
129+ */
130+ protected function progressBar (callable $ callback , int $ total = 1 , int $ barWidth = 50 ): void
131+ {
132+ $ completed = 0 ;
133+
134+ // Writer compatible with CMD: use STDOUT + fflush, fallback to echo.
135+ $ write = static function (string $ text ): void {
136+ if (defined ('STDOUT ' )) {
137+ fwrite (STDOUT , $ text );
138+ fflush (STDOUT );
139+ } else {
140+ echo $ text ;
141+ }
142+ };
143+
144+ $ draw = static function (int $ completed , int $ total , int $ barWidth , callable $ write ): void {
145+ $ safeTotal = max (1 , $ total );
146+ $ percent = (int ) floor (($ completed / $ safeTotal ) * 100 );
147+ if ($ percent > 100 ) {
148+ $ percent = 100 ;
149+ }
150+ $ filled = (int ) floor (($ percent / 100 ) * $ barWidth );
151+ $ empty = max (0 , $ barWidth - $ filled );
152+ $ write ("\r[ " . str_repeat ('# ' , $ filled ) . str_repeat ('- ' , $ empty ) . " ] {$ percent }% " );
153+ };
154+
155+ // Initial draw (0%)
156+ $ draw (0 , $ total , $ barWidth , $ write );
157+
158+ // $report closure to update the bar after each unit of work
159+ $ report = function () use (&$ completed , $ total , $ barWidth , $ write , $ draw ) {
160+ $ completed ++;
161+ $ draw ($ completed , $ total , $ barWidth , $ write );
162+ };
163+
164+ try {
165+ // execute the callback and pass the $report closure
166+ $ callback ($ report );
167+ } finally {
168+ // Finish the line
169+ $ write (PHP_EOL );
170+ }
171+ }
172+
173+ /**
174+ * Write an info message.
175+ */
176+ protected function info (string $ message ): void
177+ {
178+ Logger::info ($ message . "\n" );
179+ }
180+
181+ /**
182+ * Write a success message.
183+ */
184+ protected function success (string $ message ): void
185+ {
186+ Logger::success ($ message . "\n" );
187+ }
188+
189+ /**
190+ * Write a warning message.
191+ */
192+ protected function warning (string $ message ): void
193+ {
194+ Logger::writeln ("<warning> {$ message }</warning> " );
195+ }
196+
197+ /**
198+ * Write an error message.
199+ */
200+ protected function error (string $ message ): void
201+ {
202+ Logger::error ($ message . "\n" );
203+ }
204+
205+ }
0 commit comments