<?php
/*
* Copyright (c) 2004, Doron Enav, dizzyPages
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name dizzyPages nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* dizzyPages application framework
*
* @package dizzyPages
* @copyright dizzyPages
* @author Doron Enav <hide@address.com>
*/
/**
* DzePage
*
* The top level container of all functionality required to
* process a dizzyPage. This includes SQL connectivity, form processing,
* building output page, and handling session and user persistent data.
*
* @author Doron Enav
*/
class DzePage
{
/**
* @var object DzeMySQL handle to current sql transaction
*/
public $sql;
private $userId;
private $userName;
private $loginApp;
private $config;
private $pageTs;
private $pageId;
private $isStandAlone;
private $sesId;
private $sesExtId;
private $sesName;
private $url;
private $urlBase;
private $urlExt;
private $urlIsPublic;
private $urlApp;
private $urlAppTitle;
private $isRedirect;
private $isRedirected;
private $referrerFormName;
private $previousUrl;
private $previousUrlIsPublic;
private $previousUrlApp;
private $previousFormErr;
private $previousFormErrTrap;
private $previousFormName;
private $securityPass;
private $isFormError;
private $vpi;
/**#@+
* @internal
* @access private
*/
/**
* Create an instance of a DzePage.
*
* Every page has a DzePage instance <b>$this</b> created by default.
* You never call this constructor method but you can access all of it's
* public methods through the default object instance.
*/
public function __construct($config) {
$this->config = $config;
$this->sql = new DzeMySQL($config);
$this->sql->beginWork();
$this->isRedirect = $this->getRequest("redirect");
$this->isRedirected = 'N';
$this->setPageVars();
$this->initSession();
if ($this->isStandAlone != "Y") $this->setPreviousPageVars();
$this->setUrlAppTitle();
$this->initSecurity();
}
public function close() {
if ($this->isRedirect == 'Y')
$this->setSesAttrib("common-SESSION-INVALID_NAV", "N");
if ($this->isStandAlone != "Y")
$this->setSesAttrib("common-SESSION-PAGE_ID", $this->pageId);
$this->sql->commitWork();
$this->sql->closeDB();
}
private function setPageVars() {
// PHP _REQUEST looks for both get and post form submitions
$this->referrerFormName = $this->getRequest("__DZE__FORM_NAME");
$this->url = $this->getRequest("url");
if (! $this->url)
$this->url = "/" . $this->config['default_application']
. "/_no_url_supplied_in_search_string_";
$this->isStandAlone = $this->getPage($this->url, "STAND_ALONE_B");
$this->urlExt = strrchr($this->url, ".");
$this->urlBase = substr($this->url, 0, strlen($this->url) - strlen($this->urlExt));
$this->urlApp = $this->getAppFromUrl($this->url);
if (! $this->urlApp) $this->urlApp = $this->config["default_application"];
$this->urlIsPublic = $this->isUrlPublic($this->url);
}
private function setPreviousPageVars() {
$this->previousUrl = $this->getSesAttrib("common-SESSION-PREVIOUS-URL");
$this->previousUrlApp = $this->getAppFromUrl($this->previousUrl);
$this->previousUrlIsPublic = $this->isUrlPublic($this->previousUrl);
$this->previousFormErr = $this->getSesAttrib("common-SESSION-PREVIOUS-FORM_ERR");
$this->previousFormName = $this->getSesAttrib("common-SESSION-PREVIOUS-FORM_NAME");
if ($this->previousFormErr == 'Y') {
$this->previousFormErrTrap = $this->getFormTrapOnErr($this->previousFormName);
// $this->previousActionUrl = $this->getSesAttrib("common-SESSION-PREVIOUS-ACTION_URL");
}
}
private function setUrlAppTitle() {
if ($this->urlApp == $this->previousUrlApp)
$this->urlAppTitle = $this->getSesAttrib("common-ApplicationTitle");
else {
$appId = $this->getAppIdFromName($this->urlApp);
$this->urlAppTitle =
$appId
? $this->getUserAttrib("common-ApplicationTitle", 1, $appId)
: "";
$this->setSesAttrib("common-ApplicationTitle", $this->urlAppTitle);
}
}
private function getAppIdFromName($appMame) {
$this->sql->pushResult();
$this->sql->select(
"DZE_USR",
array("USR_ID"),
array("LWR_CASE_NAME" => $appMame)
);
$usr = $this->sql->fetchAssoc();
$this->sql->popResult();
return ($usr ? $usr["USR_ID"] : 0);
}
private function isUrlPublic($url) {
$basedir = explode('/', $url);
return (isset($basedir[2]) && $basedir[2] == 'public') ? 'Y' : 'N';
}
private function getFormTrapOnErr($formName) {
$this->sql->pushResult();
$this->sql->select(
"DZE_FORM",
array("TRAP_ON_ERR_TYPE"),
array("FORM_NAME" => $formName)
);
$row = $this->sql->fetchAssoc();
$this->sql->freeResult();
$this->sql->popResult();
return $row["TRAP_ON_ERR_TYPE"];
}
private function getSecureString() {
return sha1($this->pageTs . rand());
}
private function initSecurity() {
$this->securityPass = $this->getSesAttrib("common-SESSION-PAGE_ID")
== $this->getRequest("pageid");
$this->pageId = $this->getSecureString();
}
private function initSession() {
$this->sesName = "id";
$this->sesExtId = $this->getRequest($this->sesName);
$this->sql->pushResult();
$this->sql->select(
"DZE_SESSION",
array(
"SESSION_USR_ID",
"REGISTER_USR_ID",
"LAST_HIT_TS",
"TIME_OUT_AT_TS"
),
array("SESSION_ID" => $this->sesExtId),
'FOR UPDATE'
);
$session = $this->sql->fetchAssoc();
$this->sql->freeResult();
if ($session) {
$timeStamp = time();
$this->sesId = $session["SESSION_USR_ID"];
$this->userId = $session["REGISTER_USR_ID"];
$this->pageTs = $this->getNextPageTs($session, $timeStamp);
$this->loginApp = $this->getSesAttrib("common-SESSION-APP-NAME");
if (!$this->isSessionValid($session)) {
$this->newSession();
}
else {
$this->sql->update(
"DZE_SESSION",
array(
"LAST_HIT_TS" => $this->pageTs,
"TIME_OUT_AT_TS" =>
gmstrftime(
"%Y-%m-%d %H:%M:%S",
$timeStamp + (60 * 60) // Time out in 60 minutes
),
"LAST_PAGE_URL" => $this->url
),
array("SESSION_ID" => $this->sesExtId)
);
if (!is_null($this->userId))
$this->userName = $this->getSesAttrib("common-SESSION-USER-NAME");
}
}
else {
$this->newSession();
}
$this->sql->popResult();
}
private function isSessionValid($session) {
$this->sql->pushResult();
$isValid = true;
// TODO set a session/user TIME OUT attribute for audit purpose
// Check for logged in user's session timeout
if ( ! is_null($this->userId)
&& $this->pageTs > $session["TIME_OUT_AT_TS"])
$isValid = false;
// Check for user logout
if ($isValid && $this->getRequest("__DZE__LOGOUT") == "Y") {
$this->setSesAttrib("common-SESSION-TS-LOGOUT", $this->pageTs);
$isValid = false;
}
// remove invalid session
if (! $isValid) {
$this->sql->delete(
"DZE_SESSION",
array("SESSION_ID" => $this->sesExtId)
);
}
$this->sql->popResult();
return $isValid;
}
private function newSession() {
$this->sql->pushResult();
$timeStamp = time();
$this->pageTs = gmstrftime("%Y-%m-%d %H:%M:%S", $timeStamp) . ".000";
// Time out in 60 minutes
$timeOutTs = gmstrftime("%Y-%m-%d %H:%M:%S", $timeStamp + (60 * 60));
$this->sesExtId = md5($this->pageTs . rand());
$this->sesId = $this->sql->seqValue("DZE-SESSION_ID");
$this->userId = null;
// TODO time out should be user settable
$this->sql->insert(
"DZE_SESSION",
array(
"SESSION_ID" => $this->sesExtId,
"SESSION_USR_ID" => $this->sesId,
"LAST_HIT_TS" => $this->pageTs,
"TIME_OUT_AT_TS" => $timeOutTs,
"LAST_PAGE_URL" => $this->url
)
);
// TODO set a session/user TIME OUT attribute for audit purpose
// cleanup timed out sessions
$this->sql->delete(
"DZE_SESSION",
array("1" => "1"),
"and TIME_OUT_AT_TS < '" . $this->pageTs . "'"
);
// no longer using PHP sessions
//$_SESSION["session_user_id"] = $this->sesId;
$this->sql->delete("DZE_USR_ATTRIB_ERR",
array("USR_ID" => $this->sesId));
$this->sql->delete("DZE_USR_FORM_ERR",
array("USR_ID" => $this->sesId));
$this->sql->delete("DZE_USR_ATTRIB",
array("USR_ID" => $this->sesId));
$this->setSesAttrib("common-SESSION-TS-START", $this->pageTs);
// time out moved to DZE_SESSION table
// $this->setSesAttrib("common-SESSION-TIMEOUT-MINUTES", "60");
$this->sql->popResult();
}
private function getNextPageTs($session, $timeStamp) {
$this->sql->pushResult();
$pageTs = gmstrftime("%Y-%m-%d %H:%M:%S", $timeStamp);
// Timestamp format 'YYYY-MM-DD hh:mm:ss.cnt"
// hh - is 00-23 hours
// cnt - is not a fractional second rather a 3 digit number that
// counts a page hit within a second. This insures uniqnes on
// every page hit.
$tsLastHit = $session["LAST_HIT_TS"];
// If a unique registered user has more than one session make sure the
// last hit ts is the highest amongst all the users session
// before adjusting the current page ts to be unique
if (!is_null($this->userId)) {
$this->sql->select(
"DZE_SESSION",
array("LAST_HIT_TS"),
array("REGISTER_USR_ID" => $this->userId),
" and LAST_HIT_TS > '" . $tsLastHit . "'"
);
if ($ts = $this->sql->fetchAssoc())
$tsLastHit = $ts["LAST_HIT_TS"];
$this->sql->freeResult();
}
// adjust current page ts if it has already been used by a previous page
list($tsLastHitSeconds, $tsLastHitCount) = explode(".", $tsLastHit);
if ($tsLastHitSeconds == $pageTs)
$pageTs = $tsLastHitSeconds . "."
. sprintf("%03d", ($tsLastHitCount + 1));
else $pageTs .= ".000";
$this->sql->popResult();
return $pageTs;
}
private function copyUserErrorToSession() {
$this->sql->pushResult();
$isError = $this->getUserAttrib("common-SESSION-PREVIOUS-FORM_ERR");
if ($isError == "Y") {
$this->setSesAttrib("common-SESSION-PREVIOUS-FORM_ERR", "Y");
$this->setSesAttrib("common-SESSION-PREVIOUS-FORM_NAME",
$this->getUserAttrib("common-SESSION-PREVIOUS-FORM_NAME"));
$previousUrl = $this->getUserAttrib("common-SESSION-PREVIOUS-URL");
$this->setSesAttrib("common-SESSION-PREVIOUS-URL", $previousUrl);
$this->redirect($previousUrl);
$this->sql->select(
"DZE_USR_ATTRIB_ERR",
array("ATTRIB_NAME", "REC_ID", "ERR_TXT"),
array("USR_ID" => $this->userId)
);
while ($error = $this->sql->fetchAssoc())
$this->setSesAttribError(
$error["ATTRIB_NAME"],
$error["ERR_TXT"],
$error["REC_ID"]
);
$this->sql->freeResult();
}
$this->sql->popResult();
}
private function setReqPageErrs() {
// TODO currently run on every page I believe this only needs to be run
// on pages the have a form with escape on error set to off
// TODO this needs a good cleanup
$errAttribInFromFound = false;
$this->sql->pushResult();
$this->sql->select(
"DZE_FORM_IN_PAGE",
array("FORM_NAME"),
array("PAGE_URL" => $this->url),
"ORDER BY DISPLAY_ORDER"
);
while ( (! $errAttribInFromFound)
&& ($form_in_page = $this->sql->fetchAssoc())) {
$this->sql->pushResult();
$this->sql->select(
"DZE_FORM",
array("FORM_NAME", "ACTION_URL", "TRAP_ON_ERR_TYPE"),
array(
"FORM_NAME" => $form_in_page["FORM_NAME"],
"TYPE" => "S"
),
"and TRAP_ON_ERR_TYPE <> 'N'"
);
if ($form = $this->sql->fetchAssoc()) {
$this->sql->pushResult();
$this->sql->select(
"DZE_ATTRIB_IN_FORM",
array("ATTRIB_NAME"),
array("FORM_NAME" => $form["FORM_NAME"])
);
while ($attrib_in_form = $this->sql->fetchAssoc()) {
$this->sql->pushResult();
$this->sql->select(
"DZE_ATTRIB",
array("ATTRIB_NAME", "SAVE_TYPE", "REQUIRED_B", "DFLT_VALUE"),
array("ATTRIB_NAME" => $attrib_in_form["ATTRIB_NAME"])
);
if ($attrib = $this->sql->fetchAssoc()) {
$this->sql->pushResult();
switch ($attrib["SAVE_TYPE"]) {
case "S":
$usr_value = $this->getSesAttrib($attrib["ATTRIB_NAME"]);
break;
case "U":
$usr_value = $this->getUserAttrib($attrib["ATTRIB_NAME"]);
break;
default:
$usr_value = null;
}
if ( is_null($usr_value)
&& strlen($attrib["DFLT_VALUE"]) > 0) {
$usr_value = $attrib["DFLT_VALUE"];
}
$error = array();
$this->sql->select(
"DZE_ATTRIB_RULE",
array("RULE", "FIRE_ORDER", "RULE_TYPE", "ERR_TXT"),
array("ATTRIB_NAME" => $attrib["ATTRIB_NAME"]),
"ORDER BY FIRE_ORDER"
);
$error['found'] = false;
while ( ($rule = $this->sql->fetchAssoc())
&& (! $error['found'])
) {
$error['found'] = ereg($rule["RULE"], $usr_value);
if ($rule["RULE_TYPE"] != "M") $error['found'] = ! $error['found'];
if ($error['found']) {
$error['found'] = 'Y';
$error['text'] = $rule["ERR_TXT"];
}
}
if ($error['found']) {
$this->setSesAttribError($attrib["ATTRIB_NAME"], $error['text']);
if ($form["TRAP_ON_ERR_TYPE"] == "U")
$this->setUserAttribError($attrib["ATTRIB_NAME"], $error['text']);
$errAttribInFromFound = true;
}
$this->sql->freeResult();
$this->sql->popResult();
}
$this->sql->freeResult();
$this->sql->popResult();
}
$this->sql->freeResult();
$this->sql->popResult();
}
$this->sql->freeResult();
$this->sql->popResult();
if ($errAttribInFromFound) {
$this->setSesAttrib("common-SESSION-PREVIOUS-FORM_ERR", "Y");
$this->setSesAttrib("common-SESSION-PREVIOUS-FORM_NAME", $form["FORM_NAME"]);
// $this->setSesAttrib("common-SESSION-PREVIOUS-ACTION_URL", $form["ACTION_URL"]);
if ($form["TRAP_ON_ERR_TYPE"] == "U") {
$this->setUserAttrib("common-SESSION-PREVIOUS-FORM_ERR", "Y");
$this->setUserAttrib("common-SESSION-PREVIOUS-FORM_NAME", $form["FORM_NAME"]);
$this->setUserAttrib("common-SESSION-PREVIOUS-URL", $this->url);
}
}
}
$this->sql->freeResult();
$this->sql->popResult();
}
public function getRequest($requestName) {
return
(isset($_REQUEST[$requestName])
? $_REQUEST[$requestName] : null);
}
public function getAppFromUrl($url) {
$app = explode('/', $url);
return isset($app[1]) ? $app[1] : null;
}
public function setVpi($name, $value) {
$this->vpi[$name] = $value;
}
public function isValidNavigation() {
$retValue = true;
if ($this->getSesAttrib("common-SESSION-INVALID_NAV") == "Y") {
$retValue = false;
}
return ($retValue);
}
public function getMember($memberName) {
eval ('$memeber = $this->' . $memberName . ';');
return $memeber;
}
public function setFormError($isError = null) {
if (! is_null($isError))
$this->isFormError = $isError;
return $this->isFormError;
}
public function processPage() {
$setReqPageErrs = false;
// Do not process form
// If prvious page is not public
// and ( user is not logged in
// or previous page does not belong to the logged in app
// or previous page is not being run inside the CASE tool)
if ( $this->previousUrlIsPublic != 'Y'
&& ( is_null($this->userId)
|| ( $this->loginApp != 'dze'
&& $this->loginApp != $this->previousUrlApp)
|| ( $this->loginApp == 'dze'
&& $this->userName != $this->previousUrlApp
&& $this->loginApp != $this->previousUrlApp))) {
dzeLog("--->1 Do not process form\n");
// Do not process form
}
// Redirect to previous page
// If not already performing redirect
// and previous page/form contains an outstanding error
// and previous page/form is trapping
// and submitted form is not the form with the outstanding error
else if ( $this->isRedirect != 'Y'
&& $this->previousFormErr == 'Y'
&& $this->previousFormErrTrap != 'N'
&& $this->previousFormName != $this->referrerFormName) {
dzeLog("--->2 Redirect to previous page\n");
$this->redirect($this->previousUrl, "Y", "Y");
}
// Proceed to process form
// If previous form has no errors
// or ( previous form has errors
// and submitted form is the previous form with the outstanding error)
else if ( $this->previousFormErr != 'Y'
|| $this->previousFormErr == 'Y'
&& $this->previousFormName == $this->referrerFormName) {
dzeLog("--->3 Proceed to process form\n");
// Process form
// If a form has been submitted
if ($this->referrerFormName) {
// If form has been submitted in the expected order
if ($this->securityPass) {
$phpFile = $this->config["directory"] . "/formprocess" . substr($this->previousUrl, 0, strlen($this->previousUrl) - 4) . ".php";
if (!file_exists($phpFile))
$phpFile = $this->config["directory"] . "/formprocess/default.php";
dzeLog("--->4 Process form - " . $phpFile . "\n");
include $phpFile;
if ($this->loginApp == 'dze' || $this->config['log_level'] >= 5)
$this->vpi['formPhpFile'] = $phpFile;
// Redirect to previous page after processing form
// If current form contains errors
// and form originating page is not the current page
if ( $this->isFormError == 'Y'
&& $this->previousUrl != $this->url) {
dzeLog("--->5 Redirect to previous page " . $this->previousUrl . " Due to outstanding error.\n");
$this->redirect($this->previousUrl);
}
}
// else the form has NOT been submitted in the expected order
// This happens when the user uses the browser back button to
// navigate
else {
dzeLog("--->6 Redirect to previous page " . $this->previousUrl . " Due to illegal user navigation.\n");
$this->redirect($this->previousUrl, "Y", "Y");
}
}
// No form submitted or form submitted out of order
else {
dzeLog("--->7 No form submitted\n");
// TODO test this with two Standard forms
// TODO I think this only needs to be run for form with no escape
$setReqPageErrs = true;
}
}
// Escape occured clearing outstanding errors
// If user is escaping
// and exists outstanding errors
// and page/form is not trapping
else if ( $this->previousUrl != $this->url
&& $this->previousFormErr == 'Y'
&& $this->previousFormErrTrap == 'N') {
dzeLog("--->8 Escape occured clearing outstanding errors\n");
// clear outstanding errors so that the new page/form does not display
// erroneous errors form the escaped page/form
$this->clearErrors($this->sesId);
}
// Redirect page to public/home.dze
// If not already performing redirect
// and page is not public
// and ( user is not logged in
// or page does not belong to the logged in app
// or page is not being run inside the CASE tool)
if ( $this->isRedirected != 'Y'
&& $this->urlIsPublic != 'Y'
&& ( is_null($this->userId)
|| ( $this->loginApp != 'dze'
&& $this->loginApp != $this->urlApp)
|| ( $this->loginApp == 'dze'
&& $this->userName != $this->urlApp
&& $this->loginApp != $this->urlApp))) {
dzeLog( "--->9 Redirect page to /"
. ($this->loginApp == "dze" ? "dze" : $this->urlApp)
. "/public/home.dze\n");
$this->redirect( "/"
. ($this->loginApp == "dze" ? "dze" : $this->urlApp)
. '/public/home.dze', "Y", "Y");
}
// Display page
// If not performing redirect
if ($this->isRedirected != 'Y') {
$phpFile = $this->config["directory"] . "/pageoutput" . $this->urlBase . ".php";
if (!file_exists($phpFile))
$phpFile = $this->config["directory"] . "/pageoutput/default.php";
dzeLog("--->10 Display page - " . $phpFile . "\n");
include $phpFile;
if ($this->loginApp == 'dze' || $this->config['log_level'] >= 5)
$this->vpi['outputPhpFile'] = $phpFile;
if ($this->isStandAlone != "Y")
$this->setSesAttrib("common-SESSION-PREVIOUS-URL", $this->url);
if ($setReqPageErrs) $this->setReqPageErrs();
}
}
public function getPage($url, $fields = null) {
$retValue = null;
$this->sql->pushResult();
if (is_null($fields))
$fields = array(
"TITLE",
"STAND_ALONE_B",
"DESCRIP"
);
$this->sql->select(
"DZE_PAGE",
(is_array($fields)) ? $fields : array($fields),
array("PAGE_URL" => $url)
);
if (is_array($fields))
$retValue = $this->sql->fetchAssoc();
else {
$row = $this->sql->fetchArray();
if ($this->sql->dbCount > 0)
$retValue = array_pop($row);
else
$retValue = $row;
}
$this->sql->freeResult();
$this->sql->popResult();
return $retValue;
}
public function setPage($url, $cols) {
$this->sql->pushResult();
$this->sql->select(
"DZE_PAGE",
array("'X'"),
array("PAGE_URL" => $url),
"FOR UPDATE"
);
if ($this->sql->fetchArray()) {
$this->sql->update(
"DZE_PAGE",
$cols,
array("PAGE_URL" => $url)
);
}
else {
$this->sql->insert(
"DZE_PAGE",
array_merge(
array("PAGE_URL" => $url),
$cols
)
);
}
$this->sql->popResult();
}
public function deletePage($url) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_FORM_IN_PAGE",
array("PAGE_URL" => $url)
);
$this->sql->delete(
"DZE_PAGE",
array("PAGE_URL" => $url)
);
$this->sql->update(
"DZE_FORM",
array("ACTION_URL" => ""),
array("ACTION_URL" => $url)
);
$this->sql->popResult();
}
public function getForm($name, $fields = null) {
$this->sql->pushResult();
if (is_null($fields))
$fields = array(
"TYPE",
"METHOD",
"TITLE",
"ACTION_URL",
"TRAP_ON_ERR_TYPE",
"R_SAVE_TYPE",
"R_AUDIT_TYPE",
"R_ITEMS_MAX",
"R_ITEMS_MAX",
"DESCRIP"
);
$this->sql->select(
"DZE_FORM",
(is_array($fields)) ? $fields : array($fields),
array("FORM_NAME" => $name)
);
if (is_array($fields))
$retValue = $this->sql->fetchAssoc();
else {
$row = $this->sql->fetchArray();
if ($this->sql->dbCount > 0)
$retValue = array_pop($row);
else
$retValue = $row;
}
$this->sql->freeResult();
$this->sql->popResult();
return $retValue;
}
public function setForm($name, $cols) {
$this->sql->pushResult();
$this->sql->select(
"DZE_FORM",
array("'X'"),
array("FORM_NAME" => $name),
"FOR UPDATE"
);
if ($this->sql->fetchArray()) {
$this->sql->update(
"DZE_FORM",
$cols,
array("FORM_NAME" => $name)
);
}
else {
$this->sql->insert(
"DZE_FORM",
array_merge(
array("FORM_NAME" => $name),
$cols
)
);
}
$this->setAttrib(
"__CT__" . $name,
array(
"TYPE" => "T",
"SAVE_TYPE" => "S",
"AUDIT_TYPE" => "N",
"REQUIRED_B" => "N",
"S_SLCT_DYN_B" => "N",
"DESCRIP" => "DZE Internal maintains record count"
)
);
if (isset($cols["TYPE"]) && $cols["TYPE"] == "R") {
$delAttribName = "__DT__" . $name;
$this->setAttrib(
$delAttribName,
array(
"TYPE" => "M",
"SAVE_TYPE" => "N",
"AUDIT_TYPE" => "N",
"REQUIRED_B" => "N",
"S_SLCT_DYN_B" => "N",
"S_FORM_TYPE" => "B",
"S_FORM_ORDER_TYPE" => "H",
"FORM_LABEL" => "DELETE",
"DESCRIP" => "DZE Internal record delete indicator"
)
);
$options = array();
$options[1] =
array("VALUE" => "Y", "FORM_LABEL" => "", "DEFAULT_B" => "N");
$this->setAttribOption($delAttribName, $options);
}
$this->sql->popResult();
}
public function deleteForm($name) {
$this->sql->pushResult();
$this->deleteAttrib("__CT__" . $name);
$this->deleteAttrib("__DT__" . $name);
$this->sql->delete(
"DZE_ATTRIB_IN_FORM",
array("FORM_NAME" => $name)
);
$this->sql->delete(
"DZE_FORM_IN_PAGE",
array("FORM_NAME" => $name)
);
$this->sql->delete(
"DZE_FORM",
array("FORM_NAME" => $name)
);
$this->sql->popResult();
}
public function getAttrib($name, $fields = null) {
$this->sql->pushResult();
if (is_null($fields))
$fields = array(
"TYPE",
"SAVE_TYPE",
"AUDIT_TYPE",
"REQUIRED_B",
"FORM_LABEL",
"DFLT_VALUE",
"T_FORM_TYPE",
"T_FORM_LEN",
"T_FORM_LEN_MAX",
"T_AREA_FORM_ROWS",
"S_FORM_TYPE",
"S_FORM_COLS",
"S_FORM_ORDER_TYPE",
"S_SLCT_DYN_B",
"M_SLCT_OPTION_MIN",
"M_SLCT_OPTION_MAX",
"P_ENCRYPT_B",
"DESCRIP"
);
$this->sql->select(
"DZE_ATTRIB",
(is_array($fields)) ? $fields : array($fields),
array("ATTRIB_NAME" => $name)
);
if (is_array($fields))
$retValue = $this->sql->fetchAssoc();
else {
$row = $this->sql->fetchArray();
if ($this->sql->dbCount > 0)
$retValue = array_pop($row);
else
$retValue = $row;
}
$this->sql->popResult();
return $retValue;
}
public function setAttrib($name, $cols) {
$this->sql->pushResult();
$this->sql->select(
"DZE_ATTRIB",
array("'X'"),
array("ATTRIB_NAME" => $name),
"FOR UPDATE"
);
if ($this->sql->fetchArray()) {
$this->sql->update(
"DZE_ATTRIB",
$cols,
array("ATTRIB_NAME" => $name)
);
}
else {
$this->sql->insert(
"DZE_ATTRIB",
array_merge(
array("ATTRIB_NAME" => $name),
$cols
)
);
}
$this->sql->popResult();
}
public function deleteAttrib($name) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_USR_ATTRIB_ERR",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_USR_ATTRIB",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_USR_ATTRIB_ADT",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_ATTRIB_RULE",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_SLCT_OPTION",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_ATTRIB_IN_FORM",
array("ATTRIB_NAME" => $name)
);
$this->sql->delete(
"DZE_ATTRIB",
array("ATTRIB_NAME" => $name)
);
$this->sql->popResult();
}
public function getFormAttrib($name) {
$this->sql->pushResult();
$attribS = array();
$this->sql->select(
"DZE_ATTRIB_IN_FORM",
array("DISPLAY_ORDER", "ATTRIB_NAME"),
array("FORM_NAME" => $name),
" and ATTRIB_NAME not like '\_\_DT\_\_%' order by DISPLAY_ORDER"
);
$attribSCt = 0;
while ($attrib = $this->sql->fetchAssoc())
$attribS[++$attribSCt] = $attrib["ATTRIB_NAME"];
$this->sql->freeResult();
$this->sql->popResult();
return $attribS;
}
public function setFormAttrib($name, $attribS) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_ATTRIB_IN_FORM",
array("FORM_NAME" => $name)
);
foreach ($attribS as $displayOrder => $attribName)
$this->sql->insert(
"DZE_ATTRIB_IN_FORM",
array(
"FORM_NAME" => $name,
"ATTRIB_NAME" => $attribName,
"DISPLAY_ORDER" => $displayOrder
)
);
// Record forms have an internal __DT__(delete) attribute
if ($this->getForm($name, "TYPE") == "R")
$this->sql->insert(
"DZE_ATTRIB_IN_FORM",
array(
"FORM_NAME" => $name,
"ATTRIB_NAME" => "__DT__" . $name,
"DISPLAY_ORDER" => count($attribS) + 1
)
);
$this->sql->popResult();
}
public function getPageForm($url) {
$this->sql->pushResult();
$formS = array();
$this->sql->select(
"DZE_FORM_IN_PAGE",
array("DISPLAY_ORDER", "FORM_NAME"),
array("PAGE_URL" => $url),
" order by DISPLAY_ORDER"
);
$formSCt = 0;
while ($form = $this->sql->fetchAssoc())
$formS[++$formSCt] = $form["FORM_NAME"];
$this->sql->freeResult();
$this->sql->popResult();
return $formS;
}
public function setPageForm($url, $formS) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_FORM_IN_PAGE",
array("PAGE_URL" => $url)
);
foreach ($formS as $displayOrder => $formName)
$this->sql->insert(
"DZE_FORM_IN_PAGE",
array(
"PAGE_URL" => $url,
"FORM_NAME" => $formName,
"DISPLAY_ORDER" => $displayOrder
)
);
$this->sql->popResult();
}
public function getAttribRule($name) {
$this->sql->pushResult();
$ruleS = array();
$this->sql->select(
"DZE_ATTRIB_RULE",
array("FIRE_ORDER", "RULE", "RULE_TYPE", "ERR_TXT"),
array("ATTRIB_NAME" => $name)
);
while ($rule = $this->sql->fetchAssoc())
$ruleS[$rule["FIRE_ORDER"]] = array(
"RULE" => $rule["RULE"],
"RULE_TYPE" => $rule["RULE_TYPE"],
"ERR_TXT" => $rule["ERR_TXT"]
);
$this->sql->freeResult();
$this->sql->popResult();
return $ruleS;
}
public function getAttribOption($name) {
$this->sql->pushResult();
$optionS = array();
$this->sql->select(
"DZE_SLCT_OPTION",
array("DISPLAY_ORDER", "VALUE", "FORM_LABEL", "DEFAULT_B"),
array("ATTRIB_NAME" => $name)
);
while ($option = $this->sql->fetchAssoc())
$optionS[$option["DISPLAY_ORDER"]] = array(
"VALUE" => $option["VALUE"],
"FORM_LABEL" => $option["FORM_LABEL"],
"DEFAULT_B" => $option["DEFAULT_B"]
);
$this->sql->freeResult();
$this->sql->popResult();
return $optionS;
}
public function setAttribRule($name, $ruleS) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_ATTRIB_RULE",
array("ATTRIB_NAME" => $name)
);
foreach ($ruleS as $fireOrder => $rule)
$this->sql->insert(
"DZE_ATTRIB_RULE",
array(
"ATTRIB_NAME" => $name,
"FIRE_ORDER" => $fireOrder,
"RULE" => $rule["RULE"],
"RULE_TYPE" => $rule["RULE_TYPE"],
"ERR_TXT" => $rule["ERR_TXT"]
)
);
$this->sql->popResult();
}
public function setAttribOption($name, $optionS) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_SLCT_OPTION",
array("ATTRIB_NAME" => $name)
);
$defaultValue = array();
// Mimics the blank entry in a form submittion for a Multi-select
if ($this->getAttrib($name, 'TYPE') == 'M')
array_push($defaultValue, "");
foreach ($optionS as $displayOrder => $option) {
$defaultB = substr($option["DEFAULT_B"], -1);
if ($defaultB == 'Y') array_push($defaultValue, $option["VALUE"]);
$this->sql->insert(
"DZE_SLCT_OPTION",
array(
"ATTRIB_NAME" => $name,
"DISPLAY_ORDER" => $displayOrder,
"VALUE" => $option["VALUE"],
"FORM_LABEL" => $option["FORM_LABEL"],
"DEFAULT_B" => $defaultB
)
);
}
$defaultValue = array_unique($defaultValue);
sort($defaultValue);
$cols = array(
"DFLT_VALUE" => implode("|", $defaultValue)
);
$this->setAttrib($name, $cols);
$this->sql->popResult();
}
public function createVpi() {
// TODO cleanup required
// This happens when the user clicks logout from the CASE tool
// with out this poor style of return several errors are reported
if ( !$this->userName
|| ( $this->loginApp != 'dze'
and $this->config['log_level'] < 5)
) return;
if ($this->isRedirected == 'Y') return;
$logDir =
$_SERVER["DOCUMENT_ROOT"] . "/dze/usr/" .
($this->loginApp
? ($this->loginApp == 'dze'
? strtolower($this->userName)
: $this->loginApp)
: $this->urlApp) .
"/log";
if (! isset($this->vpi['formPhpFile'])) {
if ($this->isRedirect != 'Y') {
$this->vpi['formPhpFile'] = 'No form processed';
$logHandle = fopen($logDir . "/form.txt", "w");
fwrite($logHandle, "empty ...");
fclose($logHandle);
$logHandle = fopen($logDir . "/attrib.txt", "w");
fwrite($logHandle, "empty ...");
fclose($logHandle);
}
else
$this->vpi['formPhpFile'] = $this->config["directory"] . '/formprocess' . substr($this->previousUrl, 0, -3) . 'php';
}
else {
if (strpos($this->vpi['formPhpFile'], '/formprocess/dze/')) {
$logHandle = fopen($logDir . "/form.txt", "w");
fwrite($logHandle, "dizzyPages internals code ...");
fclose($logHandle);
}
else copy($this->vpi['formPhpFile'], $logDir . '/form.txt');
$logHandle = fopen($logDir . "/attrib.txt", "w");
fwrite($logHandle, isset($this->vpi['attrib']) ? $this->vpi['attrib'] : "");
fclose($logHandle);
}
if (strpos($this->vpi['outputPhpFile'], '/pageoutput/dze/')) {
$logHandle = fopen($logDir . "/dom.txt", "w");
fwrite($logHandle, "dizzyPages internals code ...");
fclose($logHandle);
}
else copy($this->vpi['outputPhpFile'], $logDir . '/dom.txt');
copy($this->vpi['xslFile'], $logDir . '/page.xsl');
$logHandle = fopen($logDir . "/xml.txt", "w");
fwrite($logHandle, $this->vpi['xml']);
fclose($logHandle);
copy($logDir . '/xml.txt', $logDir . '/page.xml');
$logHandle = fopen($logDir . "/vpi.html", "w");
fwrite($logHandle,
'<HTML>
<HEAD>
<TITLE>dizzyPages - View Page Internals</TITLE>
</HEAD>
<BODY>
<FORM>
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD COLSPAN="2">dizzyPages View Page Internals</TD>
</TR>
<TR>
<TD COLSPAN="2">URL: ' . $this->url . '</TD>
</TR>
<TR>
<TD COLSPAN="2">At: ' . $this->pageTs . '</TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD COLSPAN="2"><A HREF="#form">Form Process PHP Class Source</A></TD>
</TR>
<TR>
<TD COLSPAN="2"><A HREF="#attrib">Form Process Data</A></TD>
</TR>
<TR>
<TD COLSPAN="2"><A HREF="#dom">Page Output PHP Class Source</A></TD>
</TR>
<TR>
<TD COLSPAN="2"><A HREF="#xml">Page Output Dynamic XML</A></TD>
</TR>
<TR>
<TD COLSPAN="2"><A HREF="#xsl">Page Output XSL Stylesheet</A></TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD><A NAME="form">Form Process PHP Class Source</A>:</TD>
<TD ALIGN="RIGHT"><INPUT TYPE="BUTTON" VALUE="Close Window"
ONCLICK="self.close()"></TD>
</TR>
<TR>
<TD COLSPAN="3">' . $this->vpi['formPhpFile'] . '</TD>
</TR>
<TR>
<TD COLSPAN="2">
<TABLE BGCOLOR="#000000">
<TR>
<TD BGCOLOR="#FFFFFF"><IFRAME SRC="form.txt"
NORESIZE="NORESIZE" SCROLLING="AUTO" HEIGHT="400" WIDTH="600" BORDER="0"
FRAMEBORDER="0"></IFRAME></TD>
</TR>
</TABLE></TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD><A NAME="attrib">Form Process Data</A></TD>
<TD ALIGN="RIGHT"><INPUT TYPE="BUTTON" VALUE="Close Window"
ONCLICK="self.close()"></TD>
</TR>
<TR>
<TD COLSPAN="2">
<TABLE BGCOLOR="#000000">
<TR>
<TD BGCOLOR="#FFFFFF"><IFRAME SRC="attrib.txt"
NORESIZE="NORESIZE" SCROLLING="AUTO" HEIGHT="400" WIDTH="600" BORDER="0"
FRAMEBORDER="0"></IFRAME></TD>
</TR>
</TABLE></TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD><A NAME="dom">Page Output PHP Class Source</A>: </TD>
<TD ALIGN="RIGHT"><INPUT TYPE="BUTTON" VALUE="Close Window"
ONCLICK="self.close()"></TD>
</TR>
<TR>
<TD COLSPAN="3">' . $this->vpi['outputPhpFile'] . '</TD>
</TR>
<TR>
<TD COLSPAN="2">
<TABLE BGCOLOR="#000000">
<TR>
<TD BGCOLOR="#FFFFFF"><IFRAME SRC="dom.txt" NORESIZE="NORESIZE"
SCROLLING="AUTO" HEIGHT="400" WIDTH="600" BORDER="0"
FRAMEBORDER="0"></IFRAME></TD>
</TR>
</TABLE></TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD><A NAME="xml">Page Output Dynamic XML</A></TD>
<TD ALIGN="RIGHT"><INPUT TYPE="BUTTON" VALUE="Close Window"
ONCLICK="self.close()"></TD>
</TR>
<TR>
<TD COLSPAN="2">
<TABLE BGCOLOR="#000000">
<TR>
<TD BGCOLOR="#FFFFFF"><IFRAME SRC="xml.txt"
NORESIZE="NORESIZE" SCROLLING="AUTO" HEIGHT="400" WIDTH="600" BORDER="0"
FRAMEBORDER="0"></IFRAME></TD>
</TR>
</TABLE></TD>
</TR>
<TR>
<TD COLSPAN="2"> </TD>
</TR>
<TR>
<TD><A NAME="xsl">Page Output XSL Stylesheet</A>:</TD>
<TD ALIGN="RIGHT"><INPUT TYPE="BUTTON" VALUE="Close Window"
ONCLICK="self.close()"></TD>
</TR>
<TR>
<TD COLSPAN="3">' . $this->vpi['xslFile'] . '</TD>
</TR>
<TR>
<TD COLSPAN="2">
<TABLE BGCOLOR="#000000">
<TR>
<TD BGCOLOR="#FFFFFF"><IFRAME SRC="page.xsl"
NORESIZE="NORESIZE" SCROLLING="AUTO" HEIGHT="400" WIDTH="600" BORDER="0"
FRAMEBORDER="0"></IFRAME></TD>
</TR>
</TABLE></TD>
</TR>
</TABLE></FORM> </BODY>
</HTML>
');
fflush($logHandle);
fclose($logHandle);
}
/**#@-*/
/**
* redirect page to new URL
*
* @param string redirect URL
* @param string is the redirect a dizzyPages URL
* <ul>
* <li> "Y" - Yes the URL is a dizzyPages URL
* <li> "N" - No the URL is not a dizzyPages URL
* </ul>
* @param string is the redirect caused by a user requesting an
* invalid navigation
* <ul>
* <li> "Y" - Yes the redirect was caused by an invalid navigation
* <li> "N" - No the redirect was not caused by an invalid navigation
* </ul>
* @return boolean true - redirect performed
* @throws -101, Redirect to [URL] failed the current page has already been redirected to [URL].
*/
public function redirect($url, $isDzeUrl = "Y", $isInvalidNav = "N") {
static $redirectUrl;
if ($this->isRedirected != 'Y') {
$this->isRedirected = 'Y';
$redirectUrl = $url;
header("HTTP/1.1 302 Moved Temporarily");
$fullUrl =
($isDzeUrl == "Y")
? "http://" . $_SERVER["HTTP_HOST"]
. ( $_SERVER["SERVER_PORT"] != "80"
? (":" . $_SERVER["SERVER_PORT"])
: "")
. $this->config["indexPage"]
. "?" . "url=" . $url
. "&" . "redirect=Y"
. "&" . $this->sesName . "=" . $this->sesExtId
. "&pageid=" . $this->pageId
: $url;
header("Location: " . $fullUrl);
if ($isInvalidNav == "Y") $this->setSesAttrib("common-SESSION-INVALID_NAV", "Y");
}
else throw new Exception("Redirect to '" . $url . "' failed the current page has already been redirected to '" . $redirectUrl . "'.", -101);
return true;
}
/**
* get session persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to retrieve
* @return string attribute value
*/
public function getSesAttrib($name, $rec = 1) {
return $this->getUserAttrib($name, $rec, $this->sesId);
}
/**
* get user persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to retrieve
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return string - attribute value
* @throws -111, The session is not logged in.
*/
public function getUserAttrib($name, $rec = 1, $userId = 0) {
# TODO handle values larger than 255 characters
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->select(
"DZE_USR_ATTRIB",
array("VALUE"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
$row = $this->sql->fetchAssoc();
$this->sql->freeResult();
$this->sql->popResult();
return $row["VALUE"];
}
/**
* delete a session persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to delete
* @return boolean true - attribute value deleted
*/
public function delSesAttrib($name, $rec = 1) {
return $this->delUserAttrib($name, $rec, $this->sesId);
}
/**
* delete a user persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to delete
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return boolean true - attribute value deleted
* @throws -111, The session is not logged in.
*/
public function delUserAttrib($name, $rec = 1, $userId = 0) {
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->delete(
"DZE_USR_ATTRIB",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
$this->sql->delete(
"DZE_USR_ATTRIB_ERR",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
$this->sql->query(
"update DZE_USR_ATTRIB"
. " set REC_ID = REC_ID - 1"
. " where USR_ID = " . $userId
. " and ATTRIB_NAME = '" . $name . "'"
. " and REC_ID > " . $rec
);
$this->sql->query(
"update DZE_USR_ATTRIB_ERR"
. " set REC_ID = REC_ID - 1"
. " where USR_ID = " . $userId
. " and ATTRIB_NAME = '" . $name . "'"
. " and REC_ID > " . $rec
);
$this->sql->popResult();
return true;
}
/**
* audit the deletion a session persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to audit
* @return boolean true - deletion of attribute value audited
*/
public function auditDelSesAttrib($name, $rec = 1) {
return $this->auditDelUserAttrib($name, $rec, $this->sesId);
}
/**
* audit the deletion a user persistent attribute value
*
* @param string attribute name
* @param integer optional record number of attribute to audit
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return boolean true - deletion of attribute value audited
* @throws -111, The session is not logged in.
*/
public function auditDelUserAttrib($name, $rec = 1, $userId = 0) {
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
// negative record ids in the audit table indicate deleted record
$this->sql->select(
"DZE_USR_ATTRIB_ADT",
array("min(REC_ID) REC_ID"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
)
);
$row = $this->sql->fetchAssoc();
$this->sql->freeResult();
$delRecId =
$row['REC_ID'] == 1
? -1
: $row['REC_ID'] - 1;
$this->sql->update(
"DZE_USR_ATTRIB_ADT",
array("REC_ID" => $delRecId),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
// time stamp deletion
$this->sql->insert(
"DZE_USR_ATTRIB_ADT",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $delRecId,
"CREATE_TS" => $this->pageTs,
"VALUE" => ""
)
);
$this->sql->query(
"update DZE_USR_ATTRIB_ADT"
. " set REC_ID = REC_ID - 1"
. " where USR_ID = " . $userId
. " and ATTRIB_NAME = '" . $name . "'"
. " and REC_ID > " . $rec
);
$this->sql->popResult();
return true;
}
/**
* get the outsatnding error of a session persistent attribute value
* entered in the last form processed
*
* @param string attribute name
* @param integer optional record number of attribute error to retrieve
* @return string error text
*/
public function getSesAttribError($name, $rec = 1) {
return $this->getUserAttribError($name, $rec, $this->sesId);
}
/**
* get the outsatnding error of a user persistent attribute value
* entered in the last form processed
*
* @param string attribute name
* @param integer optional record number of attribute error to retrieve
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return string error text or null if no error exists for the attribute
* @throws -111, The session is not logged in.
*/
public function getUserAttribError($name, $rec = 1, $userId = 0) {
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->select(
"DZE_USR_ATTRIB_ERR",
array("ERR_TXT"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
$row = $this->sql->fetchAssoc();
$this->sql->freeResult();
$this->sql->popResult();
return $row["ERR_TXT"];
}
/**
* set the outsatnding error of a session persistent attribute value
* entered in the last form processed
*
* @param string attribute name
* @param string error text
* @param integer optional record number of attribute error to set
* @return boolean true - error set
*/
public function setSesAttribError($name, $err_txt, $rec = 1) {
return $this->setUserAttribError($name, $err_txt, $rec, $this->sesId);
}
/**
* set the outsatnding error of a user persistent attribute value
* entered in the last form processed
*
* @param string attribute name
* @param string error text
* @param integer optional record number of attribute error to set
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return boolean true - error set
* @throws -111, The session is not logged in.
*/
public function setUserAttribError($name, $errText, $rec = 1, $userId = 0) {
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->select(
"DZE_USR_ATTRIB_ERR",
array("'X'"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
),
"FOR UPDATE"
);
if ($this->sql->fetchArray())
$this->sql->update("DZE_USR_ATTRIB_ERR",
array(
"ERR_TXT" => $errText
),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
else
$this->sql->insert("DZE_USR_ATTRIB_ERR",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec,
"ERR_TXT" => $errText
)
);
$this->sql->popResult();
return true;
}
/**
* get the user id of the current logged in user
*
* @return integer - user id
* @throws -111, The session is not logged in.
*/
public function getUserId() {
$retValue = $this->userId;
if (is_null($retValue))
throw new Exception("The session is not logged in.", -111);
return $retValue;
}
/**
* get the current session id
*
* @return integer session id
*/
public function getSesId() {
return $this->sesId;
}
/**
* set session persistent attribute value
*
* @param string attribute name
* @param string attribute value
* @param integer optional record number of attribute to set
* @return boolean true - attribute value set
*/
public function setSesAttrib($name, $value, $rec = 1) {
return $this->setUserAttrib($name, $value, $rec, $this->sesId);
}
/** or null if no error exists for the attribute
* set user persistent attribute value
*
* @param string attribute name
* @param string attribute value
* @param integer optional record number of attribute to set
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return boolean - attribute value set
* @throws -111, The session is not logged in.
*/
public function setUserAttrib($name, $value, $rec = 1, $userId = 0) {
# TODO handle values larger than 255 characters
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->select(
"DZE_USR_ATTRIB",
array("'X'"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
),
"FOR UPDATE"
);
if ($this->sql->fetchArray())
$this->sql->update("DZE_USR_ATTRIB",
array(
"VALUE" => (is_null($value) ? "" : $value),
"SET_TS" => $this->pageTs
),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec
)
);
else
$this->sql->insert("DZE_USR_ATTRIB",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec,
"VALUE" => (is_null($value) ? "" : $value),
"SET_TS" => $this->pageTs
)
);
$this->sql->popResult();
return true;
}
/**
* audit session attribute value
*
* @param string attribute name
* @param string attribute value
* @param integer optional record number of attribute to audit
* @return boolean true - attribute value audited
*/
public function auditSesAttrib($name, $value, $rec = 1) {
return $this->auditUserAttrib($name, $value, $rec, $this->sesId);
}
/**
* audit user attribute value
*
* @param string attribute name
* @param string attribute value
* @param integer optional record number of attribute to audit
* @param integer optional user id.
* If 0 the current logged in user's id is used.
* @return boolean true - attribute value audited
* @throws -111, The session is not logged in.
*/
public function auditUserAttrib($name, $value, $rec = 1, $userId = 0) {
# TODO handle values larger than 255 characters
if ($userId == 0) $userId = $this->getUserId();
$this->sql->pushResult();
$this->sql->select(
"DZE_USR_ATTRIB_ADT",
array("'X'"),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec,
"CREATE_TS" => $this->pageTs
),
"FOR UPDATE"
);
if ($this->sql->fetchArray())
// this should never happen on a default page
// only on a developer enhanced page
$this->sql->update("DZE_USR_ATTRIB_ADT",
array(
"VALUE" => (is_null($value) ? "" : $value),
),
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec,
"CREATE_TS" => $this->pageTs
)
);
else
$this->sql->insert("DZE_USR_ATTRIB_ADT", array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $name,
"REC_ID" => $rec,
"CREATE_TS" => $this->pageTs,
"VALUE" => (is_null($value) ? "" : $value)
));
$this->sql->popResult();
return true;
}
/**
* delete all attribute values of a form
*
* @param string form name
* @param integer optional user or session id
* If 0 the current session id is used.
* @return boolean true - form cleared
*/
public function clearForm($formName, $userId = 0) {
$this->sql->pushResult();
if ($userId == 0) $userId = $this->sesId;
$this->sql->select(
"DZE_ATTRIB_IN_FORM",
array("ATTRIB_NAME"),
array("FORM_NAME" => $formName)
);
while ($attrib = $this->sql->fetchAssoc()) {
$this->sql->pushResult();
$this->sql->delete(
"DZE_USR_ATTRIB",
array(
"USR_ID" => $userId,
"ATTRIB_NAME" => $attrib["ATTRIB_NAME"]
),
"and REC_ID > 0"
);
$this->sql->popResult();
}
$this->setUserAttrib("__CT__" . $formName, "0", 1, $userId);
$this->sql->freeResult();
$this->sql->popResult();
return true;
}
/**
* clear all outstanding form errors
*
* @param integer optional user or session id
* If 0 the current session id is used.
* @return boolean true - errors cleared
*/
public function clearErrors($userId = 0) {
$this->sql->pushResult();
if ($userId == 0) $userId = $this->sesId;
$this->sql->delete(
"DZE_USR_ATTRIB_ERR",
array("USR_ID" => $userId)
);
$this->sql->delete(
"DZE_USR_FORM_ERR",
array("USR_ID" => $userId)
);
$this->setUserAttrib("common-SESSION-PREVIOUS-FORM_ERR", "N", 1, $userId);
$this->sql->popResult();
return true;
}
/**
* set the logged in user for the current session
*
* @param string user id
* @param string user name
* @return boolean true - user set
* @throws -112, Session already has an assigned user id.
*/
public function setSesUser($userId, $userName) {
if (! is_null($this->userId))
throw new Exception("Session already has an assigned user id.", -112);
$this->sql->pushResult();
$this->userId = $userId;
$this->sql->update(
"DZE_SESSION",
array("REGISTER_USR_ID" => $userId),
array("SESSION_ID" => $this->sesExtId)
);
$this->userName = $userName;
$this->setSesAttrib('common-SESSION-USER-NAME', $userName);
$this->loginApp = $this->getAppFromUrl($this->previousUrl);
$this->setSesAttrib('common-SESSION-APP-NAME', $this->loginApp);
$this->copyUserErrorToSession();
$this->sql->popResult();
return true;
}
}
?>