Exemple #1
0
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // Load the request headers. If we're not running on Apache, then we
     // need to manually extract the headers from the $_SERVER array.
     if (function_exists('apache_request_headers')) {
         $headers = apache_request_headers();
     } else {
         $headers = self::extract_request_headers($_SERVER);
     }
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session, $model);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, array_merge((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     // @todo find better way to extract HTTP headers
     if (isset($_SERVER['HTTP_ACCEPT'])) {
         $req->addHeader("Accept", $_SERVER['HTTP_ACCEPT']);
     }
     if (isset($_SERVER['CONTENT_TYPE'])) {
         $req->addHeader("Content-Type", $_SERVER['CONTENT_TYPE']);
     }
     if (isset($_SERVER['HTTP_REFERER'])) {
         $req->addHeader("Referer", $_SERVER['HTTP_REFERER']);
     }
     // Load the session into the controller
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $result = Director::handleRequest($req, $session);
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $response->output();
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             // ?debug_memory=1 will output the number of bytes of memory used for this request
             if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                 Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
             } else {
                 $response->output();
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  *
  * Request processing is handled as follows:
  * - Director::direct() creates a new SS_HTTPResponse object and passes this to
  *   Director::handleRequest().
  * - Director::handleRequest($request) checks each of the Director rules and identifies a controller
  *   to handle this request.
  * - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL,
  *   and call the rule handling method.
  * - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method
  *   returns a RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of
  * the actual response to the browser.
  *
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  *
  * @param string $url
  * @param DataModel $model
  *
  * @throws SS_HTTPResponse_Exception
  */
 public static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, ArrayLib::array_merge_recursive((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     $headers = self::extract_request_headers($_SERVER);
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Initiate an empty session - doesn't initialize an actual PHP session until saved (see below)
     $session = Injector::inst()->create('Session', isset($_SESSION) ? $_SESSION : array());
     // Only resume a session if its not started already, and a session identifier exists
     if (!isset($_SESSION) && Session::request_contains_session_id()) {
         $session->inst_start();
     }
     $output = Injector::inst()->get('RequestProcessor')->preRequest($req, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     $result = Director::handleRequest($req, $session, $model);
     // Save session data. Note that inst_save() will start/resume the session if required.
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $url = substr($result, 9);
         if (Director::is_cli()) {
             // on cli, follow SilverStripe redirects automatically
             return Director::direct(str_replace(Director::absoluteBaseURL(), '', $url), DataModel::inst());
         } else {
             $response = new SS_HTTPResponse();
             $response->redirect($url);
             $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
             if ($res !== false) {
                 $response->output();
             }
         }
         // Handle a controller
     } elseif ($result) {
         if ($result instanceof SS_HTTPResponse) {
             $response = $result;
         } else {
             $response = new SS_HTTPResponse();
             $response->setBody($result);
         }
         $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
         if ($res !== false) {
             $response->output();
         } else {
             // @TODO Proper response here.
             throw new SS_HTTPResponse_Exception("Invalid response");
         }
         //$controllerObj->getSession()->inst_save();
     }
 }
Exemple #4
0
	/**
	 * Called on save, it creates the appropriate objects and writes them
	 * to the database.
	 * 
	 * @param SS_List $dataObjects
	 * @param boolean $existingValues If set to TRUE, it tries to find existing objects
	 *  based on the database IDs passed as array keys in $dataObjects parameter.
	 *  If set to FALSE, it will always create new object (default: TRUE)
	 * @return array Array of saved object IDs in the key, and the status ("Updated") in the value
	 */
	function saveData($dataObjects, $existingValues = true) {
		if(!$dataObjects) return false;

		$savedObjIds = array();
		$fieldset = $this->FieldSetForRow();

		// add hiddenfields
		if($this->extraData) {
			foreach($this->extraData as $fieldName => $fieldValue) {
				$fieldset->push(new HiddenField($fieldName));
			}
		}

		$form = new Form($this, null, $fieldset, new FieldList());

		foreach ($dataObjects as $objectid => $fieldValues) {
			// 'new' counts as an empty column, don't save it
			if($objectid === "new") continue;

			// extra data was creating fields, but
			if($this->extraData) {
				$fieldValues = array_merge( $this->extraData, $fieldValues );
			}

			// either look for an existing object, or create a new one
			if($existingValues) {
				$obj = DataObject::get_by_id($this->sourceClass(), $objectid);
			} else {
				$sourceClass = $this->sourceClass();
				$obj = new $sourceClass();
			}

			// Legacy: Use the filter as a predefined relationship-ID 
			if($this->filterField && $this->filterValue) {
				$filterField = $this->filterField;
				$obj->$filterField = $this->filterValue;
			}

			// Determine if there is changed data for saving
			$dataFields = array();
			foreach($fieldValues as $type => $value) {
				// if the field is an actual datafield (not a preset hiddenfield)
				if(is_array($this->extraData)) { 
					if(!in_array($type, array_keys($this->extraData))) {
						$dataFields[$type] = $value;
					}
				// all fields are real 
				} else {  
					$dataFields[$type] = $value;
				}
			}
			$dataValues = ArrayLib::array_values_recursive($dataFields);
			// determine if any of the fields have a value (loose checking with empty())
			$hasData = false;
			foreach($dataValues as $value) {
				if(!empty($value)) $hasData = true;
			}

			if($hasData) {
				$form->loadDataFrom($fieldValues, true);
				$form->saveInto($obj);

				$objectid = $obj->write();

				$savedObjIds[$objectid] = "Updated";
			}

		}

		return $savedObjIds;
   }
	/**
	 * Called on save, it creates the appropriate objects and writes them
	 * to the database.
	 */
	function saveData($dataObjects,$ExistingValues = true) {
      $savedObj = array();
      $fieldset = $this->FieldSetForRow();
	    
      // add hiddenfields
      if($this->extraData) {
         foreach($this->extraData as $fieldName => $fieldValue) {
				$fieldset->push(new HiddenField($fieldName));
			}
       }
		
	    $form = new Form($this, null, $fieldset, new FieldSet());

       if($dataObjects) {
			foreach ($dataObjects as $objectid => $fieldValues) {
            // we have to "sort" new data first, and process it in a seperate saveData-call (see setValue())
           	if($objectid === "new") continue;

	        // extra data was creating fields, but
	        if($this->extraData) {
              $fieldValues = array_merge( $this->extraData, $fieldValues );
	        }
        
	        $hasData = false;
	        $obj = new $this->sourceClass();
				
           if($ExistingValues) {
				$obj = DataObject::get_by_id($this->sourceClass, $objectid);
           }

				// Legacy: Use the filter as a predefined relationship-ID 
				if($this->filterField && $this->filterValue) {
					$filterField = $this->filterField;
					$obj->$filterField = $this->filterValue;
				}
			
				// Determine if there is changed data for saving
				$dataFields = array();
			
				foreach($fieldValues as $type => $value) {
					if(is_array($this->extraData)){ // if the field is an actual datafield (not a preset hiddenfield)
						if(!in_array($type, array_keys($this->extraData))) {
							$dataFields[$type] = $value;
						}
					} else {  // all fields are real 
						$dataFields[$type] = $value;
					}					
				}
		
				$dataValues = ArrayLib::array_values_recursive($dataFields);
		
				foreach($dataValues as $value) {
					if(!empty($value)) {
						$hasData = true;
					}
				}

				// save
				if($hasData) {
					$form->loadDataFrom($fieldValues, true);
					$form->saveInto($obj);
								
					$objectid = $obj->write();
				
					$savedObj[$objectid] = "Updated";
				}

			}
		   return $savedObj;
	   } else {
	      return false;
	   }
   }
 /**
  * Process the given URL, creating the appropriate controller and executing it.
  * 
  * Request processing is handled as follows:
  *  - Director::direct() creates a new SS_HTTPResponse object and passes this to Director::handleRequest().
  *  - Director::handleRequest($request) checks each of the Director rules and identifies a controller to handle this 
  *    request.
  *  - Controller::handleRequest($request) is then called.  This will find a rule to handle the URL, and call the rule
  *    handling method.
  *  - RequestHandler::handleRequest($request) is recursively called whenever a rule handling method returns a
  *    RequestHandler object.
  *
  * In addition to request processing, Director will manage the session, and perform the output of the actual response
  * to the browser.
  * 
  * @param $url String, the URL the user is visiting, without the querystring.
  * @uses handleRequest() rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function direct($url, DataModel $model)
 {
     // Validate $_FILES array before merging it with $_POST
     foreach ($_FILES as $k => $v) {
         if (is_array($v['tmp_name'])) {
             $v = ArrayLib::array_values_recursive($v['tmp_name']);
             foreach ($v as $tmpFile) {
                 if ($tmpFile && !is_uploaded_file($tmpFile)) {
                     user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
                 }
             }
         } else {
             if ($v['tmp_name'] && !is_uploaded_file($v['tmp_name'])) {
                 user_error("File upload '{$k}' doesn't appear to be a valid upload", E_USER_ERROR);
             }
         }
     }
     $req = new SS_HTTPRequest(isset($_SERVER['X-HTTP-Method-Override']) ? $_SERVER['X-HTTP-Method-Override'] : $_SERVER['REQUEST_METHOD'], $url, $_GET, ArrayLib::array_merge_recursive((array) $_POST, (array) $_FILES), @file_get_contents('php://input'));
     $headers = self::extract_request_headers($_SERVER);
     foreach ($headers as $header => $value) {
         $req->addHeader($header, $value);
     }
     // Only resume a session if its not started already, and a session identifier exists
     if (!isset($_SESSION) && (isset($_COOKIE[session_name()]) || isset($_REQUEST[session_name()]))) {
         Session::start();
     }
     // Initiate an empty session - doesn't initialize an actual PHP session until saved (see belwo)
     $session = new Session(isset($_SESSION) ? $_SESSION : null);
     $output = Injector::inst()->get('RequestProcessor')->preRequest($req, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     $result = Director::handleRequest($req, $session, $model);
     // Save session data (and start/resume it if required)
     $session->inst_save();
     // Return code for a redirection request
     if (is_string($result) && substr($result, 0, 9) == 'redirect:') {
         $response = new SS_HTTPResponse();
         $response->redirect(substr($result, 9));
         $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
         if ($res !== false) {
             $response->output();
         }
         // Handle a controller
     } else {
         if ($result) {
             if ($result instanceof SS_HTTPResponse) {
                 $response = $result;
             } else {
                 $response = new SS_HTTPResponse();
                 $response->setBody($result);
             }
             $res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
             if ($res !== false) {
                 // ?debug_memory=1 will output the number of bytes of memory used for this request
                 if (isset($_REQUEST['debug_memory']) && $_REQUEST['debug_memory']) {
                     Debug::message(sprintf("Peak memory usage in bytes: %s", number_format(memory_get_peak_usage(), 0)));
                 } else {
                     $response->output();
                 }
             } else {
                 // @TODO Proper response here.
                 throw new SS_HTTPResponse_Exception("Invalid response");
             }
             //$controllerObj->getSession()->inst_save();
         }
     }
 }