| 
<?phpnamespace Jackbooted\Forms;
 
 use \Jackbooted\Html\Tag;
 use \Jackbooted\Html\WebPage;
 use \Jackbooted\Security\Cryptography;
 use \Jackbooted\Security\CSRFGuard;
 use \Jackbooted\Security\TamperGuard;
 /**
 * @copyright Confidential and copyright (c) 2016 Jackbooted Software. All rights reserved.
 *
 * Written by Brett Dutton of Jackbooted Software
 * brett at brettdutton dot com
 *
 * This software is written and distributed under the GNU General Public
 * License which means that its source code is freely-distributed and
 * available to the general public.
 */
 
 /**
 * Response - Created Hidden variables and URLs for the Response Vars
 */
 class Response  extends PipeLine {
 const UNIQUE_CSRF = 'unique guard';
 
 private static $crossSiteGuard = null;
 private static $ignoreCrossSiteGuard = false;
 
 private $intermediateUrlArray;
 private $intermediateHiddenArray;
 private $exemptKeys =  [];
 
 /**
 * @param  $initPattern
 * @return Response
 */
 public static function factory ( $initPattern=null ) {
 return new Response ( $initPattern );
 }
 
 /**
 * @param  $initPattern
 * @return void
 */
 public function  __construct( $initPattern=null ) {
 parent::__construct();
 // If there is a pattern passed thru then copy from request
 if ( $initPattern != null ) $this->copyVarsFromRequest ( $initPattern );
 
 $this->copyVarsFromRequest ( WebPage::SAVE_URL );
 
 // Ensure that the known fields
 foreach ( TamperGuard::$knownFields as $key ) {
 $this->copyVarsFromRequest ( $key );
 $this->addExempt ( $key );
 }
 }
 
 /**
 * @param  $key
 * @return void
 */
 public function addExempt ( $key ) {
 $this->exemptKeys[$key] = true;
 return $this;
 }
 
 /**
 * @param  $key
 * @param  $val
 * @param bool $encrypt
 * @return Response
 */
 public function set ( $key, $val ) {
 $this->formVars[$key] = $val;
 return $this;
 }
 
 /**
 * @param  $val
 * @return Response
 */
 public function action ( $val ) {
 $this->formVars[WebPage::ACTION] = $val;
 return $this;
 }
 
 /**
 * @param  $key
 * @return Response
 */
 public function del ( $key ) {
 unset ( $this->formVars[$key] );
 return $this;
 }
 
 /**
 * @param string $matches
 * @return Response
 */
 public function copyVarsFromRequest ( $matches='/.*/') {
 if ( ! preg_match ( '/^\\/.*\\/$/', $matches ) ) $matches = '/^' . $matches . '$/';
 
 foreach ( Request::get () as $key => $val) {
 if ( preg_match ( $matches, $key) ) $this->set ( $key, $val );
 }
 return $this;
 }
 
 private function addCSRFGuard () {
 if ( self::$ignoreCrossSiteGuard ) return;
 
 if ( self::$crossSiteGuard == null ) {
 self::$crossSiteGuard = CSRFGuard::key();
 }
 $this->set ( CSRFGuard::KEY, self::$crossSiteGuard );
 }
 
 private function delCSRFGuard () {
 $this->del ( CSRFGuard::KEY );
 }
 /**
 * @return string
 */
 public function toHidden ( $guard=true ) {
 if ( $guard ) $this->addCSRFGuard ();
 TamperGuard::add ( $this );
 
 $html = '';
 $this->convertFormVarsToAssocArray ();
 foreach ( $this->intermediateHiddenArray as $key => $val ) {
 $cypherText = $this->encryptValue ( $key, $val );
 $html .= Tag::hidden ( $key, $cypherText );
 }
 
 TamperGuard::del ( $this );
 if ( $guard ) $this->delCSRFGuard ();
 return $html;
 }
 
 private function convertFormVarsToAssocArray () {
 $this->intermediateHiddenArray =  [];
 foreach ( $this->formVars as $key => $val ) {
 $this->arrayWalkerToConvertToAssoc ( $key, $val );
 }
 }
 
 private function arrayWalkerToConvertToAssoc ( $key, &$value, $prefix='' ) {
 $subKey = ( $prefix == '' ) ? $key : '[' . $key . ']';
 $compoundKey = $prefix . $subKey;
 
 if ( is_array ( $value ) ) {
 foreach ( $value as $key => $val ) {
 $this->arrayWalkerToConvertToAssoc ( $key, $val, $compoundKey );
 }
 }
 else {
 $this->intermediateHiddenArray[$compoundKey] = $value;
 }
 }
 
 /**
 * @return string
 */
 public function toUrl ( $guard=false ) {
 if ( $guard === true ) $this->addCSRFGuard ();
 else if ( $guard == self::UNIQUE_CSRF ) {
 $tempGuard = self::$crossSiteGuard;
 self::$crossSiteGuard = null;
 $this->addCSRFGuard ();
 self::$crossSiteGuard = $tempGuard;
 }
 
 TamperGuard::add ( $this );
 $this->convertFormVarsToFlatArray ();
 TamperGuard::del ( $this );
 if ( $guard ) $this->delCSRFGuard ();
 return join ( '&', $this->intermediateUrlArray );
 }
 
 public function  __toString () {
 return $this->toUrl ();
 }
 
 private function convertFormVarsToFlatArray () {
 $this->intermediateUrlArray =  [];
 foreach ( $this->formVars as $key => $val ) {
 $this->arrayWalkerToConvertToFlat ( $key, $val );
 }
 }
 
 private function arrayWalkerToConvertToFlat ( $key, &$value, $prefix='' ) {
 $subKey = ( $prefix == '' ) ? $key : '[' . $key . ']';
 $compoundKey = $prefix . $subKey;
 
 if ( is_array ( $value ) ) {
 foreach ( $value as $key => $val ) {
 $this->arrayWalkerToConvertToFlat ( $key, $val, $compoundKey );
 }
 }
 else {
 $cypherText = $this->encryptValue ( $compoundKey, $value );
 $this->intermediateUrlArray[] = $compoundKey . '=' . urlencode ( $cypherText );
 }
 }
 
 private function encryptValue ( $key, $value ) {
 if ( isset ( $this->exemptKeys[$key] ) ) {
 return $value;
 }
 else {
 return Cryptography::en ( $value );
 }
 }
 }
 |