Esempio n. 1
0
 /**
  * Construct a new DataObject.
  *
  * @param array|null $record This will be null for a new database record.  Alternatively, you can pass an array of
  * field values.  Normally this contructor is only used by the internal systems that get objects from the database.
  * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.  Singletons
  * don't have their defaults set.
  */
 function __construct($record = null, $isSingleton = false)
 {
     // Set the fields data.
     if (!$record) {
         $record = array("ID" => 0);
     }
     if (!is_array($record)) {
         if (is_object($record)) {
             $passed = "an object of type '{$record->class}'";
         } else {
             $passed = "The value '{$record}'";
         }
         user_error("DataObject::__construct passed {$passed}.  It's supposed to be passed an array,\n\t\t\t\ttaken straight from the database.  Perhaps you should use DataObject::get_one instead?", E_USER_WARNING);
         $record = null;
     }
     $this->record = $this->original = $record;
     // Keep track of the modification date of all the data sourced to make this page
     // From this we create a Last-Modified HTTP header
     if (isset($record['LastEdited'])) {
         HTTP::register_modification_date($record['LastEdited']);
     }
     parent::__construct();
     // Must be called after parent constructor
     if (!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) {
         $this->populateDefaults();
     }
     // prevent populateDefaults() and setField() from marking overwritten defaults as changed
     $this->changed = array();
 }
Esempio n. 2
0
 /**
  * Construct a new DataObject.
  *
  * @param array|null $record This will be null for a new database record.  Alternatively, you can pass an array of
  * field values.  Normally this contructor is only used by the internal systems that get objects from the database.
  * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.  Singletons
  * don't have their defaults set.
  */
 function __construct($record = null, $isSingleton = false, $model = null)
 {
     parent::__construct();
     // Set the fields data.
     if (!$record) {
         $record = array('ID' => 0, 'ClassName' => get_class($this), 'RecordClassName' => get_class($this));
     }
     if (!is_array($record)) {
         if (is_object($record)) {
             $passed = "an object of type '{$record->class}'";
         } else {
             $passed = "The value '{$record}'";
         }
         user_error("DataObject::__construct passed {$passed}.  It's supposed to be passed an array,\n\t\t\ttaken straight from the database.  Perhaps you should use DataList::create()->First(); instead?", E_USER_WARNING);
         $record = null;
     }
     // Set $this->record to $record, but ignore NULLs
     $this->record = array();
     foreach ($record as $k => $v) {
         // Ensure that ID is stored as a number and not a string
         // To do: this kind of clean-up should be done on all numeric fields, in some relatively
         // performant manner
         if ($v !== null) {
             if ($k == 'ID' && is_numeric($v)) {
                 $this->record[$k] = (int) $v;
             } else {
                 $this->record[$k] = $v;
             }
         }
     }
     // Identify fields that should be lazy loaded, but only on existing records
     if (!empty($record['ID'])) {
         $currentObj = get_class($this);
         while ($currentObj != 'DataObject') {
             $fields = self::custom_database_fields($currentObj);
             foreach ($fields as $field => $type) {
                 if (!array_key_exists($field, $record)) {
                     $this->record[$field . '_Lazy'] = $currentObj;
                 }
             }
             $currentObj = get_parent_class($currentObj);
         }
     }
     $this->original = $this->record;
     // Keep track of the modification date of all the data sourced to make this page
     // From this we create a Last-Modified HTTP header
     if (isset($record['LastEdited'])) {
         HTTP::register_modification_date($record['LastEdited']);
     }
     // Must be called after parent constructor
     if (!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) {
         $this->populateDefaults();
     }
     // prevent populateDefaults() and setField() from marking overwritten defaults as changed
     $this->changed = array();
     $this->model = $model ? $model : DataModel::inst();
 }
Esempio n. 3
0
	/**
	 * Construct a new DataObject.
	 *
	 * @param array|null $record This will be null for a new database record.  Alternatively, you can pass an array of
	 * field values.  Normally this contructor is only used by the internal systems that get objects from the database.
	 * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.  Singletons
	 * don't have their defaults set.
	 */
	function __construct($record = null, $isSingleton = false, $model = null) {
		// Set the fields data.
		if(!$record) {
			$record = array(
				'ID' => 0,
				'ClassName' => get_class($this),
				'RecordClassName' => get_class($this)
			);
		}

		if(!is_array($record)) {
			if(is_object($record)) $passed = "an object of type '$record->class'";
			else $passed = "The value '$record'";

			user_error("DataObject::__construct passed $passed.  It's supposed to be passed an array,
			taken straight from the database.  Perhaps you should use DataList::create()->First(); instead?", E_USER_WARNING);
			$record = null;
		}

		// Convert PostgreSQL boolean values
		// TODO: Implement this more elegantly, for example by writing a more intelligent SQL SELECT query prior to object construction
		if(DB::getConn() instanceof PostgreSQLDatabase) {
			$this->class = get_class($this);
			foreach($record as $k => $v) {
				if($this->db($k) == 'Boolean' && $v == 'f') $record[$k] = '0';
			}
		}
		
		// TODO: MSSQL has a convert function that can do this on the SQL end. We just need a
		// nice way of telling the database how we want to get the value out on a per-fieldtype basis
		if(DB::getConn() instanceof MSSQLDatabase) {
			$this->class = get_class($this);
			foreach($record as $k => $v) {
				if($v) {
					if($k == 'Created' || $k == 'LastEdited') {
						$fieldtype = 'SS_Datetime';
					} else {
						$fieldtype = $this->db($k);
					}
				
					// MSSQLDatabase::date() uses datetime for the data type for "Date" and "SS_Datetime"
					switch($fieldtype) {
						case "Date":
							$v = preg_replace('/:[0-9][0-9][0-9]([ap]m)$/i', ' \\1', $v);
							$record[$k] = date('Y-m-d', strtotime($v));
							break;
					
						case "Datetime":
						case "SS_Datetime":
							$v = preg_replace('/:[0-9][0-9][0-9]([ap]m)$/i', ' \\1', $v);
							$record[$k] = date('Y-m-d H:i:s', strtotime($v));
							break;
					}
				}
			}
		}

		// Set $this->record to $record, but ignore NULLs
		$this->record = array();
		foreach($record as $k => $v) {
			// Ensure that ID is stored as a number and not a string
			// To do: this kind of clean-up should be done on all numeric fields, in some relatively
			// performant manner
			if($v !== null) {
				if($k == 'ID' && is_numeric($v)) $this->record[$k] = (int)$v;
				else $this->record[$k] = $v;
			}
		}
		$this->original = $this->record;

		// Keep track of the modification date of all the data sourced to make this page
		// From this we create a Last-Modified HTTP header
		if(isset($record['LastEdited'])) {
			HTTP::register_modification_date($record['LastEdited']);
		}

		parent::__construct();

		// Must be called after parent constructor
		if(!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) {
			$this->populateDefaults();
		}

		// prevent populateDefaults() and setField() from marking overwritten defaults as changed
		$this->changed = array();
		
		$this->model = $model ? $model : DataModel::inst();
	}