This episode is about adding helper methods to the form function to call prompts directly instead of through a callback.
The approach is: alter one test to use the desired methods (which don’t exist yet), see it fail, do a quick&dirty code change to see it go back to green.
The initial implementation uses the magic __call method inside FormBuilder
like this:
1public function __call(string $prompt, array $arguments) 2{ 3 $prompt = "\\Laravel\\Prompts\\{$prompt}"; 4 5 if(! function_exists($prompt)) { 6 throw new BadFunctionCallException("The prompt [{$prompt}] does not exist."); 7 } 8 9 return $this->add(function () use ($prompt, $arguments) {10 return $prompt(...$arguments);11 });12}
The flaw of the implementation above is that we don’t have IDE support for any of the form methods (text, select, etc).
To get around it there are a couple options:
use class annotation to list the methods available similarly to how is done with facades
actually implement the methods and wrap them around the _call() method
The second option is the one chosen as the first one doesn’t seem to save much of the work anyway.
Turns out that implementation is pretty simple:
1public function intro(string $message): self 2{ 3 return $this->callPrompt("\\Laravel\\Prompts\\intro", get_defined_vars()); 4} 5 6protected function callPrompt(string $prompt, array $arguments): self 7{ 8 if(! function_exists($prompt)) { 9 throw new BadFunctionCallException("The prompt [{$prompt}] does not exist.");10 }11 12 return $this->add(function () use ($prompt, $arguments) {13 return $prompt(...$arguments);14 });15}16 17public function __call(string $prompt, array $arguments)18{19 $prompt = "\\Laravel\\Prompts\\{$prompt}";20 21 return $this->callPrompt($prompt, $arguments);22}
Bonus from this lesson is how to squash all the WIP commits created along the way. I do use WIP commits a lot, so this is a card I’ll play soon on my projects.
get the commit hash of the first WIP commit
git reset —soft <hash>
this un-dos all the changes locally, but because of the
—soft
flag, all changes to the files are still present
git add . && git commit -m “some meaningful message“
git push -f