本文整理汇总了PHP中fORMSchema::retrieve方法的典型用法代码示例。如果您正苦于以下问题:PHP fORMSchema::retrieve方法的具体用法?PHP fORMSchema::retrieve怎么用?PHP fORMSchema::retrieve使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类fORMSchema
的用法示例。
在下文中一共展示了fORMSchema::retrieve方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: configureMoneyColumn
/**
* Sets a column to be formatted as an fMoney object
*
* @param mixed $class The class name or instance of the class to set the column format
* @param string $column The column to format as an fMoney object
* @param string $currency_column If specified, this column will store the currency of the fMoney object
* @return void
*/
public static function configureMoneyColumn($class, $column, $currency_column = NULL)
{
$class = fORM::getClass($class);
$table = fORM::tablize($class);
$schema = fORMSchema::retrieve($class);
$data_type = $schema->getColumnInfo($table, $column, 'type');
$valid_data_types = array('float');
if (!in_array($data_type, $valid_data_types)) {
throw new fProgrammerException('The column specified, %1$s, is a %2$s column. Must be %3$s to be set as a money column.', $column, $data_type, join(', ', $valid_data_types));
}
if ($currency_column !== NULL) {
$currency_column_data_type = $schema->getColumnInfo($table, $currency_column, 'type');
$valid_currency_column_data_types = array('varchar', 'char', 'text');
if (!in_array($currency_column_data_type, $valid_currency_column_data_types)) {
throw new fProgrammerException('The currency column specified, %1$s, is a %2$s column. Must be %3$s to be set as a currency column.', $currency_column, $currency_column_data_type, join(', ', $valid_currency_column_data_types));
}
}
$camelized_column = fGrammar::camelize($column, TRUE);
fORM::registerActiveRecordMethod($class, 'encode' . $camelized_column, self::encodeMoneyColumn);
fORM::registerActiveRecordMethod($class, 'prepare' . $camelized_column, self::prepareMoneyColumn);
if (!fORM::checkHookCallback($class, 'post::validate()', self::validateMoneyColumns)) {
fORM::registerHookCallback($class, 'post::validate()', self::validateMoneyColumns);
}
fORM::registerReflectCallback($class, self::reflect);
fORM::registerInspectCallback($class, $column, self::inspect);
$value = FALSE;
if ($currency_column) {
$value = $currency_column;
if (empty(self::$currency_columns[$class])) {
self::$currency_columns[$class] = array();
}
self::$currency_columns[$class][$currency_column] = $column;
if (!fORM::checkHookCallback($class, 'post::loadFromResult()', self::makeMoneyObjects)) {
fORM::registerHookCallback($class, 'post::loadFromResult()', self::makeMoneyObjects);
}
if (!fORM::checkHookCallback($class, 'pre::validate()', self::makeMoneyObjects)) {
fORM::registerHookCallback($class, 'pre::validate()', self::makeMoneyObjects);
}
fORM::registerActiveRecordMethod($class, 'set' . $camelized_column, self::setMoneyColumn);
fORM::registerActiveRecordMethod($class, 'set' . fGrammar::camelize($currency_column, TRUE), self::setCurrencyColumn);
} else {
fORM::registerObjectifyCallback($class, $column, self::objectifyMoney);
}
if (empty(self::$money_columns[$class])) {
self::$money_columns[$class] = array();
}
self::$money_columns[$class][$column] = $value;
}
示例2: store
/**
* 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');
//.........这里部分代码省略.........
示例3: validateOneToStar
/**
* Validates one-to-* related records
*
* @param string $class The class to validate the related records for
* @param array &$values The values for the object
* @param array &$related_records The related records for the object
* @param string $related_class The name of the class for this record set
* @param string $route The route between the table and related table
* @return array An array of validation messages
*/
private static function validateOneToStar($class, &$values, &$related_records, $related_class, $route)
{
$schema = fORMSchema::retrieve($class);
$table = fORM::tablize($class);
$related_table = fORM::tablize($related_class);
$relationship = fORMSchema::getRoute($schema, $table, $related_table, $route);
$first_pk_column = self::determineFirstPKColumn($class, $related_class, $route);
$filter = self::determineRequestFilter($class, $related_class, $route);
$pk_field = $filter . $first_pk_column;
$input_keys = array_keys(fRequest::get($pk_field, 'array', array()));
$related_record_name = self::getRelatedRecordName($class, $related_class, $route);
$messages = array();
$one_to_one = fORMSchema::isOneToOne($schema, $table, $related_table, $route);
if ($one_to_one) {
$records = array(self::createRecord($class, $values, $related_records, $related_class, $route));
} else {
$records = self::buildRecords($class, $values, $related_records, $related_class, $route);
}
foreach ($records as $i => $record) {
fRequest::filter($filter, isset($input_keys[$i]) ? $input_keys[$i] : $i);
$record_messages = $record->validate(TRUE);
foreach ($record_messages as $column => $record_message) {
// Ignore validation messages about the primary key since it will be added
if ($column == $relationship['related_column']) {
continue;
}
if ($one_to_one) {
$token_field = fValidationException::formatField('__TOKEN__');
$extract_message_regex = '#' . str_replace('__TOKEN__', '(.*?)', preg_quote($token_field, '#')) . '(.*)$#D';
preg_match($extract_message_regex, $record_message, $matches);
$column_name = self::compose('%1$s %2$s', $related_record_name, $matches[1]);
$messages[$related_table . '::' . $column] = self::compose('%1$s%2$s', fValidationException::formatField($column_name), $matches[2]);
} else {
$main_key = $related_table . '[' . $i . ']';
if (!isset($messages[$main_key])) {
if (isset(self::$validation_name_methods[$class][$related_class][$route])) {
$name = $record->{self::$validation_name_methods[$class][$related_class][$route]}($i + 1);
} else {
$name = $related_record_name . ' #' . ($i + 1);
}
$messages[$main_key] = array('name' => $name, 'errors' => array());
}
$messages[$main_key]['errors'][$column] = $record_message;
}
}
fRequest::unfilter();
}
return $messages;
}
示例4: configureTimezoneColumn
/**
* Sets a timestamp column to store the timezone in another column
*
* Since not all databases support timezone information in timestamp
* columns, this method allows storing the timezone in another columns.
* When the timestamp and timezone are retrieved from the database, they
* will be automatically combined together into an fTimestamp object.
*
* @param mixed $class The class name or instance of the class to set the column format
* @param string $timestamp_column The timestamp column to store the timezone for
* @param string $timezone_column The column to store the timezone in
* @return void
*/
public static function configureTimezoneColumn($class, $timestamp_column, $timezone_column)
{
$class = fORM::getClass($class);
$table = fORM::tablize($class);
$schema = fORMSchema::retrieve($class);
$timestamp_data_type = $schema->getColumnInfo($table, $timestamp_column, 'type');
if ($timestamp_data_type != 'timestamp') {
throw new fProgrammerException('The timestamp column specified, %1$s, is a %2$s column. Must be a %3$s to have a related timezone column.', $timestamp_column, $data_type, 'timestamp');
}
$timezone_column_data_type = $schema->getColumnInfo($table, $timezone_column, 'type');
$valid_timezone_column_data_types = array('varchar', 'char', 'text');
if (!in_array($timezone_column_data_type, $valid_timezone_column_data_types)) {
throw new fProgrammerException('The timezone column specified, %1$s, is a %2$s column. Must be %3$s to be set as a timezone column.', $timezone_column, $timezone_column_data_type, join(', ', $valid_timezone_column_data_types));
}
if (!fORM::checkHookCallback($class, 'post::validate()', self::validateTimezoneColumns)) {
fORM::registerHookCallback($class, 'post::validate()', self::validateTimezoneColumns);
}
if (!fORM::checkHookCallback($class, 'post::loadFromResult()', self::makeTimestampObjects)) {
fORM::registerHookCallback($class, 'post::loadFromResult()', self::makeTimestampObjects);
}
if (!fORM::checkHookCallback($class, 'pre::validate()', self::makeTimestampObjects)) {
fORM::registerHookCallback($class, 'pre::validate()', self::makeTimestampObjects);
}
fORM::registerInspectCallback($class, $timezone_column, self::inspect);
fORM::registerActiveRecordMethod($class, 'set' . fGrammar::camelize($timestamp_column, TRUE), self::setTimestampColumn);
fORM::registerActiveRecordMethod($class, 'set' . fGrammar::camelize($timezone_column, TRUE), self::setTimezoneColumn);
if (empty(self::$timestamp_columns[$class])) {
self::$timestamp_columns[$class] = array();
}
self::$timestamp_columns[$class][$timestamp_column] = $timezone_column;
if (empty(self::$timezone_columns[$class])) {
self::$timezone_columns[$class] = array();
}
self::$timezone_columns[$class][$timezone_column] = $timestamp_column;
}
示例5: precreate
/**
* Creates the objects for related records that are in a one-to-one or many-to-one relationship with the current class in a single DB query
*
* @param string $related_class This should be the name of a related class
* @param string $route This should be the column name of the foreign key and is only required when there are multiple routes to a related table. If there are multiple routes and this is not specified, an fProgrammerException will be thrown.
* @return fRecordSet The record set object, to allow for method chaining
*/
private function precreate($related_class, $route = NULL)
{
if (!$this->records) {
return $this;
}
$this->validateSingleClass('precreate');
// If there are no primary keys we can just exit
if (!array_merge($this->getPrimaryKeys())) {
return $this;
}
fActiveRecord::validateClass($related_class);
fActiveRecord::forceConfigure($related_class);
$relationship = fORMSchema::getRoute(fORMSchema::retrieve($this->class), fORM::tablize($this->class), fORM::tablize($related_class), $route, '*-to-one');
$values = $this->call('get' . fGrammar::camelize($relationship['column'], TRUE));
$values = array_unique($values);
self::build($related_class, array($relationship['related_column'] . '=' => $values));
return $this;
}
示例6: validate
/**
* Validates values for an fActiveRecord object against the database schema and any additional rules that have been added
*
* @internal
*
* @param fActiveRecord $object The instance of the class to validate
* @param array $values The values to validate
* @param array $old_values The old values for the record
* @return array An array of messages
*/
public static function validate($object, $values, $old_values)
{
$class = get_class($object);
$table = fORM::tablize($class);
$schema = fORMSchema::retrieve($class);
self::initializeRuleArrays($class);
$validation_messages = array();
// Convert objects into values for validation
foreach ($values as $column => $value) {
$values[$column] = fORM::scalarize($class, $column, $value);
}
foreach ($old_values as $column => $column_values) {
foreach ($column_values as $key => $value) {
$old_values[$column][$key] = fORM::scalarize($class, $column, $value);
}
}
$message_array = self::checkPrimaryKeys($schema, $object, $values, $old_values);
if ($message_array) {
$validation_messages[key($message_array)] = current($message_array);
}
$column_info = $schema->getColumnInfo($table);
foreach ($column_info as $column => $info) {
$message = self::checkAgainstSchema($schema, $object, $column, $values, $old_values);
if ($message) {
$validation_messages[$column] = $message;
}
}
$messages = self::checkUniqueConstraints($schema, $object, $values, $old_values);
if ($messages) {
$validation_messages = array_merge($validation_messages, $messages);
}
foreach (self::$valid_values_rules[$class] as $column => $valid_values) {
$message = self::checkValidValuesRule($class, $values, $column, $valid_values);
if ($message) {
$validation_messages[$column] = $message;
}
}
foreach (self::$regex_rules[$class] as $column => $rule) {
$message = self::checkRegexRule($class, $values, $column, $rule['regex'], $rule['message']);
if ($message) {
$validation_messages[$column] = $message;
}
}
foreach (self::$conditional_rules[$class] as $rule) {
$messages = self::checkConditionalRule($schema, $class, $values, $rule['main_columns'], $rule['conditional_values'], $rule['conditional_columns']);
if ($messages) {
$validation_messages = array_merge($validation_messages, $messages);
}
}
foreach (self::$one_or_more_rules[$class] as $rule) {
$message = self::checkOneOrMoreRule($schema, $class, $values, $rule['columns']);
if ($message) {
$validation_messages[join(',', $rule['columns'])] = $message;
}
}
foreach (self::$only_one_rules[$class] as $rule) {
$message = self::checkOnlyOneRule($schema, $class, $values, $rule['columns']);
if ($message) {
$validation_messages[join(',', $rule['columns'])] = $message;
}
}
return $validation_messages;
}
示例7: validate
/**
* 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));
}
}
}
示例8: insertFromAndGroupByClauses
/**
* Finds all of the table names in the SQL and creates the appropriate `FROM` and `GROUP BY` clauses with all necessary joins
*
* The SQL string should contain two placeholders, `:from_clause` and
* `:group_by_clause`. All columns should be qualified with their full table
* name. Here is an example SQL string to pass in presumming that the
* tables users and groups are in a relationship:
*
* {{{
* SELECT users.* FROM :from_clause WHERE groups.group_id = 5 :group_by_clause ORDER BY lower(users.first_name) ASC
* }}}
*
* @internal
*
* @param string $table The main table to be queried
* @param string $sql The SQL to insert the `FROM` clause into
* @return string The SQL `FROM` clause
*/
public static function insertFromAndGroupByClauses($table, $sql)
{
$joins = array();
if (strpos($sql, ':from_clause') === FALSE) {
throw new fProgrammerException("No %1\$s placeholder was found in:%2\$s", ':from_clause', "\n" . $sql);
}
if (strpos($sql, ':group_by_clause') === FALSE && !preg_match('#group\\s+by#i', $sql)) {
throw new fProgrammerException("No %1\$s placeholder was found in:%2\$s", ':group_by_clause', "\n" . $sql);
}
$has_group_by_placeholder = strpos($sql, ':group_by_clause') !== FALSE ? TRUE : FALSE;
// Separate the SQL from quoted values
preg_match_all("#(?:'(?:''|\\\\'|\\\\[^']|[^'\\\\])*')|(?:[^']+)#", $sql, $matches);
$table_alias = $table;
$used_aliases = array();
$table_map = array();
// If we are not passing in existing joins, start with the specified table
if (!$joins) {
$joins[] = array('join_type' => 'none', 'table_name' => $table, 'table_alias' => $table_alias);
}
$used_aliases[] = $table_alias;
foreach ($matches[0] as $match) {
if ($match[0] != "'") {
preg_match_all('#\\b((?:(\\w+)(?:\\{(\\w+)\\})?=>)?(\\w+)(?:\\{(\\w+)\\})?)\\.\\w+\\b#m', $match, $table_matches, PREG_SET_ORDER);
foreach ($table_matches as $table_match) {
if (!isset($table_match[5])) {
$table_match[5] = NULL;
}
// This is a related table that is going to join to a once-removed table
if (!empty($table_match[2])) {
$related_table = $table_match[2];
$route = fORMSchema::getRouteName($table, $related_table, $table_match[3]);
$join_name = $table . '_' . $related_table . '{' . $route . '}';
self::createJoin($table, $table_alias, $related_table, $route, $joins, $used_aliases);
$once_removed_table = $table_match[4];
$route = fORMSchema::getRouteName($related_table, $once_removed_table, $table_match[5]);
$join_name = self::createJoin($related_table, $joins[$join_name]['table_alias'], $once_removed_table, $route, $joins, $used_aliases);
$table_map[$table_match[1]] = $joins[$join_name]['table_alias'];
// This is a related table
} elseif (($table_match[4] != $table || fORMSchema::getRoutes($table, $table_match[4])) && $table_match[1] != $table) {
$related_table = $table_match[4];
$route = fORMSchema::getRouteName($table, $related_table, $table_match[5]);
// If the related table is the current table and it is a one-to-many we don't want to join
if ($table_match[4] == $table) {
$one_to_many_routes = fORMSchema::getRoutes($table, $related_table, 'one-to-many');
if (isset($one_to_many_routes[$route])) {
$table_map[$table_match[1]] = $table_alias;
continue;
}
}
$join_name = self::createJoin($table, $table_alias, $related_table, $route, $joins, $used_aliases);
$table_map[$table_match[1]] = $joins[$join_name]['table_alias'];
}
}
}
}
// Determine if we joined a *-to-many relationship
$joined_to_many = FALSE;
foreach ($joins as $name => $join) {
if (is_numeric($name)) {
continue;
}
if (substr($name, -5) == '_join') {
$joined_to_many = TRUE;
break;
}
$main_table = preg_replace('#_' . $join['table_name'] . '{\\w+}$#iD', '', $name);
$second_table = $join['table_name'];
$route = preg_replace('#^[^{]+{(\\w+)}$#D', '\\1', $name);
$routes = fORMSchema::getRoutes($main_table, $second_table, '*-to-many');
if (isset($routes[$route])) {
$joined_to_many = TRUE;
break;
}
}
$found_order_by = FALSE;
$from_clause = self::createFromClauseFromJoins($joins);
// If we are joining on a *-to-many relationship we need to group by the
// columns in the main table to prevent duplicate entries
if ($joined_to_many) {
$column_info = fORMSchema::retrieve()->getColumnInfo($table);
$group_by_clause = ' GROUP BY ';
$columns = array();
//.........这里部分代码省略.........
示例9: inspect
/**
* Returns the metadata about a column including features added by this class
*
* @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 mixed The metadata array or element specified
*/
public static function inspect($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);
$info = fORMSchema::retrieve()->getColumnInfo($table, $column);
$element = isset($parameters[0]) ? $parameters[0] : NULL;
$column = self::$ordering_columns[$class]['column'];
$other_columns = self::$ordering_columns[$class]['other_columns'];
// Retrieve the current max ordering index from the database
$sql = "SELECT max(" . $column . ") FROM " . $table;
if ($other_columns) {
$sql .= " WHERE " . self::createOtherFieldsWhereClause($table, $other_columns, $values);
}
$max_value = (int) fORMDatabase::retrieve()->translatedQuery($sql)->fetchScalar();
// If this is a new record, or in a new set, we need one more space in the ordering index
if (self::isInNewSet($column, $other_columns, $values, $old_values)) {
$max_value += 1;
}
$info['max_ordering_value'] = $max_value;
$info['feature'] = 'ordering';
fORM::callInspectCallbacks($class, $column, $info);
if ($element) {
return isset($info[$element]) ? $info[$element] : NULL;
}
return $info;
}
示例10: reflectPhpDoc
/**
* Generates phpdoc for class
* @return string
*/
public function reflectPhpDoc()
{
$signatures = array();
$class = get_class($this);
$table = fORM::tablize($class);
$schema = fORMSchema::retrieve($class);
foreach ($schema->getColumnInfo($table) as $column => $columnInfo) {
$camelizedColumn = fGrammar::camelize($column, TRUE);
// Get and set methods
$fixedType = $columnInfo['type'];
if ($fixedType == 'blob') {
$fixedType = 'string';
}
if ($fixedType == 'varchar') {
$fixedType = 'string';
}
if ($fixedType == 'date') {
$fixedType = 'fDate|string';
}
if ($fixedType == 'timestamp') {
$fixedType = 'fTimestamp|string';
}
if ($fixedType == 'time') {
$fixedType = 'fTime|string';
}
$firstFixedType = reset(explode('|', $fixedType));
$signatures[] = $this->generateMagicMethodPhpDoc('get' . $camelizedColumn, array(), $firstFixedType, "Gets the current value of {$column}");
$signatures[] = $this->generateMagicMethodPhpDoc('set' . $camelizedColumn, array($fixedType => $column), $class, "Sets the value for {$column}");
}
return $signatures;
}
示例11: reflect
/**
* Adjusts the fActiveRecord::reflect() signatures of columns that have been configured in this class
*
* @internal
*
* @param string $class The class to reflect
* @param array &$signatures The associative array of `{method name} => {signature}`
* @param boolean $include_doc_comments If doc comments should be included with the signature
* @return void
*/
public static function reflect($class, &$signatures, $include_doc_comments)
{
if (isset(self::$link_columns[$class])) {
foreach (self::$link_columns[$class] as $column => $enabled) {
$signature = '';
if ($include_doc_comments) {
$signature .= "/**\n";
$signature .= " * Prepares the value of " . $column . " for output into HTML\n";
$signature .= " * \n";
$signature .= " * This method will ensure all links that start with a domain name are preceeded by http://\n";
$signature .= " * \n";
$signature .= " * @param boolean \$create_link Will cause link to be automatically converted into an [a] tag\n";
$signature .= " * @return string The HTML-ready value\n";
$signature .= " */\n";
}
$prepare_method = 'prepare' . fGrammar::camelize($column, TRUE);
$signature .= 'public function ' . $prepare_method . '($create_link=FALSE)';
$signatures[$prepare_method] = $signature;
}
}
if (isset(self::$number_columns[$class])) {
$table = fORM::tablize($class);
$schema = fORMSchema::retrieve($class);
foreach (self::$number_columns[$class] as $column => $enabled) {
$camelized_column = fGrammar::camelize($column, TRUE);
$type = $schema->getColumnInfo($table, $column, 'type');
// Get and set methods
$signature = '';
if ($include_doc_comments) {
$signature .= "/**\n";
$signature .= " * Gets the current value of " . $column . "\n";
$signature .= " * \n";
$signature .= " * @return fNumber The current value\n";
$signature .= " */\n";
}
$get_method = 'get' . $camelized_column;
$signature .= 'public function ' . $get_method . '()';
$signatures[$get_method] = $signature;
$signature = '';
if ($include_doc_comments) {
$signature .= "/**\n";
$signature .= " * Sets the value for " . $column . "\n";
$signature .= " * \n";
$signature .= " * @param fNumber|string|integer \$" . $column . " The new value - don't use floats since they are imprecise\n";
$signature .= " * @return fActiveRecord The record object, to allow for method chaining\n";
$signature .= " */\n";
}
$set_method = 'set' . $camelized_column;
$signature .= 'public function ' . $set_method . '($' . $column . ')';
$signatures[$set_method] = $signature;
$signature = '';
if ($include_doc_comments) {
$signature .= "/**\n";
$signature .= " * Encodes the value of " . $column . " for output into an HTML form\n";
$signature .= " * \n";
$signature .= " * If the value is an fNumber object, the ->__toString() method will be called\n";
$signature .= " * resulting in the value without any thousands separators\n";
$signature .= " * \n";
if ($type == 'float') {
$signature .= " * @param integer \$decimal_places The number of decimal places to display - not passing any value or passing NULL will result in the intrisinc number of decimal places being shown\n";
}
$signature .= " * @return string The HTML form-ready value\n";
$signature .= " */\n";
}
$encode_method = 'encode' . $camelized_column;
$signature .= 'public function ' . $encode_method . '(';
if ($type == 'float') {
$signature .= '$decimal_places=NULL';
}
$signature .= ')';
$signatures[$encode_method] = $signature;
$signature = '';
if ($include_doc_comments) {
$signature .= "/**\n";
$signature .= " * Prepares the value of " . $column . " for output into HTML\n";
$signature .= " * \n";
$signature .= " * If the value is an fNumber object, the ->format() method will be called\n";
$signature .= " * resulting in the value including thousands separators\n";
$signature .= " * \n";
if ($type == 'float') {
$signature .= " * @param integer \$decimal_places The number of decimal places to display - not passing any value or passing NULL will result in the intrisinc number of decimal places being shown\n";
}
$signature .= " * @return string The HTML-ready value\n";
$signature .= " */\n";
}
$prepare_method = 'prepare' . $camelized_column;
$signature .= 'public function ' . $prepare_method . '(';
if ($type == 'float') {
$signature .= '$decimal_places=NULL';
}
//.........这里部分代码省略.........
示例12: precount
/**
* Counts the related records for all records in this set in one DB query
*
* @param string $related_class This should be the name of a related class
* @param string $route This should be a column name or a join table name and is only required when there are multiple routes to a related table. If there are multiple routes and this is not specified, an fProgrammerException will be thrown.
* @return fRecordSet The record set object, to allow for method chaining
*/
private function precount($related_class, $route = NULL)
{
if (!$this->records) {
return $this;
}
$this->validateSingleClass('precount');
// If there are no primary keys we can just exit
if (!array_merge($this->getPrimaryKeys())) {
return $this;
}
$related_table = fORM::tablize($related_class);
$table = fORM::tablize($this->class);
$route = fORMSchema::getRouteName($table, $related_table, $route, '*-to-many');
$relationship = fORMSchema::getRoute($table, $related_table, $route, '*-to-many');
$table_with_route = $route ? $table . '{' . $route . '}' : $table;
// Build the query out
$where_sql = $this->constructWhereClause($route);
$order_by_sql = $this->constructOrderByClause($route);
$related_table_keys = fORMSchema::retrieve()->getKeys($related_table, 'primary');
$related_table_keys = fORMDatabase::addTableToValues($related_table, $related_table_keys);
$related_table_keys = join(', ', $related_table_keys);
$column = $table_with_route . '.' . $relationship['column'];
$new_sql = 'SELECT count(' . $related_table_keys . ') AS __flourish_count, ' . $column . ' AS __flourish_column ';
$new_sql .= ' FROM :from_clause ';
$new_sql .= ' WHERE ' . $where_sql;
$new_sql .= ' GROUP BY ' . $column;
$new_sql .= ' ORDER BY ' . $column . ' ASC';
$new_sql = fORMDatabase::insertFromAndGroupByClauses($related_table, $new_sql);
// Run the query and inject the results into the records
$result = fORMDatabase::retrieve()->translatedQuery($new_sql);
$counts = array();
foreach ($result as $row) {
$counts[$row['__flourish_column']] = (int) $row['__flourish_count'];
}
unset($result);
$total_records = sizeof($this->records);
$get_method = 'get' . fGrammar::camelize($relationship['column'], TRUE);
$tally_method = 'tally' . fGrammar::pluralize($related_class);
for ($i = 0; $i < $total_records; $i++) {
$record = $this->records[$i];
$count = isset($counts[$record->{$get_method}()]) ? $counts[$record->{$get_method}()] : 0;
$record->{$tally_method}($count, $route);
}
return $this;
}
示例13: store
/**
* 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
*
* @return fActiveRecord The record object, to allow for method chaining
*/
public function store()
{
$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);
try {
$table = fORM::tablize($class);
$column_info = fORMSchema::retrieve()->getColumnInfo($table);
// New auto-incrementing records require lots of special stuff, so we'll detect them here
$new_autoincrementing_record = FALSE;
if (!$this->exists()) {
$pk_columns = fORMSchema::retrieve()->getKeys($table, 'primary');
if (sizeof($pk_columns) == 1 && $column_info[$pk_columns[0]]['auto_increment'] && !$this->values[$pk_columns[0]]) {
$new_autoincrementing_record = TRUE;
$pk_column = $pk_columns[0];
}
}
$inside_db_transaction = fORMDatabase::retrieve()->isInsideTransaction();
if (!$inside_db_transaction) {
fORMDatabase::retrieve()->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
$sql_values = array();
foreach ($column_info as $column => $info) {
$value = fORM::scalarize($class, $column, $this->values[$column]);
$sql_values[$column] = fORMDatabase::escapeBySchema($table, $column, $value);
}
// Most databases don't like the auto incrementing primary key to be set to NULL
if ($new_autoincrementing_record && $sql_values[$pk_column] == 'NULL') {
unset($sql_values[$pk_column]);
}
if (!$this->exists()) {
$sql = $this->constructInsertSQL($sql_values);
} else {
$sql = $this->constructUpdateSQL($sql_values);
}
$result = fORMDatabase::retrieve()->translatedQuery($sql);
// If there is an auto-incrementing primary key, grab the value from the database
if ($new_autoincrementing_record) {
$this->set($pk_column, $result->getAutoIncrementedValue());
}
// Storing *-to-many relationships
fORMRelated::store($class, $this->values, $this->related_records);
fORM::callHookCallbacks($this, 'pre-commit::store()', $this->values, $this->old_values, $this->related_records, $this->cache);
if (!$inside_db_transaction) {
fORMDatabase::retrieve()->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) {
fORMDatabase::retrieve()->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;
}
示例14: storeManyToMany
/**
* Associates a set of many-to-many related records with the current record
*
* @internal
*
* @param array &$values The current values for the main record being stored
* @param array $relationship The information about the relationship between this object and the records in the record set
* @param array $related_info An array containing the keys `'record_set'`, `'count'`, `'primary_keys'` and `'associate'`
* @return void
*/
public static function storeManyToMany(&$values, $relationship, $related_info)
{
$column_value = $values[$relationship['column']];
// First, we remove all existing relationships between the two tables
$join_table = $relationship['join_table'];
$join_column = $relationship['join_column'];
$join_column_value = fORMDatabase::escapeBySchema($join_table, $join_column, $column_value);
$delete_sql = 'DELETE FROM ' . $join_table;
$delete_sql .= ' WHERE ' . $join_column . ' = ' . $join_column_value;
fORMDatabase::retrieve()->translatedQuery($delete_sql);
// Then we add back the ones in the record set
$join_related_column = $relationship['join_related_column'];
$related_pk_columns = fORMSchema::retrieve()->getKeys($relationship['related_table'], 'primary');
$related_column_values = array();
// If the related column is the primary key, we can just use the primary keys if we have them
if ($related_pk_columns[0] == $relationship['related_column'] && $related_info['primary_keys']) {
$related_column_values = $related_info['primary_keys'];
// Otherwise we need to pull the related values out of the record set
} else {
// If there is no record set, build it from the primary keys
if (!$related_info['record_set']) {
$related_class = fORM::classize($relationship['related_table']);
$related_info['record_set'] = fRecordSet::build($related_class, array($related_pk_columns[0] . '=' => $related_info['primary_keys']));
}
$get_related_method_name = 'get' . fGrammar::camelize($relationship['related_column'], TRUE);
foreach ($related_info['record_set'] as $record) {
$related_column_values[] = $record->{$get_related_method_name}();
}
}
// Ensure we aren't storing duplicates
$related_column_values = array_unique($related_column_values);
foreach ($related_column_values as $related_column_value) {
$related_column_value = fORMDatabase::escapeBySchema($join_table, $join_related_column, $related_column_value);
$insert_sql = 'INSERT INTO ' . $join_table . ' (' . $join_column . ', ' . $join_related_column . ') ';
$insert_sql .= 'VALUES (' . $join_column_value . ', ' . $related_column_value . ')';
fORMDatabase::retrieve()->translatedQuery($insert_sql);
}
}
示例15: setupORM
protected function setupORM()
{
if ($this->isOrmSettedUp) {
return;
}
$this->defineConstants();
// Extract port from host. See wpdb::db_connect
$port = null;
$host = $this->wp->getDbHost();
if (preg_match('/^(.+):(\\d+)$/', trim($host), $m)) {
$host = $m[1];
$port = $m[2];
}
$database = new fDatabase('mysql', $this->wp->getDbName(), $this->wp->getDbUser(), $this->wp->getDbPassword(), $host, $port);
// $database->enableDebugging(true);
fORMDatabase::attach($database);
fORM::mapClassToTable('WpTesting_Model_Test', WP_DB_PREFIX . 'posts');
fORM::mapClassToTable('WpTesting_Model_Question', WPT_DB_PREFIX . 'questions');
fORM::mapClassToTable('WpTesting_Model_Taxonomy', WP_DB_PREFIX . 'term_taxonomy');
fORM::mapClassToTable('WpTesting_Model_GlobalAnswer', WP_DB_PREFIX . 'terms');
fORM::mapClassToTable('WpTesting_Model_Answer', WPT_DB_PREFIX . 'answers');
fORM::mapClassToTable('WpTesting_Model_Scale', WP_DB_PREFIX . 'terms');
fORM::mapClassToTable('WpTesting_Model_Score', WPT_DB_PREFIX . 'scores');
fORM::mapClassToTable('WpTesting_Model_Passing', WPT_DB_PREFIX . 'passings');
fORM::mapClassToTable('WpTesting_Model_Result', WP_DB_PREFIX . 'terms');
fORM::mapClassToTable('WpTesting_Model_Formula', WPT_DB_PREFIX . 'formulas');
fORM::mapClassToTable('WpTesting_Model_Respondent', WP_DB_PREFIX . 'users');
fGrammar::addSingularPluralRule('Taxonomy', 'Taxonomy');
fGrammar::addSingularPluralRule('Score', 'Score');
fGrammar::addSingularPluralRule('Answer', 'Answer');
$schema = fORMSchema::retrieve('name:default');
$fkOptions = array('on_delete' => 'cascade', 'on_update' => 'cascade');
$schema->setKeysOverride(array(array('column' => 'test_id', 'foreign_table' => WP_DB_PREFIX . 'posts', 'foreign_column' => 'ID') + $fkOptions), WPT_DB_PREFIX . 'questions', 'foreign');
$schema->setKeysOverride(array(array('column' => 'answer_id', 'foreign_table' => WPT_DB_PREFIX . 'answers', 'foreign_column' => 'answer_id') + $fkOptions, array('column' => 'scale_id', 'foreign_table' => WP_DB_PREFIX . 'terms', 'foreign_column' => 'term_id') + $fkOptions), WPT_DB_PREFIX . 'scores', 'foreign');
$schema->setKeysOverride(array(array('column' => 'test_id', 'foreign_table' => WP_DB_PREFIX . 'posts', 'foreign_column' => 'ID') + $fkOptions, array('column' => 'respondent_id', 'foreign_table' => WP_DB_PREFIX . 'users', 'foreign_column' => 'ID') + $fkOptions), WPT_DB_PREFIX . 'passings', 'foreign');
$schema->setKeysOverride(array(array('column' => 'answer_id', 'foreign_table' => WPT_DB_PREFIX . 'answers', 'foreign_column' => 'answer_id') + $fkOptions, array('column' => 'passing_id', 'foreign_table' => WPT_DB_PREFIX . 'passings', 'foreign_column' => 'passing_id') + $fkOptions), WPT_DB_PREFIX . 'passing_answers', 'foreign');
$schema->setKeysOverride(array(array('column' => 'test_id', 'foreign_table' => WP_DB_PREFIX . 'posts', 'foreign_column' => 'ID') + $fkOptions, array('column' => 'result_id', 'foreign_table' => WP_DB_PREFIX . 'terms', 'foreign_column' => 'term_id') + $fkOptions), WPT_DB_PREFIX . 'formulas', 'foreign');
$schema->setColumnInfoOverride(null, WP_DB_PREFIX . 'term_relationships', 'term_order');
$schema->setKeysOverride(array(array('column' => 'object_id', 'foreign_table' => WP_DB_PREFIX . 'posts', 'foreign_column' => 'ID') + $fkOptions, array('column' => 'term_taxonomy_id', 'foreign_table' => WP_DB_PREFIX . 'term_taxonomy', 'foreign_column' => 'term_taxonomy_id') + $fkOptions), WP_DB_PREFIX . 'term_relationships', 'foreign');
$schema->setKeysOverride(array(array('column' => 'term_id', 'foreign_table' => WP_DB_PREFIX . 'terms', 'foreign_column' => 'term_id') + $fkOptions), WP_DB_PREFIX . 'term_taxonomy', 'foreign');
$schema->setKeysOverride(array(array('column' => 'question_id', 'foreign_table' => WPT_DB_PREFIX . 'questions', 'foreign_column' => 'question_id') + $fkOptions, array('column' => 'global_answer_id', 'foreign_table' => WP_DB_PREFIX . 'terms', 'foreign_column' => 'term_id') + $fkOptions), WPT_DB_PREFIX . 'answers', 'foreign');
$schema->setKeysOverride(array(), WPT_DB_PREFIX . 'sections', 'foreign');
$schema->setKeysOverride(array(), WPT_DB_PREFIX . 'fields', 'foreign');
$schema->setKeysOverride(array(), WPT_DB_PREFIX . 'field_values', 'foreign');
$this->wp->doAction('wp_testing_orm_setup', $schema, $database);
$this->isOrmSettedUp = true;
}