Created
November 19, 2012 15:12
-
-
Save RafaelKa/4111197 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace ......; | |
/* * | |
* This script belongs to the TYPO3 Flow package '........'. * | |
* * | |
* */ | |
use TYPO3\Flow\Annotations as Flow; | |
/** | |
* ConfirmationDialog command controller for the Train2Web.Core package | |
* @todo ANSI FOREGROUNDS and BLINK & co. | |
* @Flow\Scope("singleton") | |
*/ | |
class ConfirmationDialogCommandController extends \TYPO3\Flow\Cli\CommandController { | |
/** | |
* Constants for anwer pattern | |
*/ | |
const PATTERN_USER_INPUT_YES = '/^(y|yes|j|ja|si)$/i'; | |
const PATTERN_USER_INPUT_NO = '/^(n|no|nein)$/i'; | |
const PATTERN_USER_INPUT_CANCEL = '/^(c|cancel|abort|abbrechen|abortire|abortar)$/i'; | |
/** | |
* A simpliest example for confirm dialog | |
* | |
* if (user puts yes) {do something} else { do something else } | |
* also if user puts n, no, c, cancel then is it else | |
* | |
* @return void | |
*/ | |
public function exampleCommand() { | |
if ($this->confirmDialog()) { | |
echo "I will continue.".PHP_EOL; | |
} else { | |
echo "I will not continue.".PHP_EOL; | |
} | |
} | |
/** | |
* A simple example confirm dialog with cancel | |
* | |
* Please note that switch case provide == comparison and not === <br> | |
* also if you use == instead of === you can't differentiate between no and cancel!!! | |
* | |
* @return void | |
*/ | |
public function example2Command() { | |
$usersChoice = $this->confirmDialog(); | |
if ($usersChoice) { | |
echo 'You typed "yes"!'.PHP_EOL; | |
} else if ($usersChoice === NULL) { | |
echo 'You typed "cancel"!'.PHP_EOL; | |
} else if ($usersChoice === FALSE) { | |
echo 'You typed "no"!'.PHP_EOL; | |
} | |
} | |
/** | |
* An example confirm dialog with $optionalSettings[], answer depends messages and callbacks | |
* | |
* Please note that $optionalSettings['*'] - array has priority | |
* | |
* @return void | |
*/ | |
public function demoCommand() { | |
$settings = array( | |
'confirmationMessage' => 'Please put "y" or "n" or "c" or nothing to use "%1$s" and press enter: ', | |
'standardAnswer' => 'yes', | |
'messageByYes' => 'You typed "%2$s", i will run one callback for "AGREEMENT" but only if it is declared!', | |
'messageByNo' => 'You typed "%2$s", i will run one callback for "REJECTION" but only if it is declared!', | |
'messageByCancel' => 'You typed "%2$s", i will run one callback for "RESET" but only if it is declared!', | |
'messageByWrongInput' => 'Wrong input; "%2$s"!!!'.PHP_EOL.'You will be asked for so long, until correct entry is detected.', | |
'callBackByYes' => array(array($this, 'callBackForYes'), array()), | |
'callBackByNo' => array(array($this, 'callBackForNo'), array()), | |
'callBackByCancel' => array(array($this, 'callBackForCancel'), array()), | |
'callBackByWrongInput' => array(array($this, 'callBackForWrongInput'), array()) | |
); | |
$this->confirmDialog('This message will be overwritten if $optionalSettings[\'confirmationMessage\'] is set.', 'NO', $settings); | |
} | |
/** | |
* An example <b>DEMO for callbacks returnvalue</b> based on <b>confirmationdialog:demo</b> | |
* | |
* | |
* Please note that $optionalSettings['*'] - array has priority | |
* | |
* @return void | |
*/ | |
public function demo2Command() { | |
$settings = array( | |
'confirmationMessage' => 'Please put "y" or "n" or "c" or nothing to use "%1$s" and press enter: ', | |
'standardAnswer' => 'yes', | |
'messageByYes' => 'You typed "%2$s", i will run one callback for "AGREEMENT" but only if it is declared!', | |
'messageByNo' => 'You typed "%2$s", i will run one callback for "REJECTION" but only if it is declared!', | |
'messageByCancel' => 'You typed "%2$s", i will run one callback for "RESET" but only if it is declared!', | |
'callBackByYes' => array(array($this, 'callBackForYes'), array()), | |
'callBackByNo' => array(array($this, 'callBackForNo'), array()), | |
'callBackByCancel' => array(array($this, 'callBackForCancel'), array()), | |
'callBackByWrongInput' => array(array($this, 'callBackForWrongInput2'), array()) | |
); | |
$this->confirmDialog('This message will be overwritten if $optionalSettings[\'confirmationMessage\'] is set.', 'NO', $settings); | |
} | |
/** | |
* Shows confirmation message and reads users answer from command line. | |
* | |
* <b>WARNING: don't set anything if you do not want to use it, it will cause one error. <br> | |
* ALL PARAMETERS ARE OPTIONAL. <br> | |
* ATTENTION: all settings in array $optionalSettings have priority.</b><br> | |
* | |
* <b>$optionalSettings</b> = array (<br> | |
* <b>'confirmationMessage'</b> => 'You can use %1$s as placeholder for your "standardAnswer".',<br> | |
* <b>'standardAnswer'</b> => $standardAnswer,<br> | |
* <b>'messageByYes'</b> => 'You can use %2$s as placeholder for users input string.',<br> | |
* <b>'messageByNo'</b> => 'Please see "messageByYes".',<br> | |
* <b>'messageByCancel'</b> => 'Please see "messageByYes".',<br> | |
* <b>'messageByWrongInput'</b> => 'Please see "messageByYes".',<br> | |
* <b>'callBackByYes'</b> => array (array($object, 'functionName'), array($param1, $param2, 'otherParam')), // if your callback return one value then confirmDialog return this instead of standard return of confirmDialog<br> | |
* <b>'callBackByNo'</b> => '', // can also be emppty, confirmDialog will print messageBy{yes|no|cancel} and then returns standard value for this answer.<br> | |
* <b>'callBackByCancel'</b> => 'please see "callBackByYes" and "callBackByNo"',<br> | |
* <b>'callBackByWrongInput'</b> => 'please see "callBackByYes" and "callBackByNo"', // if return is void then : will ask for so long, until correct entry is detected.<br> | |
* <b>'infiniteLoopByWrongInput'</b> => TRUE, // if FALSE and callBackByWrongInput is void then throws \InvalidArgumentException with code 1352747275<br> | |
* <b>'vsprintfVars'</b> => array($your, $own, $vars) <br> | |
* ); | |
* | |
* @param string $confirmationMessage = <b>'Would you like to perform this command? [yes|no|cancel] [%1$s] : '</b> | |
* @param string $standardAnswer = <b>'no'</b> | |
* @param array $optionalSettings <b>have priority for $confirmationMessage and $standardAnswer</b> | |
* @return boolean|NULL|yourOwnType this function will return your own type if your callback returns one value and if not then callbackBy{<br>Yes returns <b>TRUE</b><br>No returns <b>FALSE</b><br>Cancel returns <b>NULL</b><br>WrongInput throws <b>\InvalidArgumentException</b><br>}. | |
* @throws \InvalidArgumentException (code: 1353073679) if this function will be called with wrong settings | |
*/ | |
protected function confirmDialog($confirmationMessage = 'Would you like to perform this command? [yes|no|cancel] [%1$s] : ', $standardAnswer = 'no', array $optionalSettings = NULL){ | |
// search patterns | |
//| prepare and set $optionalSettings | |
//| | |
//|// set needed DEFAULTSETTINGS -> can be overwritten with array $optionalSettings | |
$defaultSettings = array( | |
'confirmationMessage' => $confirmationMessage, | |
'standardAnswer' => $standardAnswer, | |
// by infiniteLoopByWrongInput == TRUE prints messageByWrongInput | |
'messageByWrongInput' => 'Wrong input: %2$s', | |
'callBackByWrongInput' => '', | |
// set to TRUE to prevent \InvalidArgumentException by wrong input -> will cause infinite loop to the same confirm dialog. Prints "Wrong input: %3$s" and confirmationMessage again | |
'infiniteLoopByWrongInput' => TRUE, | |
'vsprintfVars' => array ( | |
$standardAnswer, | |
'' // placeholder for current users input, can be used in 'wrongInputMessage' | |
) | |
); | |
//|//| overwrite DEFAULTSETTINGS with users SETTINGS if nacessary ($optionalSettings) | |
if ($optionalSettings === NULL) { | |
$settings = $defaultSettings; | |
} else { | |
$settings = array_merge($defaultSettings, $optionalSettings); | |
//|//|//| set 'vsprintfVars' properly -> this will force priority for entire settings array | |
if (!empty($optionalSettings['standardAnswer'])) { | |
$settings['vsprintfVars'][0] = $optionalSettings['standardAnswer']; | |
} | |
} | |
// analyse developers set of $optionalSettings['standardAnswer'] | |
$developersStandardAnswerIsYes = preg_match(self::PATTERN_USER_INPUT_YES, $settings['standardAnswer']); | |
$developersStandardAnswerIsNo = preg_match(self::PATTERN_USER_INPUT_NO, $settings['standardAnswer']); | |
$developersStandardAnswerIsCancel = preg_match(self::PATTERN_USER_INPUT_CANCEL, $settings['standardAnswer']); | |
// throw an exception, if this function will be called with wrong parameter | |
// | |
// developers standardAnswer must be set correctly and can not be empty | |
$developersStandardAnswerIsCorrect = $developersStandardAnswerIsYes || $developersStandardAnswerIsNo || $developersStandardAnswerIsCancel; | |
if (!$developersStandardAnswerIsCorrect) { | |
throw new \TYPO3\Flow\Exception('Developer has set $settings[\'standardAnswer\'] as '.$settings['standardAnswer']. ' please set this in your code properly', 1352736688); | |
} | |
$messages = array(); | |
foreach ($settings as $key => $value) { | |
// Texts validation: will trying to render defined mesage by fail developer can see it immediately | |
if (preg_match('/^message/', $key) && !empty($value)) { | |
$messages[$key] = \vsprintf($settings[$key], $settings['vsprintfVars']); | |
} | |
// CallBack: throw an Exceptions immediately if something is wrong with callBacks | |
if (preg_match('/^callBack/', $key) && !empty($value) | |
&& !method_exists($value[0][0], $value[0][1])) { | |
throw new \InvalidArgumentException( | |
'function "'.$value[0][1].'" for "'.$key.'" not exists or can not be called.'.PHP_EOL. | |
'See: call_user_func_array()'.PHP_EOL. | |
'http://php.net/manual/en/function.call-user-func-array.php', | |
1353073679 | |
); | |
} | |
} | |
// render output for question | |
$output = vsprintf($settings['confirmationMessage'], $settings['vsprintfVars']); | |
echo $output.' '; | |
$usersInput = rtrim(fgets(STDIN)); | |
// set 'vsprintfVars' properly | |
$settings['vsprintfVars'][1] = $usersInput; | |
if (empty($usersInput)) { | |
$settings['vsprintfVars'][1] = $settings['standardAnswer']; | |
} | |
// prepare users answer | |
$userAnsweredWithYes = preg_match(self::PATTERN_USER_INPUT_YES, $usersInput) | |
|| empty($usersInput) && $developersStandardAnswerIsYes; | |
$userAnsweredWithNo = preg_match(self::PATTERN_USER_INPUT_NO, $usersInput) | |
|| empty($usersInput) && $developersStandardAnswerIsNo; | |
$userAnsweredWithCancel = preg_match(self::PATTERN_USER_INPUT_CANCEL, $usersInput) | |
|| empty($usersInput) && $developersStandardAnswerIsCancel; | |
$usersInputIsCorrect = $userAnsweredWithYes || $userAnsweredWithNo || $userAnsweredWithCancel || empty($usersInput); | |
if (empty($usersInput)) { | |
$usersInput = $settings['standardAnswer']; | |
} | |
// evaluate | |
if ($usersInputIsCorrect) { | |
// for YES | |
if ($userAnsweredWithYes) { | |
if (!empty($settings['messageByYes'])) { | |
echo vsprintf($settings['messageByYes'], $settings['vsprintfVars']).PHP_EOL; | |
} | |
if (!empty($settings['callBackByYes'])) { | |
$returnValueByYes = call_user_func_array($settings['callBackByYes'][0], $settings['callBackByYes'][1]); | |
} | |
if (isset($returnValueByYes)) { | |
return $returnValueByYes; | |
} | |
return true; | |
} | |
// for NO | |
if ($userAnsweredWithNo) { | |
if (!empty($settings['messageByNo'])) { | |
echo vsprintf($settings['messageByNo'], $settings['vsprintfVars']).PHP_EOL; | |
} | |
if (!empty($settings['callBackByNo'])) { | |
$returnValueByNo = call_user_func_array($settings['callBackByNo'][0], $settings['callBackByNo'][1]); | |
} | |
if (isset($returnValueByNo)) { | |
return $returnValueByNo; | |
} | |
return false; | |
} | |
// for CANCEL | |
if ($userAnsweredWithCancel) { | |
if (!empty($settings['messageByCancel'])) { | |
echo vsprintf($settings['messageByCancel'], $settings['vsprintfVars']).PHP_EOL; | |
} | |
if (!empty($settings['callBackByCancel'])) { | |
$returnValueByCancel = call_user_func_array($settings['callBackByCancel'][0], $settings['callBackByCancel'][1]); | |
} | |
if (isset($returnValueByCancel)) { | |
return $returnValueByCancel; | |
} | |
return NULL; | |
} | |
} else { | |
// for wrong input | |
if (!empty($settings['messageByWrongInput'])) { | |
echo vsprintf($settings['messageByWrongInput'], $settings['vsprintfVars']).PHP_EOL; | |
} | |
if (!empty($settings['callBackByWrongInput'])) { | |
$returnValueByWrongInput = call_user_func_array($settings['callBackByWrongInput'][0], $settings['callBackByCancel'][1]); | |
} | |
if (isset($returnValueByWrongInput)) { | |
return $returnValueByWrongInput; | |
} | |
// throws Exception, if developer will no infinite loops | |
if (!$settings['infiniteLoopByWrongInput']) { | |
throw new \InvalidArgumentException('User has made incorrect input and you have not caught this exception in your confirmation dialog. TIPP: You can set $optionalSettings[\'infiniteLoopByWrongInput\']', 1352747275); | |
} | |
} | |
// will give rise to infinite looping by incorrect user's input if $optionalSettings['infiniteLoopByWrongInput'] == TRUE | |
return $this->confirmDialog($confirmationMessage, $standardAnswer, $settings); | |
} | |
private function callBackForYes() { | |
echo 'You called '.__FUNCTION__.'().'.PHP_EOL; | |
} | |
private function callBackForNo() { | |
echo 'You called '.__FUNCTION__.'().'.PHP_EOL; | |
} | |
private function callBackForCancel() { | |
echo 'You called '.__FUNCTION__.'().'.PHP_EOL; | |
} | |
private function callBackForWrongInput() { | |
echo 'You called '.__FUNCTION__.'().'.PHP_EOL; | |
} | |
/** | |
* as you can see this function has return value | |
* | |
* confirmDialog() will return calbacks return value | |
*/ | |
private function callBackForWrongInput2() { | |
echo 'You called '.__FUNCTION__.'().'.PHP_EOL; | |
echo 'Wrong input is not allowed, I will cancel this command.'.PHP_EOL; | |
return 'blockish'; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment