示例#1
0
 /**
  * Loads a record from the database
  * 
  * @throws fNotFoundException  When the record could not be found in the database
  * 
  * @return fActiveRecord  The record object, to allow for method chaining
  */
 public function load()
 {
     $class = get_class($this);
     $db = fORMDatabase::retrieve($class, 'read');
     $schema = fORMSchema::retrieve($class);
     if (fORM::getActiveRecordMethod($class, 'load')) {
         return $this->__call('load', array());
     }
     try {
         $table = fORM::tablize($class);
         $params = array('SELECT * FROM %r WHERE ', $table);
         $params = fORMDatabase::addPrimaryKeyWhereParams($schema, $params, $table, $table, $this->values, $this->old_values);
         $result = call_user_func_array($db->translatedQuery, $params);
         $result->tossIfNoRows();
     } catch (fExpectedException $e) {
         throw new fNotFoundException('The %s requested could not be found', fORM::getRecordName($class));
     }
     $this->loadFromResult($result, TRUE);
     // Clears the cached related records so they get pulled from the database
     $this->related_records = array();
     return $this;
 }
 /**
  * Re-orders the object based on it's current state and new position
  *
  * @internal
  *
  * @param  fActiveRecord $object            The fActiveRecord instance
  * @param  array         &$values           The current values
  * @param  array         &$old_values       The old values
  * @param  array         &$related_records  Any records related to this record
  * @param  array         &$cache            The cache array for the record
  * @return void
  */
 public static function reorder($object, &$values, &$old_values, &$related_records, &$cache)
 {
     $class = get_class($object);
     $table = fORM::tablize($class);
     $db = fORMDatabase::retrieve($class, 'write');
     $schema = fORMSchema::retrieve($class);
     foreach (self::$ordering_columns[$class] as $column => $other_columns) {
         $current_value = $values[$column];
         if (!$object->exists()) {
             $old_value = fActiveRecord::retrieveOld($old_values, $column);
         } else {
             $params = array("SELECT %r FROM %r WHERE ", $column, $table);
             $params = fORMDatabase::addPrimaryKeyWhereParams($schema, $params, $table, $table, $values, $old_values);
             $old_value = call_user_func_array($db->translatedQuery, $params)->fetchScalar();
         }
         // Figure out the range we are dealing with
         $params = array("SELECT MAX(%r) FROM %r", $column, $table);
         if ($other_columns) {
             $params[0] .= ' WHERE ';
             $params = self::addOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values);
         }
         $current_max_value = (int) call_user_func_array($db->translatedQuery, $params)->fetchScalar();
         $new_max_value = $current_max_value;
         if ($new_set = self::isInNewSet($column, $other_columns, $values, $old_values)) {
             $new_max_value = $current_max_value + 1;
         }
         $changed = FALSE;
         // If a blank value was set, correct it to the old value (if there
         // was one), or a new value at the end of the set
         if ($current_value === '' || $current_value === NULL) {
             if ($old_value) {
                 $current_value = $old_value;
             } else {
                 $current_value = $new_max_value;
             }
             $changed = TRUE;
         }
         // When we move an object into a new set and the value didn't change then move it to the end of the new set
         if ($new_set && $object->exists() && ($old_value === NULL || $old_value == $current_value)) {
             $current_value = $new_max_value;
             $changed = TRUE;
         }
         // If the value is too high, then set it to the last value
         if ($current_value > $new_max_value) {
             $current_value = $new_max_value;
             $changed = TRUE;
         }
         if ($changed) {
             fActiveRecord::assign($values, $old_values, $column, $current_value);
         }
         // If the value didn't change, we can exit
         $value_didnt_change = $old_value && $current_value == $old_value || !$old_value;
         if (!$new_set && $value_didnt_change) {
             continue;
         }
         // If we are entering a new record at the end of the set we don't need to shuffle anything either
         if (!$object->exists() && $new_set && $current_value == $new_max_value) {
             continue;
         }
         // If the object already exists in the database, grab the ordering value
         // right now in case some other object reordered it since it was loaded
         if ($object->exists()) {
             $params = array("SELECT %r FROM %r WHERE ", $column, $table);
             $params = fORMDatabase::addPrimaryKeyWhereParams($schema, $params, $table, $table, $values, $old_values);
             $db_value = (int) call_user_func_array($db->translatedQuery, $params)->fetchScalar();
         }
         // We only need to move things in the new set around if we are inserting into the middle
         // of a new set, or if we are moving around in the current set
         if (!$new_set || $new_set && $current_value != $new_max_value) {
             $shift_down = $new_max_value + 10;
             // To prevent issues with the unique constraint, we move everything below 0
             $params = array("UPDATE %r SET %r = %r - %i WHERE ", $table, $column, $column, $shift_down);
             $conditions = array();
             // If we are moving into the middle of a new set we just push everything up one value
             if ($new_set) {
                 $shift_up = $new_max_value + 11;
                 $conditions[] = fORMDatabase::makeCondition($schema, $table, $column, '>=', $current_value);
                 $params[] = $table . '.' . $column;
                 $params[] = $current_value;
                 // If we are moving a value down in a set, we push values in the difference zone up one
             } elseif ($current_value < $db_value) {
                 $shift_up = $new_max_value + 11;
                 $conditions[] = fORMDatabase::makeCondition($schema, $table, $column, '<', $db_value);
                 $params[] = $table . '.' . $column;
                 $params[] = $db_value;
                 $conditions[] = fORMDatabase::makeCondition($schema, $table, $column, '>=', $current_value);
                 $params[] = $table . '.' . $column;
                 $params[] = $current_value;
                 // If we are moving a value up in a set, we push values in the difference zone down one
             } else {
                 $shift_up = $new_max_value + 9;
                 $conditions[] = fORMDatabase::makeCondition($schema, $table, $column, '>', $db_value);
                 $params[] = $table . '.' . $column;
                 $params[] = $db_value;
                 $conditions[] = fORMDatabase::makeCondition($schema, $table, $column, '<=', $current_value);
                 $params[] = $table . '.' . $column;
                 $params[] = $current_value;
             }
             $params[0] .= join(' AND ', $conditions);
             if ($other_columns) {
                 $params[0] .= " AND ";
                 $params = self::addOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values);
             }
             call_user_func_array($db->translatedQuery, $params);
             if ($object->exists()) {
                 // Put the actual record we are changing in limbo to be updated when the actual update happens
                 $params = array("UPDATE %r SET %r = 0 WHERE %r = %i", $table, $column, $column, $db_value);
                 if ($other_columns) {
                     $params[0] .= " AND ";
                     $params = self::addOldOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values, $old_values);
                 }
                 call_user_func_array($db->translatedQuery, $params);
             }
             // Anything below zero needs to be moved back up into its new position
             $params = array("UPDATE %r SET %r = %r + %i WHERE %r < 0", $table, $column, $column, $shift_up, $column);
             if ($other_columns) {
                 $params[0] .= " AND ";
                 $params = self::addOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values);
             }
             call_user_func_array($db->translatedQuery, $params);
         }
         // If there was an old set, we need to close the gap
         if ($object->exists() && $new_set) {
             $params = array("SELECT MAX(%r) FROM %r WHERE ", $column, $table);
             $params = self::addOldOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values, $old_values);
             $old_set_max = (int) call_user_func_array($db->translatedQuery, $params)->fetchScalar();
             // We only need to close the gap if the record was not at the end
             if ($db_value < $old_set_max) {
                 $shift_down = $old_set_max + 10;
                 $shift_up = $old_set_max + 9;
                 // To prevent issues with the unique constraint, we move everything below 0 and then back up above
                 $params = array("UPDATE %r SET %r = %r - %i WHERE %r > %i AND ", $table, $column, $column, $shift_down, $column, $db_value);
                 $params = self::addOldOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values, $old_values);
                 call_user_func_array($db->translatedQuery, $params);
                 if ($current_value == $new_max_value) {
                     // Put the actual record we are changing in limbo to be updated when the actual update happens
                     $params = array("UPDATE %r SET %r = 0 WHERE %r = %i", $table, $column, $column, $db_value);
                     if ($other_columns) {
                         $params[0] .= " AND ";
                         $params = self::addOldOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values, $old_values);
                     }
                     call_user_func_array($db->translatedQuery, $params);
                 }
                 $params = array("UPDATE %r SET %r = %r + %i WHERE %r < 0 AND ", $table, $column, $column, $shift_up, $column);
                 $params = self::addOldOtherFieldsWhereParams($schema, $params, $table, $other_columns, $values, $old_values);
                 call_user_func_array($db->translatedQuery, $params);
             }
         }
     }
 }