public function setUp() { if (defined('SKIPPING')) { $this->markTestSkipped(); } self::$db->execute('BEGIN'); fActiveRecord::clearIdentityMap(); }
public static function import_from_array_to_graph($input, $graph_id) { $result = true; if (!empty($input)) { $columns_to_ignore = array('line_id', 'graph_id'); $new_line = fActiveRecord::array_to_dbentry($input, __CLASS__, $columns_to_ignore); if ($new_line !== NULL) { $new_line->setGraphId($graph_id); $new_line->store(); } else { $result = false; } } return $result; }
/** * 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; }
/** * Returns a new fRecordSet containing only unique records in the record set * * @param boolean $remember_original_count If the number of records in the current set should be saved as the non-limited count for the new set - the page will be reset to `1` either way * @return fRecordSet The new record set with only unique records */ public function unique($remember_original_count = FALSE) { $records = array(); foreach ($this->records as $record) { $class = get_class($record); $hash = fActiveRecord::hash($record); if (isset($records[$class . '::' . $hash])) { continue; } $records[$class . '::' . $hash] = $record; } $set = new fRecordSet($this->class, array_values($records)); if ($remember_original_count) { $set->non_limited_count = $this->count(); } return $set; }
/** * Validates values against unique constraints * * @param fSchema $schema The schema object for the object * @param fActiveRecord $object The instance of the class to check * @param array &$values The values to check * @param array &$old_values The old values for the record * @return array An aray of error messages for the unique constraints */ private static function checkUniqueConstraints($schema, $object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $db = fORMDatabase::retrieve($class, 'read'); $key_info = $schema->getKeys($table); $pk_columns = $key_info['primary']; $unique_keys = $key_info['unique']; $messages = array(); foreach ($unique_keys as $unique_columns) { settype($unique_columns, 'array'); // NULL values are unique $found_not_null = FALSE; foreach ($unique_columns as $unique_column) { if ($values[$unique_column] !== NULL) { $found_not_null = TRUE; } } if (!$found_not_null) { continue; } $params = array("SELECT %r FROM %r WHERE ", $key_info['primary'], $table); $column_info = $schema->getColumnInfo($table); $conditions = array(); foreach ($unique_columns as $unique_column) { $value = $values[$unique_column]; // This makes sure the query performs the way an insert will if ($value === NULL && $column_info[$unique_column]['not_null'] && $column_info[$unique_column]['default'] !== NULL) { $value = $column_info[$unique_column]['default']; } if (self::isCaseInsensitive($class, $unique_column) && self::stringlike($value)) { $condition = fORMDatabase::makeCondition($schema, $table, $unique_column, '=', $value); $conditions[] = str_replace('%r', 'LOWER(%r)', $condition); $params[] = $table . '.' . $unique_column; $params[] = fUTF8::lower($value); } else { $conditions[] = fORMDatabase::makeCondition($schema, $table, $unique_column, '=', $value); $params[] = $table . '.' . $unique_column; $params[] = $value; } } $params[0] .= join(' AND ', $conditions); if ($object->exists()) { foreach ($pk_columns as $pk_column) { $value = fActiveRecord::retrieveOld($old_values, $pk_column, $values[$pk_column]); $params[0] .= ' AND ' . fORMDatabase::makeCondition($schema, $table, $pk_column, '<>', $value); $params[] = $table . '.' . $pk_column; $params[] = $value; } } try { $result = call_user_func_array($db->translatedQuery, $params); $result->tossIfNoRows(); // If an exception was not throw, we have existing values $column_names = array(); foreach ($unique_columns as $unique_column) { $column_names[] = fORM::getColumnName($class, $unique_column); } if (sizeof($column_names) == 1) { $messages[join('', $unique_columns)] = self::compose('%sThe value specified must be unique, however it already exists', fValidationException::formatField(join('', $column_names))); } else { $messages[join(',', $unique_columns)] = self::compose('%sThe values specified must be a unique combination, however the specified combination already exists', fValidationException::formatField(join(', ', $column_names))); } } catch (fNoRowsException $e) { } } return $messages; }
/** * Makes sure the ordering value is sane, removes error messages about missing values * * @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 array &$validation_messages An array of ordered validation messages * @return void */ public static function validate($object, &$values, &$old_values, &$related_records, &$cache, &$validation_messages) { $class = get_class($object); $table = fORM::tablize($class); $db = fORMDatabase::retrieve($class, 'read'); $schema = fORMSchema::retrieve($class); foreach (self::$ordering_columns[$class] as $column => $other_columns) { $current_value = $values[$column]; $old_value = fActiveRecord::retrieveOld($old_values, $column); $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; $new_set_new_value = fActiveRecord::changed($values, $old_values, $column); } $column_name = fORM::getColumnName($class, $column); // Remove any previous validation warnings $filtered_messages = array(); foreach ($validation_messages as $validation_column => $validation_message) { if (!preg_match('#(^|,)' . preg_quote($column, '#') . '(,|$)#D', $validation_column)) { $filtered_messages[$validation_column] = $validation_message; } } $validation_messages = $filtered_messages; // If we have a completely empty value, we don't need to validate since a valid value will be generated if ($current_value === '' || $current_value === NULL) { continue; } if (!is_numeric($current_value) || strlen((int) $current_value) != strlen($current_value)) { $validation_messages[$column] = self::compose('%sPlease enter an integer', fValidationException::formatField($column_name)); } elseif ($current_value < 1) { $validation_messages[$column] = self::compose('%sThe value can not be less than 1', fValidationException::formatField($column_name)); } } }
/** * Validates values against unique constraints * * @param fActiveRecord $object The instance of the class to check * @param array &$values The values to check * @param array &$old_values The old values for the record * @return string An error message for the unique constraints */ private static function checkUniqueConstraints($object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $key_info = fORMSchema::retrieve()->getKeys($table); $primary_keys = $key_info['primary']; $unique_keys = $key_info['unique']; foreach ($unique_keys as $unique_columns) { settype($unique_columns, 'array'); // NULL values are unique $found_not_null = FALSE; foreach ($unique_columns as $unique_column) { if ($values[$unique_column] !== NULL) { $found_not_null = TRUE; } } if (!$found_not_null) { continue; } $sql = "SELECT " . join(', ', $key_info['primary']) . " FROM " . $table . " WHERE "; $first = TRUE; foreach ($unique_columns as $unique_column) { if ($first) { $first = FALSE; } else { $sql .= " AND "; } $value = $values[$unique_column]; if (self::isCaseInsensitive($class, $unique_column) && self::stringlike($value)) { $sql .= 'LOWER(' . $unique_column . ')' . fORMDatabase::escapeBySchema($table, $unique_column, fUTF8::lower($value), '='); } else { $sql .= $unique_column . fORMDatabase::escapeBySchema($table, $unique_column, $value, '='); } } if ($object->exists()) { foreach ($primary_keys as $primary_key) { $value = fActiveRecord::retrieveOld($old_values, $primary_key, $values[$primary_key]); $sql .= ' AND ' . $primary_key . fORMDatabase::escapeBySchema($table, $primary_key, $value, '<>'); } } try { $result = fORMDatabase::retrieve()->translatedQuery($sql); $result->tossIfNoRows(); // If an exception was not throw, we have existing values $column_names = array(); foreach ($unique_columns as $unique_column) { $column_names[] = fORM::getColumnName($class, $unique_column); } if (sizeof($column_names) == 1) { return self::compose('%sThe value specified must be unique, however it already exists', fValidationException::formatField(join('', $column_names))); } else { return self::compose('%sThe values specified must be a unique combination, however the specified combination already exists', fValidationException::formatField(join(', ', $column_names))); } } catch (fNoRowsException $e) { } } }
/** * 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; }
function changed($object, &$values, &$old_values, &$related_records, &$cache, $method, $parameters) { return fActiveRecord::changed($values, $old_values, $parameters[0]); }
/** * Add the appropriate SQL and params for a `WHERE` clause condition for primary keys of the table specified * * @internal * * @param fSchema $schema The schema for the database the query will be run on * @param array $params The currently constructed params for fDatabase::query() - the first param should be a SQL statement * @param string $table The table to build the where clause for * @param string $table_alias The alias for the table * @param array &$values The values array for the fActiveRecord object * @param array &$old_values The old values array for the fActiveRecord object * @return array The params to pass to fDatabase::query(), including the new primary key where condition */ public static function addPrimaryKeyWhereParams($schema, $params, $table, $table_alias, &$values, &$old_values) { $pk_columns = $schema->getKeys($table, 'primary'); $column_info = $schema->getColumnInfo($table); $conditions = array(); foreach ($pk_columns as $pk_column) { $value = fActiveRecord::retrieveOld($old_values, $pk_column, $values[$pk_column]); // This makes sure the query performs the way an insert will if ($value === NULL && $column_info[$pk_column]['not_null'] && $column_info[$pk_column]['default'] !== NULL) { $value = $column_info[$pk_column]['default']; } $params[] = $table_alias . '.' . $pk_column; $params[] = $value; $conditions[] = self::makeCondition($schema, $table, $pk_column, '=', $value); } $params[0] .= join(' AND ', $conditions); return $params; }
/** * @see fActiveRecord::set() */ protected function set($column, $value) { if (isset($this->columnAliases[$column])) { $column = $this->columnAliases[$column]; } return parent::set($column, $value); }
/** * Sets the appropriate column values to a random string if the object is new * * @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 string The formatted link */ public static function setRandomStrings($object, &$values, &$old_values, &$related_records, &$cache) { if ($object->exists()) { return; } $class = get_class($object); $table = fORM::tablize($class); foreach (self::$random_columns[$class] as $column => $settings) { if (fActiveRecord::hasOld($old_values, $column) && $values[$column]) { continue; } self::generate($object, $values, $old_values, $related_records, $cache, 'generate' . fGrammar::camelize($column, TRUE), array()); } }
/** * Generates a clone of the current record, removing any auto incremented primary key value and allowing for replicating related records * * This method will accept three different sets of parameters: * * - No parameters: this object will be cloned * - A single `TRUE` value: this object plus all many-to-many associations and all child records (recursively) will be cloned * - Any number of plural related record class names: the many-to-many associations or child records that correspond to the classes specified will be cloned * * The class names specified can be a simple class name if there is only a * single route between the two corresponding database tables. If there is * more than one route between the two tables, the class name should be * substituted with a string in the format `'RelatedClass{route}'`. * * @param string $related_class The plural related class to replicate - see method description for details * @param string ... * @return fActiveRecord The cloned record */ public function replicate($related_class = NULL) { fActiveRecord::$replicate_level++; $class = get_class($this); $hash = self::hash($this->values, $class); $table = fORM::tablize($class); // If the object has not been replicated yet, do it now if (!isset(fActiveRecord::$replicate_map[$class])) { fActiveRecord::$replicate_map[$class] = array(); } if (!isset(fActiveRecord::$replicate_map[$class][$hash])) { fActiveRecord::$replicate_map[$class][$hash] = clone $this; // We need the primary key to get a hash, otherwise certain recursive relationships end up losing members $pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary'); if (sizeof($pk_columns) == 1 && fORMSchema::retrieve()->getColumnInfo($table, $pk_columns[0], 'auto_increment')) { fActiveRecord::$replicate_map[$class][$hash]->values[$pk_columns[0]] = $this->values[$pk_columns[0]]; } } $clone = fActiveRecord::$replicate_map[$class][$hash]; $parameters = func_get_args(); $recursive = FALSE; $many_to_many_relationships = fORMSchema::retrieve()->getRelationships($table, 'many-to-many'); $one_to_many_relationships = fORMSchema::retrieve()->getRelationships($table, 'one-to-many'); // When just TRUE is passed we recursively replicate all related records if (sizeof($parameters) == 1 && $parameters[0] === TRUE) { $parameters = array(); $recursive = TRUE; foreach ($many_to_many_relationships as $relationship) { $parameters[] = fGrammar::pluralize(fORM::classize($relationship['related_table'])) . '{' . $relationship['join_table'] . '}'; } foreach ($one_to_many_relationships as $relationship) { $parameters[] = fGrammar::pluralize(fORM::classize($relationship['related_table'])) . '{' . $relationship['related_column'] . '}'; } } $record_sets = array(); foreach ($parameters as $parameter) { // Parse the Class{route} strings if (strpos($parameter, '{') !== FALSE) { $brace = strpos($parameter, '{'); $related_class = fGrammar::singularize(substr($parameter, 0, $brace)); $related_table = fORM::tablize($related_class); $route = substr($parameter, $brace + 1, -1); } else { $related_class = fGrammar::singularize($parameter); $related_table = fORM::tablize($related_class); $route = fORMSchema::getRouteName($table, $related_table); } // Determine the kind of relationship $many_to_many = FALSE; $one_to_many = FALSE; foreach ($many_to_many_relationships as $relationship) { if ($relationship['related_table'] == $related_table && $relationship['join_table'] == $route) { $many_to_many = TRUE; break; } } foreach ($one_to_many_relationships as $relationship) { if ($relationship['related_table'] == $related_table && $relationship['related_column'] == $route) { $one_to_many = TRUE; break; } } if (!$many_to_many && !$one_to_many) { throw new fProgrammerException('The related class specified, %1$s, does not appear to be in a many-to-many or one-to-many relationship with %$2s', $parameter, get_class($this)); } // Get the related records $record_set = fORMRelated::buildRecords($class, $this->values, $this->related_records, $related_class, $route); // One-to-many records need to be replicated, possibly recursively if ($one_to_many) { if ($recursive) { $records = $record_set->call('replicate', TRUE); } else { $records = $record_set->call('replicate'); } $record_set = fRecordSet::buildFromArray($related_class, $records); $record_set->call('set' . fGrammar::camelize($route, TRUE), NULL); } // Cause the related records to be associated with the new clone fORMRelated::associateRecords($class, $clone->related_records, $related_class, $record_set, $route); } fActiveRecord::$replicate_level--; if (!fActiveRecord::$replicate_level) { // This removes the primary keys we had added back in for proper duplicate detection foreach (fActiveRecord::$replicate_map as $class => $records) { $table = fORM::tablize($class); $pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary'); if (sizeof($pk_columns) != 1 || !fORMSchema::retrieve()->getColumnInfo($table, $pk_columns[0], 'auto_increment')) { continue; } foreach ($records as $hash => $record) { $record->values[$pk_columns[0]] = NULL; } } fActiveRecord::$replicate_map = array(); } return $clone; }
public static function import_from_json_to_group($json, $group_id = NULL) { $result = true; $json_array = json_decode($json, TRUE); if (!empty($json_array)) { if (array_key_exists("name", $json_array)) { // In this case, we only have a dashboard, not an array of dashboard // We convert it into an array $json_array = array($json_array); } foreach ($json_array as $dashboard_to_create) { $column_to_ignore = array('dashboard_id', 'group_id', 'graphs'); $new_dashboard = fActiveRecord::array_to_dbentry($dashboard_to_create, __CLASS__, $column_to_ignore); if ($new_dashboard !== NULL) { $new_dashboard->setGroupId(empty($group_id) ? $GLOBALS['DEFAULT_GROUP_ID'] : $group_id); $new_dashboard->setUserId(fSession::get('user_id', 1)); $new_dashboard->store(); if (in_array('graphs', array_keys($dashboard_to_create))) { $new_dashboard_id = $new_dashboard->getDashboardId(); foreach ($dashboard_to_create['graphs'] as $graph) { $result_graph = Graph::import_from_array_to_dashboard($graph, $new_dashboard_id); $result = $result && $result_graph; } } } else { $result = false; } } } else { fMessaging::create('error', "/" . Dashboard::makeUrl('list'), "Empty or malformed file"); $result = false; } return $result; }
/** * Sets the related records for *-to-many relationships * * @internal * * @param string $class The class to set the related records for * @param array &$related_records The related records existing for the fActiveRecord class * @param string $related_class The class we are associating with the current record * @param fRecordSet $records The records are associating * @param string $route The route to use between the current class and the related class * @return void */ public static function setRecordSet($class, &$related_records, $related_class, fRecordSet $records, $route = NULL) { fActiveRecord::validateClass($related_class); fActiveRecord::forceConfigure($related_class); $table = fORM::tablize($class); $related_table = fORM::tablize($related_class); $schema = fORMSchema::retrieve($class); $route = fORMSchema::getRouteName($schema, $table, $related_table, $route); if (!isset($related_records[$related_table])) { $related_records[$related_table] = array(); } if (!isset($related_records[$related_table][$route])) { $related_records[$related_table][$route] = array(); } $related_records[$related_table][$route]['record_set'] = $records; $related_records[$related_table][$route]['count'] = $records->count(); $related_records[$related_table][$route]['associate'] = FALSE; $related_records[$related_table][$route]['primary_keys'] = NULL; }
/** * Stores a record in the database, whether existing or new * * This method will start database and filesystem transactions if they have * not already been started. * * @throws fValidationException When ::validate() throws an exception * * @param boolean $force_cascade When storing related records, this will force deleting child records even if they have their own children in a relationship with an RESTRICT or NO ACTION for the ON DELETE clause * @return fActiveRecord The record object, to allow for method chaining */ public function store($force_cascade = FALSE) { $class = get_class($this); if (fORM::getActiveRecordMethod($class, 'store')) { return $this->__call('store', array()); } fORM::callHookCallbacks($this, 'pre::store()', $this->values, $this->old_values, $this->related_records, $this->cache); $db = fORMDatabase::retrieve($class, 'write'); $schema = fORMSchema::retrieve($class); try { $table = fORM::tablize($class); // New auto-incrementing records require lots of special stuff, so we'll detect them here $new_autoincrementing_record = FALSE; if (!$this->exists()) { $pk_columns = $schema->getKeys($table, 'primary'); $pk_column = $pk_columns[0]; $pk_auto_incrementing = $schema->getColumnInfo($table, $pk_column, 'auto_increment'); if (sizeof($pk_columns) == 1 && $pk_auto_incrementing && !$this->values[$pk_column]) { $new_autoincrementing_record = TRUE; } } $inside_db_transaction = $db->isInsideTransaction(); if (!$inside_db_transaction) { $db->translatedQuery('BEGIN'); } fORM::callHookCallbacks($this, 'post-begin::store()', $this->values, $this->old_values, $this->related_records, $this->cache); $this->validate(); fORM::callHookCallbacks($this, 'post-validate::store()', $this->values, $this->old_values, $this->related_records, $this->cache); // Storing main table if (!$this->exists()) { $params = $this->constructInsertParams(); } else { $params = $this->constructUpdateParams(); } $result = call_user_func_array($db->translatedQuery, $params); // If there is an auto-incrementing primary key, grab the value from the database if ($new_autoincrementing_record) { $this->set($pk_column, $result->getAutoIncrementedValue()); } // Fix cascade updated columns for in-memory objects to prevent issues when saving $one_to_one_relationships = $schema->getRelationships($table, 'one-to-one'); $one_to_many_relationships = $schema->getRelationships($table, 'one-to-many'); $relationships = array_merge($one_to_one_relationships, $one_to_many_relationships); foreach ($relationships as $relationship) { $type = in_array($relationship, $one_to_one_relationships) ? 'one-to-one' : 'one-to-many'; $route = fORMSchema::getRouteNameFromRelationship($type, $relationship); $related_table = $relationship['related_table']; $related_class = fORM::classize($related_table); $related_class = fORM::getRelatedClass($class, $related_class); if ($relationship['on_update'] != 'cascade') { continue; } $column = $relationship['column']; if (!fActiveRecord::changed($this->values, $this->old_values, $column)) { continue; } if (!isset($this->related_records[$related_table][$route]['record_set'])) { continue; } $record_set = $this->related_records[$related_table][$route]['record_set']; $related_column = $relationship['related_column']; $old_value = fActiveRecord::retrieveOld($this->old_values, $column); $value = $this->values[$column]; if ($old_value === NULL) { continue; } foreach ($record_set as $record) { if (isset($record->old_values[$related_column])) { foreach (array_keys($record->old_values[$related_column]) as $key) { if ($record->old_values[$related_column][$key] === $old_value) { $record->old_values[$related_column][$key] = $value; } } } if ($record->values[$related_column] === $old_value) { $record->values[$related_column] = $value; } } } // Storing *-to-many and one-to-one relationships fORMRelated::store($class, $this->values, $this->related_records, $force_cascade); fORM::callHookCallbacks($this, 'pre-commit::store()', $this->values, $this->old_values, $this->related_records, $this->cache); if (!$inside_db_transaction) { $db->translatedQuery('COMMIT'); } fORM::callHookCallbacks($this, 'post-commit::store()', $this->values, $this->old_values, $this->related_records, $this->cache); } catch (fException $e) { if (!$inside_db_transaction) { $db->translatedQuery('ROLLBACK'); } fORM::callHookCallbacks($this, 'post-rollback::store()', $this->values, $this->old_values, $this->related_records, $this->cache); if ($new_autoincrementing_record && self::hasOld($this->old_values, $pk_column)) { $this->values[$pk_column] = self::retrieveOld($this->old_values, $pk_column); unset($this->old_values[$pk_column]); } throw $e; } fORM::callHookCallbacks($this, 'post::store()', $this->values, $this->old_values, $this->related_records, $this->cache); $was_new = !$this->exists(); // If we got here we succefully stored, so update old values to make exists() work foreach ($this->values as $column => $value) { $this->old_values[$column] = array($value); } // If the object was just inserted into the database, save it to the identity map if ($was_new) { $hash = self::hash($this->values, $class); if (!isset(self::$identity_map[$class])) { self::$identity_map[$class] = array(); } self::$identity_map[$class][$hash] = $this; } return $this; }
/** * Makes sure the ordering value is sane, removes error messages about missing values * * @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 array &$validation_messages An array of ordered validation messages * @return void */ public static function validate($object, &$values, &$old_values, &$related_records, &$cache, &$validation_messages) { $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]; $old_value = fActiveRecord::retrieveOld($old_values, $column); $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; $new_set_new_value = fActiveRecord::changed($values, $old_values, $column); } $column_name = fORM::getColumnName($class, $column); // Remove any previous validation warnings $filtered_messages = array(); foreach ($validation_messages as $validation_message) { if (!preg_match('#^' . str_replace('___', '(.*?)', preg_quote(fValidationException::formatField('___' . $column_name . '___'), '#')) . '#', $validation_message)) { $filtered_messages[] = $validation_message; } } $validation_messages = $filtered_messages; // If we have a completely empty value, we don't need to validate since a valid value will be generated if ($current_value === '' || $current_value === NULL) { return; } if (!is_numeric($current_value) || strlen((int) $current_value) != strlen($current_value)) { $validation_messages[] = self::compose('%sPlease enter an integer', fValidationException::formatField($column_name)); } elseif ($current_value < 1) { $validation_messages[] = self::compose('%sThe value can not be less than 1', fValidationException::formatField($column_name)); } }
/** * 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; }
public static function import_from_array_to_dashboard($input, $dashboard_id) { $result = true; if (!empty($input)) { $columns_to_ignore = array('graph_id', 'dashboard_id', 'lines'); $new_graph = fActiveRecord::array_to_dbentry($input, __CLASS__, $columns_to_ignore); if ($new_graph !== NULL) { $new_graph->setDashboardId($dashboard_id); $new_graph->store(); if (in_array('lines', array_keys($input))) { $new_graph_id = $new_graph->getGraphId(); foreach ($input['lines'] as $line) { $result_line = Line::import_from_array_to_graph($line, $new_graph_id); $result = $result && $result_line; } } } else { $result = false; } } return $result; }