123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- <?php
- /**
- * Helper class to allow modal-style dialog box in an html form
- *
- * Possible improvement: do not use _SESSION for the caller's data,
- * instead set a member variable with caller information
- * and take the opportunity of the first edit button to place the information
- * into a hidden field
- *
- * Usage:
- */
- define('DLGSTACK_OK', 1);
- define('DLGSTACK_CANCEL', 2);
- //session_name("dialogstack");
- session_start();
- class dialogstack
- {
- private static $m_bCurrPageDeclared = false;
- /**
- * Declare the current page as being a dialog issuer, potentially pop...
- */
- static public function DeclareCaller($sTitle)
- {
- self::$m_bCurrPageDeclared = false;
- $_SESSION['dialogstack_calleruri'] = $_SERVER["REQUEST_URI"];
- $_SESSION['dialogstack_callertitle'] = $sTitle;
- if (isset($_POST["dialogstackpop"]) && ($_POST["dialogstackpop"] == count($_SESSION['dialogstack_currdlg'])))
- {
- // Pop !
- array_pop($_SESSION['dialogstack_currdlg']);
- }
- }
- /**
- * True if the current page has been loaded from an "dialog startup button"
- */
- static private function GetRetArgName()
- {
- foreach($_REQUEST as $sArgName=>$sArgValue)
- {
- if (strstr($sArgName, "dlgstack_go,"))
- {
- $aTokens = explode(",", $sArgName);
- return self::ArgNameDecode($aTokens[1]);
- }
- }
- return "";
- }
- /**
- * Protect against weird effects of PHP interpreting brackets...
- */
- static private function ArgNameEncode($sArgName)
- {
- return str_replace(array('[', ']'), array('_bracket_open_', '_bracket_close_'), $sArgName);
- }
- static private function ArgNameDecode($sCodedArgName)
- {
- return str_replace(array('_bracket_open_', '_bracket_close_'), array('[', ']'), $sCodedArgName);
- }
- /**
- * True if the current page has been loaded from an "dialog startup button"
- */
- static public function IsDialogStartup()
- {
- return (strlen(self::GetRetArgName()) > 0);
- }
- /**
- * Helper to
- */
- static private function RemoveArg(&$aValues, $sKey, &$retval = null)
- {
- if (isset($aValues[$sKey]))
- {
- if (empty($retval))
- {
- $retval = $aValues[$sKey];
- }
- unset($aValues[$sKey]);
- }
- }
-
- /**
- * Record current page args, and returns the initial value for the dialog
- */
- static public function StartDialog()
- {
- if (!isset($_SESSION['dialogstack_currdlg']))
- {
- // Init stack
- $_SESSION['dialogstack_currdlg'] = array();
- }
- $sRetArgName = self::GetRetArgName();
- $sCodedArgName = self::ArgNameEncode($sRetArgName);
- $sArgForRetArgName = "dlgstack_init_".$sCodedArgName;
- $sButtonName = "dlgstack_go,".$sCodedArgName;
- // Do not record utility arguments, neither the current value (stored separately)
- //
- $initValue = null;
- $aPost = $_POST;
- self::RemoveArg($aPost, $sArgForRetArgName, $initValue);
- self::RemoveArg($aPost, $sButtonName);
- self::RemoveArg($aPost, 'dlgstack_onok_page', $sOnOKPage);
- self::RemoveArg($aPost, 'dlgstack_onok_args', $aOnOKArgs);
- $aGet = $_GET;
- self::RemoveArg($aGet, $sArgForRetArgName, $initValue);
- self::RemoveArg($aGet, $sButtonName);
- self::RemoveArg($aGet, 'dlgstack_onok_page', $sOnOKPage);
- self::RemoveArg($aGet, 'dlgstack_onok_args', $aOnOKArgs);
- if (self::$m_bCurrPageDeclared)
- {
- throw new Exception("DeclareCaller() must not be called before StartDialog()");
- }
- $aCall = array(
- "title"=>$_SESSION['dialogstack_callertitle'],
- "uri"=>$_SESSION['dialogstack_calleruri'],
- "post"=>$aPost,
- "get"=>$aGet,
- "retarg"=>$sRetArgName,
- "initval"=>$initValue,
- );
- if (isset($sOnOKPage)) $aCall["onok_page"] = $sOnOKPage;
- if (isset($aOnOKArgs)) $aCall["onok_args"] = $aOnOKArgs;
- array_push($_SESSION['dialogstack_currdlg'], $aCall);
- return $initValue;
- }
- /**
- * Render a button to launch a new dialog
- */
- static public function RenderEditableField($sTitle, $sArgName, $sCurrValue, $bAddFieldValue, $sOnOKPage = "", $aOnOKArgs = array())
- {
- $sRet = "";
- $sCodedArgName = self::ArgNameEncode($sArgName);
- if ($bAddFieldValue)
- {
- $sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$sCurrValue\">\n";
- }
- $sRet .= "<input type=\"hidden\" name=\"dlgstack_init_$sCodedArgName\" value=\"$sCurrValue\">\n";
- $sRet .= "<input type=\"submit\" name=\"dlgstack_go,$sCodedArgName\" value=\"$sTitle\">\n";
- if (!empty($sOnOKPage))
- {
- $sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_page\" value=\"$sCurrValue\">\n";
- }
- foreach($aOnOKArgs as $sArgName=>$value)
- {
- $sRet .= "<input type=\"hidden\" name=\"dlgstack_onok_args[$sArgName]\" value=\"$value\">\n";
- }
- return $sRet;
- }
- /**
- * Render a [set of] hidden field, from a value that may be an array
- */
- static private function RenderHiddenField($sName, $value)
- {
- $sRet = "";
- if (is_array($value))
- {
- foreach($value as $sKey=>$subvalue)
- {
- $sRet .= self::RenderHiddenField($sName.'['.$sKey.']', $subvalue);
- }
- }
- else
- {
- $sRet .= "<input type=\"hidden\" name=\"$sName\" value=\"$value\">\n";
- }
- return $sRet;
- }
- /**
- * Render a form to end the current dialog and return to the caller
- */
- static public function RenderEndDialogForm($iButtonStyle, $sTitle, $sRetValue = null)
- {
- $aCall = end($_SESSION['dialogstack_currdlg']);
- if (!$aCall) return;
- return self::privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue);
- }
- /**
- * Returns an array of buttons to get back to upper dialog levels
- */
- static public function GetCurrentStack()
- {
- $aRet = array();
- if (isset($_SESSION['dialogstack_currdlg']))
- {
- foreach ($_SESSION['dialogstack_currdlg'] as $aCall)
- {
- $aRet[] = self::privRenderEndDialogForm($aCall, DLGSTACK_CANCEL, $aCall["title"]);
- }
- }
- return $aRet;
- }
- /**
- * Render a form to end the current dialog and return to the caller
- */
- static private function privRenderEndDialogForm($aCall, $iButtonStyle, $sTitle, $sRetValue = null)
- {
- if (($iButtonStyle == DLGSTACK_OK) && isset($aCall["onok_page"])) $sFormAction = $aCall["onok_page"];
- else $sFormAction = $aCall["uri"];
- $sRet = "<form method=\"post\" action=\"$sFormAction\">\n";
- foreach ($aCall["post"] as $sName=>$value)
- {
- $sRet .= self::RenderHiddenField($sName, $value);
- }
- if ($iButtonStyle == DLGSTACK_OK)
- {
- if (isset($aCall["onok_args"]))
- {
- foreach($aCall["onok_args"] as $sArgName=>$value)
- {
- $sRet .= "<input type=\"hidden\" name=\"$sArgName\" value=\"$value\">\n";
- }
- }
- $sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"$sRetValue\">\n";
- $sRet .= "<input type=\"submit\" name=\"dlgstackOK\" value=\"$sTitle, (OK) Back to ".$aCall["title"]."\">\n";
- }
- elseif ($iButtonStyle == DLGSTACK_CANCEL)
- {
- if (!is_null($aCall["initval"]))
- {
- $sRet .= "<input type=\"hidden\" name=\"".$aCall["retarg"]."\" value=\"".$aCall["initval"]."\">\n";
- }
- $sRet .= "<input type=\"submit\" name=\"dlgstackCANCEL\" value=\"$sTitle\">\n";
- }
- else
- {
- throw new Exception("Wrong value for button style ($iButtonStyle)");
- }
- $sRet .= "<input type=\"hidden\" name=\"dialogstackpop\" value=\"".count($_SESSION['dialogstack_currdlg'])."\">\n";
- $sRet .= "</form>\n";
- return $sRet;
- }
- }
- ?>
|