/** * Returns the record name for a related class * * The default record name of a related class is the result of * fGrammar::humanize() called on the class. * * @internal * * @param string $class The class to get the related class name for * @param string $related_class The related class to get the record name of * @return string The record name for the related class specified */ public static function getRelatedRecordName($class, $related_class, $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(self::$related_record_names[$table]) || !isset(self::$related_record_names[$table][$related_class]) || !isset(self::$related_record_names[$table][$related_class][$route])) { return fORM::getRecordName($related_class); } // If fText is loaded, use it if (class_exists('fText', FALSE)) { return call_user_func(array('fText', 'compose'), str_replace('%', '%%', self::$related_record_names[$table][$related_class][$route])); } return self::$related_record_names[$table][$related_class][$route]; }
/** * 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; }
/** * Throws an fEmptySetException if the record set is empty * * @throws fEmptySetException When there are no record in the set * * @param string $message The message to use for the exception if there are no records in this set * @return fRecordSet The record set object, to allow for method chaining */ public function tossIfEmpty($message = NULL) { if ($this->records) { return $this; } if ($message === NULL) { if (is_array($this->class)) { $names = array_map(array('fORM', 'getRecordName'), $this->class); $names = array_map(array('fGrammar', 'pluralize'), $names); $name = join(', ', $names); } else { $name = fGrammar::pluralize(fORM::getRecordName($this->class)); } $message = self::compose('No %s could be found', $name); } throw new fEmptySetException($message); }
/** * Overlays user data over info from the record set * * @param array $data The user data * @param string|array $class The class or classes present in the record set * @return array The merged data */ private static function extendRecordSetInfo($data, $class) { if (is_array($class)) { $record_name = array_map(array('fORM', 'getRecordName'), $class); } else { $record_name = fORM::getRecordName($class); } return array_merge(array('class' => $class, 'record_name' => $record_name), $data); }
/** * Makes sure a record with the same primary keys is not already in the database * * @param fSchema $schema The schema object for the object * @param fActiveRecord $object The instance of the class to check * @param array &$values An associative array of all values going into the row (needs all for multi-field unique constraint checking) * @param array &$old_values The old values for the record * @return array A single element associative array with the key being the primary keys joined by ,s and the value being the error message */ private static function checkPrimaryKeys($schema, $object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $db = fORMDatabase::retrieve($class, 'read'); $pk_columns = $schema->getKeys($table, 'primary'); $columns = array(); $found_value = FALSE; foreach ($pk_columns as $pk_column) { $columns[] = fORM::getColumnName($class, $pk_column); if ($values[$pk_column]) { $found_value = TRUE; } } if (!$found_value) { return; } $different = FALSE; foreach ($pk_columns as $pk_column) { if (!fActiveRecord::hasOld($old_values, $pk_column)) { continue; } $old_value = fActiveRecord::retrieveOld($old_values, $pk_column); $value = $values[$pk_column]; if (self::isCaseInsensitive($class, $pk_column) && self::stringlike($value) && self::stringlike($old_value)) { if (fUTF8::lower($value) != fUTF8::lower($old_value)) { $different = TRUE; } } elseif ($old_value != $value) { $different = TRUE; } } if (!$different) { return; } try { $params = array("SELECT %r FROM %r WHERE ", $pk_columns, $table); $column_info = $schema->getColumnInfo($table); $conditions = array(); foreach ($pk_columns as $pk_column) { $value = $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']; } if (self::isCaseInsensitive($class, $pk_column) && self::stringlike($value)) { $condition = fORMDatabase::makeCondition($schema, $table, $pk_column, '=', $value); $conditions[] = str_replace('%r', 'LOWER(%r)', $condition); $params[] = $pk_column; $params[] = fUTF8::lower($value); } else { $conditions[] = fORMDatabase::makeCondition($schema, $table, $pk_column, '=', $value); $params[] = $pk_column; $params[] = $value; } } $params[0] .= join(' AND ', $conditions); $result = call_user_func_array($db->translatedQuery, $params); $result->tossIfNoRows(); return array(join(',', $pk_columns) => self::compose('Another %1$s with the same %2$s already exists', fORM::getRecordName($class), fGrammar::joinArray($columns, 'and'))); } catch (fNoRowsException $e) { } }
/** * Returns the record name for a related class * * The default record name of a related class is the result of * fGrammar::humanize() called on the class. * * @internal * * @param string $class The class to get the related class name for * @param string $related_class The related class to get the record name of * @return string The record name for the related class specified */ public static function getRelatedRecordName($class, $related_class, $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(self::$related_record_names[$table]) || !isset(self::$related_record_names[$table][$related_class]) || !isset(self::$related_record_names[$table][$related_class][$route])) { return fORM::getRecordName($related_class); } return self::$related_record_names[$table][$related_class][$route]; }
/** * 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; }
/** * Returns the record name for a related class * * The default record name of a related class is the result of * fGrammar::humanize() called on the class. * * @internal * * @param string $class The class to get the related class name for * @param string $related_class The related class to get the record name of * @return string The record name for the related class specified */ public static function getRelatedRecordName($class, $related_class, $route = NULL) { $table = fORM::tablize($class); $related_table = fORM::tablize($related_class); $route = fORMSchema::getRouteName($table, $related_table, $route); if (!isset(self::$related_record_names[$table]) || !isset(self::$related_record_names[$table][$related_class]) || !isset(self::$related_record_names[$table][$related_class][$route])) { return fORM::getRecordName($related_class); } return self::$related_record_names[$table][$related_class][$route]; }
/** * Makes sure a record with the same primary keys is not already in the database * * @param fActiveRecord $object The instance of the class to check * @param array &$values An associative array of all values going into the row (needs all for multi-field unique constraint checking) * @param array &$old_values The old values for the record * @return string An error message */ private static function checkPrimaryKeys($object, &$values, &$old_values) { $class = get_class($object); $table = fORM::tablize($class); $primary_keys = fORMSchema::retrieve()->getKeys($table, 'primary'); $columns = array(); $found_value = FALSE; foreach ($primary_keys as $primary_key) { $columns[] = fORM::getColumnName($class, $primary_key); if ($values[$primary_key]) { $found_value = TRUE; } } if (!$found_value) { return; } $different = FALSE; foreach ($primary_keys as $primary_key) { if (!fActiveRecord::hasOld($old_values, $primary_key)) { continue; } $old_value = fActiveRecord::retrieveOld($old_values, $primary_key); $value = $values[$primary_key]; if (self::isCaseInsensitive($class, $primary_key) && self::stringlike($value) && self::stringlike($old_value)) { if (fUTF8::lower($value) != fUTF8::lower($old_value)) { $different = TRUE; } } elseif ($old_value != $value) { $different = TRUE; } } if (!$different) { return; } try { $sql = "SELECT " . join(', ', $primary_keys) . " FROM " . $table . " WHERE "; $conditions = array(); foreach ($primary_keys as $primary_key) { if (self::isCaseInsensitive($class, $primary_key) && self::stringlike($values[$primary_key])) { $conditions[] = 'LOWER(' . $primary_key . ')' . fORMDatabase::escapeBySchema($table, $primary_key, fUTF8::lower($values[$primary_key]), '='); } else { $conditions[] = $primary_key . fORMDatabase::escapeBySchema($table, $primary_key, $values[$primary_key], '='); } } $sql .= join(' AND ', $conditions); $result = fORMDatabase::retrieve()->translatedQuery($sql); $result->tossIfNoRows(); return self::compose('Another %1$s with the same %2$s already exists', fORM::getRecordName($class), fGrammar::joinArray($columns, 'and')); } catch (fNoRowsException $e) { } }