protected function fillSteps() { $questions = $this->test->buildQuestions(); $total = $questions->count(); $answered = $this->answeredQuestions->count(); foreach ($questions as $q => $question) { $records = fRecordSet::buildFromArray('WpTesting_Model_Question', array($q => $question)); $isCurrent = $answered == $q; $this->addStep(new WpTesting_Model_Step('', $records), $isCurrent); } return $this->enableStepsCounter(); }
/** * 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) { fORM::callHookCallbacks($this, 'pre::replicate()', $this->values, $this->old_values, $this->related_records, $this->cache, fActiveRecord::$replicate_level); fActiveRecord::$replicate_level++; $class = get_class($this); $hash = self::hash($this->values, $class); $schema = fORMSchema::retrieve($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 = $schema->getKeys($table, 'primary'); if (sizeof($pk_columns) == 1 && $schema->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 = $schema->getRelationships($table, 'many-to-many'); $one_to_many_relationships = $schema->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_class = fORM::getRelatedClass($class, $related_class); $related_table = fORM::tablize($related_class); $route = substr($parameter, $brace + 1, -1); } else { $related_class = fGrammar::singularize($parameter); $related_class = fORM::getRelatedClass($class, $related_class); $related_table = fORM::tablize($related_class); $route = fORMSchema::getRouteName($schema, $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 = $schema->getKeys($table, 'primary'); if (sizeof($pk_columns) != 1 || !$schema->getColumnInfo($table, $pk_columns[0], 'auto_increment')) { continue; } foreach ($records as $hash => $record) { $record->values[$pk_columns[0]] = NULL; } } fActiveRecord::$replicate_map = array(); } fORM::callHookCallbacks($this, 'post::replicate()', $this->values, $this->old_values, $this->related_records, $this->cache, fActiveRecord::$replicate_level); fORM::callHookCallbacks($clone, 'cloned::replicate()', $clone->values, $clone->old_values, $clone->related_records, $clone->cache, fActiveRecord::$replicate_level); return $clone; }
public function testUnique() { $set = fRecordSet::buildFromArray('User', array(new User(1, new User(2)))); $set = $set->merge(new User(2)); $set = $set->unique(); $this->assertEquals(array(1, 2), $set->getPrimaryKeys()); }
/** * Sets the values for records in a one-to-many relationship with this record * * @internal * * @param string $class The class to populate the related records of * @param array &$related_records The related records existing for the fActiveRecord class * @param string $related_class The related class to populate * @param string $route The route to the related class * @param boolean $recursive If a recursive populate should be performed on the child records * @return void */ public static function populateRecords($class, &$related_records, $related_class, $route = NULL, $recursive = FALSE) { fActiveRecord::validateClass($related_class); fActiveRecord::forceConfigure($related_class); $table = fORM::tablize($class); $related_table = fORM::tablize($related_class); $schema = fORMSchema::retrieve($class); $pk_columns = $schema->getKeys($related_table, 'primary'); $first_pk_column = self::determineFirstPKColumn($class, $related_class, $route); $filter = self::determineRequestFilter($class, $related_class, $route); $pk_field = $filter . $first_pk_column; $records = array(); $input_keys = array(); if (fRequest::check($pk_field, TRUE)) { $related_keys = fRequest::get($pk_field); $input_keys = is_array($related_keys) ? array_keys($related_keys) : array(NULL); } foreach ($input_keys as $input_key) { fRequest::filter($filter, $input_key); // Try to load the value from the database first try { if (sizeof($pk_columns) == 1) { $primary_key_values = fRequest::get($first_pk_column); } else { $primary_key_values = array(); foreach ($pk_columns as $pk_column) { $primary_key_values[$pk_column] = fRequest::get($pk_column); } } $record = new $related_class($primary_key_values); } catch (fNotFoundException $e) { $record = new $related_class(); } $record->populate($recursive); $records[] = $record; fRequest::unfilter(); } $record_set = fRecordSet::buildFromArray($related_class, $records); self::setRecordSet($class, $related_records, $related_class, $record_set, $route); self::flagForAssociation($class, $related_records, $related_class, $route); }
/** * @param fRecordSet $answers * @return self */ private function extractQuestionsFromAnswers(fRecordSet $answers) { $questions = array(); foreach ($answers as $answer) { /* @var $answer WpTesting_Model_Answer */ $questions[$answer->getQuestionId()] = $answer->createQuestion(); } $this->answeredQuestions = fRecordSet::buildFromArray('WpTesting_Model_Question', $questions); return $this; }
/** * Recursivly builds records. * * @param array* $completed_fixtures * Completed records is stored in this array * @param $fixture_data * Build records of this fixture */ private function buildRecords(&$completed_fixtures, $fixture_name, $traverse = TRUE) { if (array_key_exists($fixture_name, $completed_fixtures)) { return; } // Load data if (isset($this->fixture_data[$fixture_name]) === FALSE) { $this->loadFixture($fixture_name); } $class_name = fORM::classize($fixture_name); // If the class does not exists created it if (class_exists($class_name) === FALSE) { fORM::defineActiveRecordClass($class_name); } // Create the records $method_name = NULL; $record = NULL; $records = array(); foreach ($this->fixture_data[$fixture_name] as $record_data) { $record = new $class_name(); foreach ($record_data as $key => $value) { $method_name = 'set' . fGrammar::camelize($key, $upper = TRUE); $value = $this->applyHookCallbacks(self::PreSetBuildHook, $fixture_name, $key, $value); if ($this->isRelationshipKey($fixture_name, $key)) { $related_table = $this->getRelatedTable($fixture_name, $key); $required = $this->isRequiredKey($fixture_name, $key); if ($traverse && array_key_exists($related_table, $completed_fixtures) === FALSE && $fixture_name !== $related_table) { if (isset($value) && array_key_exists($related_table, $this->fixture_sources)) { $this->buildRecords($completed_fixtures, $related_table); array_unshift($this->tables_to_tear_down, $related_table); } } } $record->{$method_name}($value); } $record->store(); $records[] = $record; } $completed_fixtures[$fixture_name] = fRecordSet::buildFromArray($class_name, $records); }
/** * Prepare results through test, that has true formulas, using current test variables * * @return WpTesting_Model_Result[] */ public function buildResults() { $test = $this->createTest(); $variables = $test->buildFormulaVariables($this->buildScalesWithRangeOnce()); $result = array(); foreach ($test->buildFormulas() as $formula) { $formula->resetValues(); foreach ($variables as $variable) { $formula->addValue($variable->getSource(), $variable->getValue(), $variable->getValueAsRatio()); } if ($formula->isTrue()) { $result[] = $formula->createResult(); } } return fRecordSet::buildFromArray('WpTesting_Model_Result', $result); }