Example #1
0
 /**
  * Sets the money column and then tries to objectify it with an related currency column
  * 
  * @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
  * @param  string        $method_name       The method that was called
  * @param  array         $parameters        The parameters passed to the method
  * @return fActiveRecord  The record object, to allow for method chaining
  */
 public static function setMoneyColumn($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
 {
     list($action, $column) = fORM::parseMethod($method_name);
     $class = get_class($object);
     if (count($parameters) < 1) {
         throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name);
     }
     $value = $parameters[0];
     fActiveRecord::assign($values, $old_values, $column, $value);
     $currency_column = self::$money_columns[$class][$column];
     // See if we can make an fMoney object out of the values
     self::objectifyMoneyWithCurrency($values, $old_values, $column, $currency_column);
     if ($currency_column) {
         if ($value instanceof fMoney) {
             fActiveRecord::assign($values, $old_values, $currency_column, $value->getCurrency());
         }
     }
     return $object;
 }
Example #2
0
 /**
  * Uploads a file
  * 
  * @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
  * @param  string        $method_name       The method that was called
  * @param  array         $parameters        The parameters passed to the method
  * @return fFile  The uploaded file
  */
 public static function upload($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
 {
     $class = get_class($object);
     list($action, $column) = fORM::parseMethod($method_name);
     $existing_temp_file = FALSE;
     // Try to upload the file putting it in the temp dir incase there is a validation problem with the record
     try {
         $upload_dir = self::$file_upload_columns[$class][$column];
         $temp_dir = self::prepareTempDir($upload_dir);
         if (!fUpload::check($column)) {
             throw new fExpectedException('Please upload a file');
         }
         $uploader = self::setUpFUpload($class, $column);
         $file = $uploader->move($temp_dir, $column);
         // If there was an eror, check to see if we have an existing file
     } catch (fExpectedException $e) {
         // If there is an existing file and none was uploaded, substitute the existing file
         $existing_file = fRequest::get('existing-' . $column);
         $delete_file = fRequest::get('delete-' . $column, 'boolean');
         $no_upload = $e->getMessage() == self::compose('Please upload a file');
         if ($existing_file && $delete_file && $no_upload) {
             $file = NULL;
         } elseif ($existing_file) {
             $file_path = $upload_dir->getPath() . $existing_file;
             $file = fFilesystem::createObject($file_path);
             $current_file = $values[$column];
             // If the existing file is the same as the current file, we can just exit now
             if ($current_file && $file->getPath() == $current_file->getPath()) {
                 return;
             }
             $existing_temp_file = TRUE;
         } else {
             $file = NULL;
         }
     }
     // Assign the file
     fActiveRecord::assign($values, $old_values, $column, $file);
     // Perform the file upload inheritance
     if (!empty(self::$column_inheritence[$class][$column])) {
         foreach (self::$column_inheritence[$class][$column] as $other_column) {
             if ($file) {
                 // Image columns will only inherit if it is an fImage object
                 if (!$file instanceof fImage && isset(self::$image_upload_columns[$class][$other_column])) {
                     continue;
                 }
                 $other_upload_dir = self::$file_upload_columns[$class][$other_column];
                 $other_temp_dir = self::prepareTempDir($other_upload_dir);
                 if ($existing_temp_file) {
                     $other_file = fFilesystem::createObject($other_temp_dir->getPath() . $file->getName());
                 } else {
                     $other_file = $file->duplicate($other_temp_dir, FALSE);
                 }
             } else {
                 $other_file = $file;
             }
             fActiveRecord::assign($values, $old_values, $other_column, $other_file);
             if (!$existing_temp_file && $other_file) {
                 self::processImage($class, $other_column, $other_file);
             }
         }
     }
     // Process the file
     if (!$existing_temp_file && $file) {
         self::processImage($class, $column, $file);
     }
     return $file;
 }
Example #3
0
 /**
  * Sets the timezone column and then tries to objectify the related timestamp column
  *
  * @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
  * @param  string        $method_name       The method that was called
  * @param  array         $parameters        The parameters passed to the method
  * @return fActiveRecord  The record object, to allow for method chaining
  */
 public static function setTimezoneColumn($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
 {
     list($action, $subject) = fORM::parseMethod($method_name);
     $column = fGrammar::underscorize($subject);
     $class = get_class($object);
     if (!isset($parameters[0])) {
         throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name);
     }
     fActiveRecord::assign($values, $old_values, $column, $parameters[0]);
     // See if we can make an fTimestamp object out of the values
     self::objectifyTimestampWithTimezone($values, $old_values, self::$timezone_columns[$class][$column], $column);
     return $object;
 }
 /**
  * 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);
             }
         }
     }
 }
Example #5
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);
         }
     }
 }
 /**
  * Sets the value for an email column, trimming the value if it is a valid email
  *
  * @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
  * @param  string        $method_name       The method that was called
  * @param  array         $parameters        The parameters passed to the method
  * @return fActiveRecord  The record object, to allow for method chaining
  */
 public static function setEmailColumn($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
 {
     list($action, $subject) = fORM::parseMethod($method_name);
     $column = fGrammar::underscorize($subject);
     $class = get_class($object);
     if (count($parameters) < 1) {
         throw new fProgrammerException('The method, %s(), requires at least one parameter', $method_name);
     }
     $email = $parameters[0];
     if (preg_match('#^\\s*[a-z0-9\\.\'_\\-\\+]+@(?:[a-z0-9\\-]+\\.)+[a-z]{2,}\\s*$#iD', $email)) {
         $email = trim($email);
     }
     if ($email === '') {
         $email = NULL;
     }
     fActiveRecord::assign($values, $old_values, $column, $email);
     return $object;
 }
Example #7
0
 /**
  * Generates a new random value for the 
  * 
  * @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
  * @param  string        $method_name       The method that was called
  * @param  array         $parameters        The parameters passed to the method
  * @return string  The encoded number
  */
 public static function generate($object, &$values, &$old_values, &$related_records, &$cache, $method_name, $parameters)
 {
     list($action, $column) = fORM::parseMethod($method_name);
     $class = get_class($object);
     $table = fORM::tablize($class);
     $settings = self::$random_columns[$class][$column];
     // Check to see if this is a unique column
     $unique_keys = fORMSchema::retrieve()->getKeys($table, 'unique');
     $is_unique_column = FALSE;
     foreach ($unique_keys as $unique_key) {
         if ($unique_key == array($column)) {
             $is_unique_column = TRUE;
             do {
                 $value = fCryptography::randomString($settings['length'], $settings['type']);
                 // See if this is unique
                 $sql = "SELECT " . $column . " FROM " . $table . " WHERE " . $column . " = " . fORMDatabase::retrieve()->escape('string', $value);
             } while (fORMDatabase::retrieve()->query($sql)->countReturnedRows());
         }
     }
     // If is is not a unique column, just generate a value
     if (!$is_unique_column) {
         $value = fCryptography::randomString($settings['length'], $settings['type']);
     }
     fActiveRecord::assign($values, $old_values, $column, $value);
 }