Beispiel #1
0
 /**
  * Process the variable stack scope (pagevars, stackvars).
  *
  * @param array $postvars The http request variables.
  */
 protected function _stackscope(&$postvars)
 {
     $sessionData =& self::getSession();
     // session vars are valid until they are set to something else. if you go a session level higher,
     // the next level will still contain these vars (unless overriden in the url)
     $sessionVars = array('atknodeuri', 'atkfilter', 'atkaction', 'atkpkret', 'atkstore', 'atkstore_key');
     // pagevars are valid on a page. if you go a session level higher, the pagevars are no longer
     // visible until you return. if the name ends in a * the pagevar is treated as an array that
     // needs to be merged recursive with new postvar values
     $pageVars = array('atkdg*', 'atkdgsession', 'atksearch', 'atkselector', 'atksearchmode', 'atkorderby', 'atkstartat', 'atklimit', 'atktarget', 'atkformdata', 'atktree', 'atksuppress', 'atktab', 'atksmartsearch', 'atkindex');
     // lockedvars are session or page vars that will not be overwritten in partial mode
     // e.g., the values that are already known in the session will be used
     $lockedVars = array('atknodeuri', 'atkaction', 'atkselector');
     // Mental note: We have an $this->atkLevel() function for retrieving the atklevel,
     // but we use the global var itself here, because it gets modified in
     // the stackscope function.
     if (!isset($this->atklevel) || $this->atklevel == '') {
         $this->atklevel = 0;
     }
     Tools::atkdebug('ATKLevel: ' . $this->atklevel);
     if ($this->_verifyStackIntegrity() && $this->atklevel == -1) {
         // New stack, new stackid, if level = -1.
         $stackid = $this->atkStackID($this->atklevel == -1);
     } else {
         $stackid = $this->atkStackID();
     }
     $stack =& $sessionData[$this->m_namespace]['stack'][$stackid];
     // garbage collect
     $this->_touchCurrentStack();
     $this->_removeExpiredStacks();
     // Prevent going more than 1 level above the current stack top which
     // causes a new stackitem to be pushed onto the stack at the wrong
     // location.
     if ($this->atklevel > count($stack)) {
         Tools::atkdebug('Requested ATKLevel (' . $this->atklevel . ') too high for stack, lowering to ' . count($stack));
         $this->atklevel = count($stack);
     }
     if (isset($postvars['atkescape']) && $postvars['atkescape'] != '') {
         $this->m_escapemode = true;
         Tools::atkdebug('ATK session escapemode');
         $currentitem =& $stack[count($stack) - 1];
         Tools::atkdebug('Saving formdata in session');
         unset($currentitem['atkreject']);
         // clear old reject info
         $atkformdata = [];
         foreach (array_keys($postvars) as $varname) {
             // Only save formdata itself, hence no $atk.. variables.
             // Except atktab because it could be changed in the page load.
             // but why don't we save all page vars here? What is the reason for
             // not doing this? TODO: Ask Ivo.
             if (substr($varname, 0, 3) != 'atk' || $varname == 'atktab') {
                 $atkformdata[$varname] = $postvars[$varname];
             }
         }
         $currentitem['atkformdata'] = $atkformdata;
         // also remember getvars that were passed in the url
         // this *may not be* $_REQUEST, because then the posted vars
         // will be overwritten, which may not be done in escape mode,
         // I wonder if the next few lines are necessary at all, but
         // I think I needed them once, so I'll leave it in place.
         foreach (array_keys($_GET) as $var) {
             if (isset($postvars[$var]) && $postvars[$var] != '') {
                 $currentitem[$var] = $postvars[$var];
             }
         }
         // finally, reset atkescape to prevent atk from keeping escaping upon return
         unset($currentitem['atkescape']);
     } else {
         // partial mode?
         $partial = false;
         if ($this->atklevel == -1 || !is_array($stack)) {
             // SessionManager::SESSION_NEW
             Tools::atkdebug('Cleaning stack');
             $stack = [];
             $this->atklevel = 0;
         } else {
             if ($this->atklevel == -2) {
                 // SessionManager::SESSION_REPLACE
                 // Replace top level.
                 array_pop($stack);
                 // Note that the atklevel is now -2. This is actually wrong. We are at
                 // some level in the stack. We can determine the real level by
                 // counting the stack.
                 $this->atklevel = count($stack);
             } else {
                 if ($this->atklevel == -3) {
                     // SessionManager::SESSION_PARTIAL
                     $partial = true;
                     // Note that the atklevel is now -3. This is actually wrong. We are at
                     // some level in the stack. We can determine the real level by
                     // counting the stack.
                     $this->atklevel = count($stack) - 1;
                 }
             }
         }
         if (isset($stack[$this->atklevel])) {
             $currentitem = $stack[$this->atklevel];
         }
         if (!isset($currentitem) || $currentitem == '') {
             Tools::atkdebug('New level on session stack');
             // Initialise
             $currentitem = [];
             // new level.. always based on the previous level
             if (isset($stack[count($stack) - 1])) {
                 $copieditem = $stack[count($stack) - 1];
             }
             if (isset($copieditem) && is_array($copieditem)) {
                 foreach ($copieditem as $key => $value) {
                     if (in_array($key, $sessionVars) || isset($copieditem['defined_stackvars']) && is_array($copieditem['defined_stackvars']) && in_array($key, $copieditem['defined_stackvars'])) {
                         $currentitem[$key] = $value;
                     }
                 }
                 if (isset($copieditem['defined_stackvars'])) {
                     $currentitem['defined_stackvars'] = $copieditem['defined_stackvars'];
                 }
             }
             // Posted vars always overwrite anything in the current session..
             foreach (array_merge($pageVars, $sessionVars) as $var) {
                 $recursive = $var[strlen($var) - 1] == '*';
                 $var = $recursive ? substr($var, 0, -1) : $var;
                 if (isset($postvars[$var]) && $postvars[$var] != '') {
                     if ($postvars[$var] == 'clear') {
                         $currentitem[$var] = '';
                     } else {
                         if ($recursive && is_array($currentitem[$var]) && is_array($postvars[$var])) {
                             $currentitem[$var] = array_merge_recursive($currentitem[$var], $postvars[$var]);
                         } else {
                             $currentitem[$var] = $postvars[$var];
                         }
                     }
                 }
             }
             array_push($stack, $currentitem);
         } else {
             // Stay at the current level..
             // If we are getting back from a higher level, we may now delete everything above
             $deletecount = count($stack) - 1 - $this->atklevel;
             for ($i = 0; $i < $deletecount; ++$i) {
                 Tools::atkdebug('popped an item out of the stack');
                 array_pop($stack);
             }
             foreach ($pageVars as $var) {
                 $recursive = $var[strlen($var) - 1] == '*';
                 $var = $recursive ? substr($var, 0, -1) : $var;
                 if (isset($postvars[$var]) && count($postvars[$var]) > 0 && (!$partial || !in_array($var, $lockedVars))) {
                     if ($recursive && isset($currentitem[$var]) && is_array($currentitem[$var]) && is_array($postvars[$var])) {
                         $currentitem[$var] = Tools::atk_array_merge_recursive($currentitem[$var], $postvars[$var]);
                     } else {
                         $currentitem[$var] = $postvars[$var];
                     }
                 }
             }
             // page vars must overwrite the current stack..
             $stack[$this->atklevel] =& $currentitem;
             // session vars need not be remembered..
             foreach ($sessionVars as $var) {
                 if (isset($postvars[$var]) && count($postvars[$var]) > 0 && (!$partial || !in_array($var, $lockedVars))) {
                     $currentitem[$var] = $postvars[$var];
                 }
             }
         }
         if (isset($currentitem['atkformdata']) && is_array($currentitem['atkformdata'])) {
             Tools::atkdebug('Session formdata present');
             foreach ($currentitem['atkformdata'] as $var => $value) {
                 // don't override what was passed in the url.
                 if (!isset($postvars[$var])) {
                     $postvars[$var] = $value;
                 } else {
                     if (is_array($postvars[$var]) && is_array($value)) {
                         // Formdata that was posted earlier needs to be merged with the current
                         // formdata. We use a custom array_merge here to preserve key=>value pairs.
                         $postvars[$var] = Tools::atk_array_merge_keys($value, $postvars[$var]);
                     }
                 }
             }
             // We leave atkformdata in the current stack entry untouched so that
             // when the stack might be forked of whatsoever the form data is still
             // present. However, this data should not be directly accessed in the node!
         }
         if (is_array($currentitem)) {
             foreach ($currentitem as $var => $value) {
                 $recursive = in_array("{$var}*", $pageVars);
                 // don't override what was passed in the url except for
                 // recursive mergeable pagevars
                 if ($recursive || !isset($postvars[$var])) {
                     $postvars[$var] = $value;
                 }
             }
         }
     }
     // end if atkescape
 }