22
33namespace  MaplePHP \Prompts ;
44
5+ use  Exception ;
6+ use  MaplePHP \Http \Interfaces \StreamInterface ;
57use  MaplePHP \Http \Stream ;
6- //use MaplePHP\Prompts\SttyWrapper; 
7- //use MaplePHP\Prompts\Ansi; 
8- //use MaplePHP\Prompts\Navigation; 
98use  InvalidArgumentException ;
109
1110/** 
1413 */ 
1514class  Command
1615{
17-     private  Stream   $ stream ;
16+     private  StreamInterface   $ stream ;
1817    private  SttyWrapper   $ stty ;
1918    private  Ansi   $ ansi ;
2019
21-     public  function  __construct ()
20+     public  function  __construct (? StreamInterface   $ stream  =  null )
2221    {
23-         $ this  ->stream  = new  Stream (Stream::STDOUT );
22+         // This is the stream we want to use, 9/10 times 
23+         $ this  ->stream  = is_null ($ stream ) ? new  Stream (Stream::STDOUT ) : $ stream ;
2424        $ this  ->stty  = new  SttyWrapper ();
2525        $ this  ->ansi  = new  Ansi ();
2626    }
2727
2828    /** 
2929     * Get stream 
30-      *   
31-      * @return Stream  
30+      * 
31+      * @return StreamInterface  
3232     */ 
33-     public  function  getStream (): Stream 
33+     public  function  getStream (): StreamInterface 
3434    {
3535        return  $ this  ->stream ;
3636    }
3737
3838    /** 
3939     * Get SttyWrapper 
40-      *   
40+      * 
4141     * @return SttyWrapper 
4242     */ 
4343    public  function  getStty (): SttyWrapper 
@@ -47,7 +47,7 @@ public function getStty(): SttyWrapper
4747
4848    /** 
4949     * Get Ansi 
50-      *   
50+      * 
5151     * @return Ansi 
5252     */ 
5353    public  function  getAnsi (): Ansi 
@@ -57,7 +57,7 @@ public function getAnsi(): Ansi
5757
5858    /** 
5959     * Read line 
60-      *   
60+      * 
6161     * @param string $message 
6262     * @return string 
6363     */ 
@@ -68,12 +68,12 @@ public function readline(string $message): string
6868        }
6969
7070        $ this  ->stream ->write ("$ message:  " );
71-         return  $ this  ->stream ->getLine ();
71+         return  ( string ) $ this  ->stream ->getLine ();
7272    }
7373
7474    /** 
7575     * Display a message 
76-      *   
76+      * 
7777     * @param string $message 
7878     * @param bool $getLine Stop and get line 
7979     * @return string|false 
@@ -146,24 +146,25 @@ public function error(string $message, bool $break = true): string|false
146146     */ 
147147    public  function  list (string  $ message ): array 
148148    {
149-         $ line  = $ this  ->message ("$ message (comma separate) " , true );
149+         $ line  = ( string ) $ this  ->message ("$ message (comma separate) " , true );
150150        return  array_map ("trim " , explode (", " , $ line ));
151151    }
152152
153153    /** 
154154     * Display an interactive prompt with multiple options 
155155     * If interactive prompt is not supported, use "inputSelect" 
156-      *   
156+      * 
157157     * @param string $message 
158158     * @param array $items 
159159     * @return int|string 
160+      * @throws Exception 
160161     */ 
161162    public  function  select (string  $ message , array  $ items ): int |string 
162163    {
163164        if  ($ this  ->stty ->hasSttySupport ()) {
164165            $ command  = new  Navigation ($ this  );
165166            $ command ->setHelperText ($ command ::HELPER_TEXT );
166-             $ command ->navigation ($ message , $ items , function  ($ index , $ items ) {
167+             $ command ->navigation ($ message , $ items , function  (int   $ index ,  array  $ items ) {
167168                $ this  ->showMenu ($ index , $ items );
168169            });
169170            return  $ command ->getValue ();
@@ -173,7 +174,7 @@ public function select(string $message, array $items): int|string
173174
174175    /** 
175176     * Display a non-interactive prompt with multiple options 
176-      *   
177+      * 
177178     * @param string $message 
178179     * @param array $choices 
179180     * @return int|string 
@@ -191,7 +192,7 @@ public function inputSelect(string $message, array $choices): int|string
191192            $ this  ->message ($ this  ->getAnsi ()->style (["blue " , "bold " ], "$ int: " ) . "  $ value " );
192193            $ int ++;
193194        }
194-         $ line  = $ this  ->message ("Input your answer " , true );
195+         $ line  = ( int ) $ this  ->message ("Input your answer " , true );
195196        if  ($ line  > 0  && $ line  <= $ length ) {
196197            $ index  = $ line  - 1 ;
197198            $ values  = array_keys ($ choices );
@@ -202,17 +203,18 @@ public function inputSelect(string $message, array $choices): int|string
202203
203204    /** 
204205     * Interactive prompt, choose between yes or no 
205-      *   
206+      * 
206207     * @param string $message 
207208     * @return int|string 
209+      * @throws Exception 
208210     */ 
209211    public  function  toggle (string  $ message ): int |string 
210212    {
211213        if  ($ this  ->stty ->hasSttySupport ()) {
212214            $ items  = [1  => "Yes " , 0  => "No " ];
213215            $ command  = new  Navigation ($ this  );
214216            $ command ->setHelperText (Navigation::HELPER_TEXT );
215-             $ command ->navigation ($ message , $ items , function  ($ index , $ items ) {
217+             $ command ->navigation ($ message , $ items , function  (int   $ index ,  array  $ items ) {
216218                $ this  ->showMenu ($ index , $ items );
217219            });
218220            return  $ command ->getValue ();
@@ -222,14 +224,15 @@ public function toggle(string $message): int|string
222224
223225    /** 
224226     * Non-interactive prompt, choose between yes or no 
225-      *   
227+      * 
226228     * @param string $message 
227-      * @return string 
229+      * @return int|string 
230+      * @throws Exception 
228231     */ 
229-     public  function  inputToggle (string  $ message ): string 
232+     public  function  inputToggle (string  $ message ): int | string 
230233    {
231234        $ this  ->message ($ this  ->getAnsi ()->bold ($ message ));
232-         $ line  = strtolower ($ this  ->message ("Type 'yes' or 'no' " , true ));
235+         $ line  = strtolower (( string ) $ this  ->message ("Type 'yes' or 'no' " , true ));
233236
234237        if  ($ line  === "yes "  || $ line  === "no " ) {
235238            return  (int )($ line  === "yes " );
@@ -239,7 +242,7 @@ public function inputToggle(string $message): string
239242
240243    /** 
241244     * Get a masked input if supported, otherwise get unmasked input 
242-      *   
245+      * 
243246     * @param string $message 
244247     * @return string 
245248     */ 
@@ -252,26 +255,26 @@ public function mask(string $message): string
252255                // Not yet tested. But should work if my research is right 
253256                $ input  = rtrim ((string )exec ("powershell -Command  \$input = Read-Host -AsSecureString; [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR( \$input)) " ));
254257            } else  {
255-                 $ input  = rtrim (exec ($ this  ->stty ->maskInput ()));
258+                 $ input  = rtrim (( string ) exec (( string ) $ this  ->stty ->maskInput ()));
256259            }
257260            $ this  ->stream ->write ("\n" );
258261            //ob_get_clean(); 
259262            return  $ input ;
260263        }
261264        $ this  ->message ("Warning: The input will not be masked. The PHP function  \"system \" is disabled. " );
262-         return  $ this  ->message ($ message , true );
265+         return  ( string ) $ this  ->message ($ message , true );
263266    }
264267
265268    /** 
266269     * Display a confirmation prompt 
267-      *   
270+      * 
268271     * @param string $message 
269272     * @return bool 
270273     */ 
271274    public  function  confirm (string  $ message ): bool 
272275    {
273276        $ this  ->message ($ this  ->getAnsi ()->style (["yellow " , "bold " ], $ message ));
274-         $ line  = trim (strtolower ($ this  ->message ("Type 'yes' to continue and 'no' to abort' " , true )));
277+         $ line  = trim (strtolower (( string ) $ this  ->message ("Type 'yes' to continue and 'no' to abort' " , true )));
275278
276279        if  ($ line  === "yes " ) {
277280            return  true ;
@@ -280,10 +283,10 @@ public function confirm(string $message): bool
280283        }
281284        return  $ this  ->confirm ($ message );
282285    }
283-      
286+ 
284287    /** 
285288     * Create a progress bar 
286-      *   
289+      * 
287290     * @param int $expectedRows The maximum expected rows 
288291     * @param int $maxLength The maximum bar length 
289292     * @param int|callable|null $sleep int for sleep in milliseconds (3000 ms = 1 second) or callback with returned int for sleep in milliseconds 
@@ -300,7 +303,7 @@ public function progress(int $expectedRows, int $maxLength = 100, null|int|calla
300303            if  (is_callable ($ sleep )) {
301304                $ sleep  = $ sleep ($ i , $ length );
302305            }
303-             if  (is_int ($ sleep )) {
306+             if  (is_int ($ sleep ) &&  $ sleep  >=  0 ) {
304307                usleep ($ sleep  * 1000 );
305308            }
306309            $ this  ->stream ->write ($ this  ->progAppear ($ char , $ i , $ length ));
@@ -311,7 +314,7 @@ public function progress(int $expectedRows, int $maxLength = 100, null|int|calla
311314
312315    /** 
313316     * Progress appearance 
314-      *   
317+      * 
315318     * @param string $char 
316319     * @param float $i 
317320     * @param float $length 
@@ -330,16 +333,17 @@ private function progAppear(string $char, float $i, float $length): string
330333
331334    /** 
332335     * Show interactive menu 
333-      *   
336+      * 
334337     * @param int $selIndex 
335338     * @param array $items 
336339     * @return void 
340+      * @throws Exception 
337341     */ 
338342    protected  function  showMenu (int  $ selIndex , array  $ items ): void 
339343    {
340344        foreach  ($ items  as  $ index  => $ item ) {
341345            if  ($ index  === $ selIndex ) {
342-                 $ this  ->stream ->write ("[ "  . $ this  ->ansi ->style (["blue " ], $ this  ->ansi ->checkbox ()) . "]  "  . $ this  ->ansi ->selectedItem ($ item ) . "\n" );
346+                 $ this  ->stream ->write ("[ "  . $ this  ->ansi ->style (["blue " ], $ this  ->ansi ->checkbox ()) . "]  "  . $ this  ->ansi ->selectedItem (( string ) $ item ) . "\n" );
343347            } else  {
344348                $ this  ->stream ->write ("[ ]  $ item \n" );
345349            }
0 commit comments