Exemple #1
0
 /**
  * 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);
     $column = self::$ordering_columns[$class]['column'];
     $other_columns = self::$ordering_columns[$class]['other_columns'];
     $current_value = $values[$column];
     if (!$object->exists()) {
         $old_value = fActiveRecord::retrieveOld($old_values, $column);
     } else {
         $old_value = fORMDatabase::retrieve()->translatedQuery("SELECT " . $column . " FROM " . $table . " WHERE " . fORMDatabase::createPrimaryKeyWhereClause($table, $table, $values, $old_values))->fetchScalar();
     }
     // Figure out the range we are dealing with
     $sql = "SELECT max(" . $column . ") FROM " . $table;
     if ($other_columns) {
         $sql .= " WHERE " . self::createOtherFieldsWhereClause($table, $other_columns, $values);
     }
     $current_max_value = (int) fORMDatabase::retrieve()->translatedQuery($sql)->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) {
         return;
     }
     // 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) {
         return;
     }
     // 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()) {
         $sql = "SELECT " . $column . " FROM " . $table . " WHERE ";
         $sql .= fORMDatabase::createPrimaryKeyWhereClause($table, $table, $values, $old_values);
         $db_value = (int) fORMDatabase::retrieve()->translatedQuery($sql)->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;
         // 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;
             $down_condition = $column . " >= " . $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;
             $down_condition = $column . " < " . $db_value . " AND " . $column . " >= " . $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;
             $down_condition = $column . " > " . $db_value . " AND " . $column . " <= " . $current_value;
         }
         // To prevent issues with the unique constraint, we move everything below 0
         $sql = "UPDATE " . $table . " SET " . $column . " = " . $column . " - " . $shift_down;
         $sql .= " WHERE " . $down_condition;
         if ($other_columns) {
             $sql .= " AND " . self::createOtherFieldsWhereClause($table, $other_columns, $values);
         }
         fORMDatabase::retrieve()->translatedQuery($sql);
         if ($object->exists()) {
             // Put the actual record we are changing in limbo to be updated when the actual update happens
             $sql = "UPDATE " . $table . " SET " . $column . " = 0";
             $sql .= " WHERE " . $column . " = " . $db_value;
             if ($other_columns) {
                 $sql .= " AND " . self::createOldOtherFieldsWhereClause($table, $other_columns, $values, $old_values);
             }
             fORMDatabase::retrieve()->translatedQuery($sql);
         }
         // Anything below zero needs to be moved back up into its new position
         $sql = "UPDATE " . $table . " SET " . $column . " = " . $column . " + " . $shift_up;
         $sql .= " WHERE " . $column . " < 0";
         if ($other_columns) {
             $sql .= " AND " . self::createOtherFieldsWhereClause($table, $other_columns, $values);
         }
         fORMDatabase::retrieve()->translatedQuery($sql);
     }
     // If there was an old set, we need to close the gap
     if ($object->exists() && $new_set) {
         $sql = "SELECT max(" . $column . ") FROM " . $table . " WHERE ";
         $sql .= self::createOldOtherFieldsWhereClause($table, $other_columns, $values, $old_values);
         $old_set_max = (int) fORMDatabase::retrieve()->translatedQuery($sql)->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
             $sql = "UPDATE " . $table . " SET " . $column . ' = ' . $column . ' - ' . $shift_down . " WHERE ";
             $sql .= self::createOldOtherFieldsWhereClause($table, $other_columns, $values, $old_values);
             $sql .= " AND " . $column . " > " . $db_value;
             fORMDatabase::retrieve()->translatedQuery($sql);
             if ($current_value == $new_max_value) {
                 // Put the actual record we are changing in limbo to be updated when the actual update happens
                 $sql = "UPDATE " . $table . " SET " . $column . " = 0";
                 $sql .= " WHERE " . $column . " = " . $db_value;
                 if ($other_columns) {
                     $sql .= " AND " . self::createOldOtherFieldsWhereClause($table, $other_columns, $values, $old_values);
                 }
                 fORMDatabase::retrieve()->translatedQuery($sql);
             }
             $sql = "UPDATE " . $table . " SET " . $column . ' = ' . $column . ' + ' . $shift_up . " WHERE ";
             $sql .= self::createOldOtherFieldsWhereClause($table, $other_columns, $values, $old_values);
             $sql .= " AND " . $column . " < 0";
             fORMDatabase::retrieve()->translatedQuery($sql);
         }
     }
 }
Exemple #2
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);
     if (fORM::getActiveRecordMethod($class, 'load')) {
         return $this->__call('load', array());
     }
     try {
         $table = fORM::tablize($class);
         $sql = 'SELECT * FROM ' . $table . ' WHERE ' . fORMDatabase::createPrimaryKeyWhereClause($table, $table, $this->values, $this->old_values);
         $result = fORMDatabase::retrieve()->translatedQuery($sql);
         $result->tossIfNoRows();
     } catch (fExpectedException $e) {
         throw new fNotFoundException('The %s requested could not be found', fORM::getRecordName($class));
     }
     $this->loadFromResult($result, TRUE);
     return $this;
 }