/** * doExport * * FIXME: This function has ugly hacks in it for temporarily disabling INDEXBY query parts of tables * to export. * * Update from jwage: I am not sure if their is any other better solution for this. It may be the correct * solution to disable the indexBy settings for tables when exporting data fixtures. Maybe a better idea * would be to extract this functionality to a pair of functions to enable/disable the index by settings * so simply turn them on and off when they need to query for the translations standalone and don't need * it to be indexed by the lang. * * @return void */ public function doExport() { $models = Doctrine_Core::getLoadedModels(); $specifiedModels = $this->getModels(); $data = array(); // for situation when the $models array is empty, but the $specifiedModels array isn't if (empty($models)) { $models = $specifiedModels; } $models = Doctrine_Core::initializeModels($models); // temporarily disable indexBy query parts of selected and related tables $originalIndexBy = array(); foreach ($models as $name) { $table = Doctrine_Core::getTable($name); if (!is_null($indexBy = $table->getBoundQueryPart('indexBy'))) { $originalIndexBy[$name] = $indexBy; $table->bindQueryPart('indexBy', null); } } foreach ($models as $name) { if (!empty($specifiedModels) and !in_array($name, $specifiedModels)) { continue; } $results = Doctrine_Core::getTable($name)->findAll(); if ($results->count() > 0) { $data[$name] = $results; } } // Restore the temporarily disabled indexBy query parts foreach ($originalIndexBy as $name => $indexBy) { Doctrine_Core::getTable($name)->bindQueryPart('indexBy', $indexBy); } $data = $this->prepareData($data); return $this->dumpData($data); }
/** * @see sfTask */ protected function execute($arguments = array(), $options = array()) { $this->logSection('doctrine', 'created tables successfully'); $databaseManager = new sfDatabaseManager($this->configuration); $config = $this->getCliConfig(); Doctrine_Core::loadModels($config['models_path'], Doctrine_Core::MODEL_LOADING_CONSERVATIVE); Doctrine_Core::createTablesFromArray(Doctrine_Core::getLoadedModels()); }
/** * Loads all model classes and returns an array of model names. * * @return array An array of model names */ protected function loadModels() { Doctrine_Core::loadModels($this->configuration->getModelDirs()); $models = Doctrine_Core::getLoadedModels(); $models = Doctrine_Core::initializeModels($models); $models = Doctrine_Core::filterInvalidModels($models); return $models; }
public function testModelLoadingCacheInformation() { $models = Doctrine_Core::getLoadedModels(); $this->assertTrue(in_array('AggressiveModelLoadingUser', $models)); $this->assertTrue(in_array('ConservativeModelLoadingProfile', $models)); $this->assertTrue(in_array('ConservativeModelLoadingContact', $models)); $modelFiles = Doctrine_Core::getLoadedModelFiles(); $this->assertTrue(file_exists($modelFiles['ConservativeModelLoadingUser'])); $this->assertTrue(file_exists($modelFiles['ConservativeModelLoadingProfile'])); $this->assertTrue(file_exists($modelFiles['ConservativeModelLoadingContact'])); }
public function run() { $this->getDatabaseManager(); // build all tables for models if (!$this->getOption('models')) { sfOpenPNEApplicationConfiguration::unregisterZend(); $path = sfConfig::get('sf_lib_dir') . '/model/doctrine'; Doctrine_Core::loadModels($path, Doctrine_Core::MODEL_LOADING_CONSERVATIVE); Doctrine_Core::createTablesFromArray(Doctrine_Core::getLoadedModels()); sfOpenPNEApplicationConfiguration::registerZend(); return true; } foreach ($this->getQueries() as $query) { $db = $this->getDatabaseManager()->getDatabase('doctrine'); $db->getDoctrineConnection()->execute($query); } }
/** * exportSql * returns the sql for exporting Doctrine_Record classes to a schema * * if the directory parameter is given this method first iterates * recursively trhough the given directory in order to find any model classes * * Then it iterates through all declared classes and creates tables for the ones * that extend Doctrine_Record and are not abstract classes * * @throws Doctrine_Connection_Exception if some error other than Doctrine_Core::ERR_ALREADY_EXISTS * occurred during the create table operation * @param string $directory optional directory parameter * @return void */ public function exportSql($directory = null) { if ($directory !== null) { $models = Doctrine_Core::filterInvalidModels(Doctrine_Core::loadModels($directory)); } else { $models = Doctrine_Core::getLoadedModels(); } return $this->exportSortedClassesSql($models, false); }
/** * Generate a set of migrations from a set of models * * @param string $modelsPath Path to models * @param string $modelLoading What type of model loading to use when loading the models * @return boolean */ public function generateMigrationsFromModels($modelsPath = null, $modelLoading = null) { if ($modelsPath !== null) { $models = Doctrine_Core::filterInvalidModels(Doctrine_Core::loadModels($modelsPath, $modelLoading)); } else { $models = Doctrine_Core::getLoadedModels(); } $models = Doctrine_Core::initializeModels($models); $foreignKeys = array(); foreach ($models as $model) { $table = Doctrine_Core::getTable($model); if ($table->getTableName() !== $this->migration->getTableName()) { $export = $table->getExportableFormat(); $foreignKeys[$export['tableName']] = $export['options']['foreignKeys']; $up = $this->buildCreateTable($export); $down = $this->buildDropTable($export); $className = 'Add' . Doctrine_Inflector::classify($export['tableName']); $this->generateMigrationClass($className, array(), $up, $down); } } if (!empty($foreignKeys)) { $className = 'AddFks'; $up = array(); $down = array(); foreach ($foreignKeys as $tableName => $definitions) { $tableForeignKeyNames[$tableName] = array(); foreach ($definitions as $definition) { $up[] = $this->buildCreateForeignKey($tableName, $definition); $down[] = $this->buildDropForeignKey($tableName, $definition); } } $up = implode("\n", $up); $down = implode("\n", $down); if ($up || $down) { $this->generateMigrationClass($className, array(), $up, $down); } } return true; }
/** * Loads all Doctrine builders. */ protected function loadModels() { Doctrine_Core::loadModels($this->generatorManager->getConfiguration()->getModelDirs()); $models = Doctrine_Core::getLoadedModels(); $models = Doctrine_Core::initializeModels($models); $models = Doctrine_Core::filterInvalidModels($models); $this->models = $this->filterModels($models); return $this->models; }
/** * Returns models that have class files. * * @return array */ protected function getFileModels($modelsPath) { Doctrine_Core::loadModels($modelsPath); return Doctrine_Core::getLoadedModels(); }
/** * purge * * Purge all data for loaded models or for the passed array of Doctrine_Records * * @param string $models * @return void */ public function purge($models = null) { if ($models) { $models = Doctrine_Core::filterInvalidModels($models); } else { $models = Doctrine_Core::getLoadedModels(); } $connections = array(); foreach ($models as $model) { $connections[Doctrine_Core::getTable($model)->getConnection()->getName()][] = $model; } foreach ($connections as $connection => $models) { $models = Doctrine_Manager::getInstance()->getConnection($connection)->unitOfWork->buildFlushTree($models); $models = array_reverse($models); foreach ($models as $model) { Doctrine_Core::getTable($model)->createQuery()->delete()->execute(); } } }
/** * buildSchema * * Build schema array that can be dumped to file * * @param string $directory The directory of models to build the schema from * @param array $models The array of model names to build the schema for * @param integer $modelLoading The model loading strategy to use to load the models from the passed directory * @return void */ public function buildSchema($directory = null, $models = array(), $modelLoading = null) { if ($directory !== null) { $loadedModels = Doctrine_Core::filterInvalidModels(Doctrine_Core::loadModels($directory, $modelLoading)); } else { $loadedModels = Doctrine_Core::getLoadedModels(); } $array = array(); $parent = new ReflectionClass('Doctrine_Record'); $sql = array(); $fks = array(); $behaviors = array(); foreach (sfProjectConfiguration::getActive()->getPluginPaths() as $path) { if (strpos($path, 'sfPostgresDoctrinePlugin') !== false) { $behaviors = sfYaml::load(sfConfig::get('sf_config_dir') . DIRECTORY_SEPARATOR . 'plugins/sfPostgresDoctrinePlugin' . DIRECTORY_SEPARATOR . 'behaviors.yml'); break; } } // we iterate through the diff of previously declared classes // and currently declared classes foreach ($loadedModels as $className) { if (!empty($models) && !in_array($className, $models)) { continue; } $recordTable = Doctrine_Core::getTable($className); $data = $recordTable->getExportableFormat(); $table = array(); $table['connection'] = $recordTable->getConnection()->getName(); $remove = array('ptype', 'ntype', 'alltypes'); // Fix explicit length in schema, concat it to type in this format: type(length) $columns = array_keys($data['columns']); $tb = array(); foreach ((array) $behaviors as $name => $behavior) { $i = false; if (isset($behavior['tableName'])) { if (is_array($behavior['tableName'])) { if (in_array($data['tableName'], $behavior['tableName'])) { $i = true; } else { foreach ($behavior['tableName'] as $tName) { if (preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".+?"), $tName) . "\$/i", $data['tableName'], $m)) { $i = true; break; } } } } else { if ($behavior['tableName'] == 'all' || $behavior['tableName'] == $data['tableName'] || preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".+?"), $behavior['tableName']) . "\$/i", $data['tableName'], $m)) { $i = true; } } if ($i && isset($behavior['exclusions'])) { if (is_array($behavior['exclusions'])) { foreach ($behavior['exclusions'] as $tName) { if (preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".*?"), $tName) . "\$/i", $data['tableName'], $m)) { $i = false; break; } } } else { if (preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".*?"), $behavior['exclusions']) . "\$/i", $data['tableName'], $m)) { $i = false; } } } $cantHave = array(); $mustHave = array(); if ($i) { if (isset($behavior['condition']) && count($behavior['condition']) > 0 && isset($behavior['condition']['columns'])) { if (is_array($behavior['condition']['columns'])) { if (count($behavior['condition']['columns']) > 0) { foreach ($behavior['condition']['columns'] as $column) { if (preg_match('/^!/i', $column, $m)) { $cantHave[] = str_replace("!", "", $column); } else { $mustHave[] = $column; } } $isOK = true; if (count($mustHave > 0)) { if (count(array_intersect($columns, $mustHave)) != count($mustHave)) { $isOK = false; } } if ($isOK && count($cantHave > 0)) { if (count(array_intersect($columns, $cantHave)) > 0) { $isOK = false; } } if ($isOK) { if (array_key_exists('params', $behavior)) { if (is_array($behavior['params']) && count($behavior['params']) > 0) { $tb[$name] = isset($behavior['params']['all']) ? $behavior['params']['all'] : array(); foreach ($behavior['params'] as $tName => $p) { if ($tName != 'all' && ($data['tableName'] == $tName || preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".*?"), $tName) . "\$/i", $data['tableName'], $m))) { $tb[$name] = $this->arrayMerge($tb[$name], $p); } } } else { $tb[$name] = array(); } foreach ($mustHave as $col) { unset($data['columns'][$col]); } } } } } else { if ($behavior['condition']['columns'] != '') { if (preg_match('/^\\!/i', $behavior['condition']['columns'], $m)) { $cantHave[] = str_replace("!", "", $behavior['condition']['columns']); } else { $mustHave[] = $behavior['condition']['columns']; } $isOK = true; if (count($mustHave > 0)) { if (count(array_intersect($columns, $mustHave)) != count($mustHave)) { $isOK = false; } } if ($isOK && count($cantHave > 0)) { if (count(array_intersect($columns, $cantHave)) > 0) { $isOK = false; } } if ($isOK) { if (is_array($behavior['params']) && count($behavior['params']) > 0) { $tb[$name] = isset($behavior['params']['all']) ? $behavior['params']['all'] : array(); foreach ($behavior['params'] as $tName => $p) { if ($tName != 'all' && ($data['tableName'] == $tName || preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".*?"), $tName) . "\$/i", $data['tableName'], $m))) { $tb[$name] = $this->arrayMerge($tb[$name], $p); } } } else { $tb[$name] = array(); } foreach ($mustHave as $col) { unset($data['columns'][$col]); } } } else { $i = false; } } } else { if (array_key_exists('params', $behavior)) { if (is_array($behavior['params']) && count($behavior['params']) > 0) { $tb[$name] = isset($behavior['params']['all']) ? $behavior['params']['all'] : array(); foreach ($behavior['params'] as $tName => $p) { //if ($name == 'Callback') echo $tName.'--'.$data['tableName'].'--'.preg_match("/^".str_replace(array(".", "*"), array("\\.", ".*?"), $tName)."$/i", $data['tableName'], $m)."\n"; if ($tName != 'all' && ($data['tableName'] == $tName || preg_match("/^" . str_replace(array(".", "*"), array("\\.", ".*?"), $tName) . "\$/i", $data['tableName'], $m))) { $tb[$name] = $this->arrayMerge($tb[$name], $p); } } //$tb[$name] = array_merge(isset($behavior['params']['all']) ? $behavior['params']['all'] : array(), isset($behavior['params'][$data['tableName']]) ? $behavior['params'][$data['tableName']] : array()); } else { $tb[$name] = array(); } } else { $tb[$name] = array(); } } } } } if (count($tb) > 0) { $table['actAs'] = $tb; } foreach ($data['columns'] as $name => $column) { if (isset($column['length']) && $column['length'] && isset($column['scale']) && $column['scale']) { $data['columns'][$name]['type'] = $column['type'] . '(' . $column['length'] . ', ' . $column['scale'] . ')'; unset($data['columns'][$name]['length'], $data['columns'][$name]['scale']); } else { $data['columns'][$name]['type'] = $column['type'] . '(' . $column['length'] . ')'; unset($data['columns'][$name]['length']); } // Strip out schema information which is not necessary to be dumped to the yaml schema file foreach ($remove as $value) { if (isset($data['columns'][$name][$value])) { unset($data['columns'][$name][$value]); } } // If type is the only property of the column then lets abbreviate the syntax // columns: { name: string(255) } if (count($data['columns'][$name]) === 1 && isset($data['columns'][$name]['type'])) { $type = $data['columns'][$name]['type']; unset($data['columns'][$name]); $data['columns'][$name] = $type; } } $table['tableName'] = $data['tableName']; if (count($data['columns']) > 0) { $table['columns'] = $data['columns']; } $e = explode('.', $table['tableName']); if (2 == count($e)) { $table['package'] = ucfirst($e[0]) . '.' . 'Entities'; } if (get_parent_class($className) != $className && strpos($className, 'Base') === false) { if (strpos(get_parent_class($className), 'Base') === false) { if (get_parent_class($className) != "Doctrine_Record") { $table['inheritance'] = array('extends' => get_parent_class($className)); foreach ($table['columns'] as $key => $val) { if (true == $val['primary']) { unset($table['columns'][$key]); } } } } else { if (get_parent_class(get_parent_class($className)) != get_parent_class($className) && get_parent_class(get_parent_class($className)) != "Doctrine_Record") { $table['inheritance'] = array('extends' => get_parent_class(get_parent_class($className))); foreach ($table['columns'] as $key => $val) { if (1 == $val['primary']) { unset($table['columns'][$key]); } } } } } $relations = $recordTable->getRelations(); // unset inherited relation $keys = array_keys($relations); if (get_parent_class($className) != 'Doctrine_Record' && get_parent_class($className) != $className) { if (strpos(get_parent_class($className), 'Base') === false) { $keys = array_diff(array_keys($relations), array_keys(Doctrine_Core::getTable(get_parent_class($className))->getRelations())); } else { if (get_parent_class(get_parent_class($className)) != 'Doctrine_Record' && get_parent_class(get_parent_class($className)) != get_parent_class($className) && strpos(get_parent_class(get_parent_class($className)), 'Base') === false) { $keys = array_diff(array_keys($relations), array_keys(Doctrine_Core::getTable(get_parent_class(get_parent_class($className)))->getRelations())); } } } foreach ($relations as $key => $relation) { if (in_array($key, $keys)) { $relationData = $relation->toArray(); $relationKey = $relationData['alias']; if (isset($relationData['refTable']) && $relationData['refTable']) { $table['relations'][$relationKey]['refClass'] = $relationData['refTable']->getComponentName(); } if (isset($relationData['class']) && $relationData['class'] && $relation['class'] != $relationKey) { $table['relations'][$relationKey]['class'] = $relationData['class']; } $table['relations'][$relationKey]['local'] = $relationData['local']; $table['relations'][$relationKey]['foreign'] = $relationData['foreign']; if ($relationData['type'] === Doctrine_Relation::ONE) { $table['relations'][$relationKey]['type'] = 'one'; } else { if ($relationData['type'] === Doctrine_Relation::MANY) { $table['relations'][$relationKey]['type'] = 'many'; } else { $table['relations'][$relationKey]['type'] = 'one'; } } } } $array[$className] = $table; } return $array; }
/** * buildSchema * * Build schema array that can be dumped to file * * @param string $directory The directory of models to build the schema from * @param array $models The array of model names to build the schema for * @param integer $modelLoading The model loading strategy to use to load the models from the passed directory * @return void */ public function buildSchema($directory = null, $models = array(), $modelLoading = null) { if ($directory !== null) { $loadedModels = Doctrine_Core::filterInvalidModels(Doctrine_Core::loadModels($directory, $modelLoading)); } else { $loadedModels = Doctrine_Core::getLoadedModels(); } $array = array(); $parent = new ReflectionClass('Doctrine_Record'); $sql = array(); $fks = array(); // we iterate through the diff of previously declared classes // and currently declared classes foreach ($loadedModels as $className) { if ( ! empty($models) && !in_array($className, $models)) { continue; } $recordTable = Doctrine_Core::getTable($className); $data = $recordTable->getExportableFormat(); $table = array(); $table['connection'] = $recordTable->getConnection()->getName(); $remove = array('ptype', 'ntype', 'alltypes'); // Fix explicit length in schema, concat it to type in this format: type(length) foreach ($data['columns'] AS $name => $column) { if (isset($column['length']) && $column['length'] && isset($column['scale']) && $column['scale']) { $data['columns'][$name]['type'] = $column['type'] . '(' . $column['length'] . ', ' . $column['scale'] . ')'; unset($data['columns'][$name]['length'], $data['columns'][$name]['scale']); } else { $data['columns'][$name]['type'] = $column['type'] . '(' . $column['length'] . ')'; unset($data['columns'][$name]['length']); } // Strip out schema information which is not necessary to be dumped to the yaml schema file foreach ($remove as $value) { if (isset($data['columns'][$name][$value])) { unset($data['columns'][$name][$value]); } } // If type is the only property of the column then lets abbreviate the syntax // columns: { name: string(255) } if (count($data['columns'][$name]) === 1 && isset($data['columns'][$name]['type'])) { $type = $data['columns'][$name]['type']; unset($data['columns'][$name]); $data['columns'][$name] = $type; } } $table['tableName'] = $data['tableName']; $table['columns'] = $data['columns']; $relations = $recordTable->getRelations(); foreach ($relations as $key => $relation) { $relationData = $relation->toArray(); $relationKey = $relationData['alias']; if (isset($relationData['refTable']) && $relationData['refTable']) { $table['relations'][$relationKey]['refClass'] = $relationData['refTable']->getComponentName(); } if (isset($relationData['class']) && $relationData['class'] && $relation['class'] != $relationKey) { $table['relations'][$relationKey]['class'] = $relationData['class']; } $table['relations'][$relationKey]['local'] = $relationData['local']; $table['relations'][$relationKey]['foreign'] = $relationData['foreign']; if ($relationData['type'] === Doctrine_Relation::ONE) { $table['relations'][$relationKey]['type'] = 'one'; } else if ($relationData['type'] === Doctrine_Relation::MANY) { $table['relations'][$relationKey]['type'] = 'many'; } else { $table['relations'][$relationKey]['type'] = 'one'; } } $array[$className] = $table; } return $array; }
protected function buildDb($options) { $tmpdir = sfConfig::get('sf_data_dir') . '/fixtures_tmp'; $this->getFilesystem()->mkdirs($tmpdir); $this->getFilesystem()->remove(sfFinder::type('file')->in(array($tmpdir))); $pluginDirs = sfFinder::type('dir')->name('data')->in(sfFinder::type('dir')->name('op*Plugin')->maxdepth(1)->in(sfConfig::get('sf_plugins_dir'))); $fixturesDirs = sfFinder::type('dir')->name('fixtures')->prune('migrations', 'upgrade')->in(array_merge(array(sfConfig::get('sf_data_dir')), $this->configuration->getPluginSubPaths('/data'), $pluginDirs)); $i = 0; foreach ($fixturesDirs as $fixturesDir) { $files = sfFinder::type('file')->name('*.yml')->sort_by_name()->in(array($fixturesDir)); foreach ($files as $file) { $this->getFilesystem()->copy($file, $tmpdir . '/' . sprintf('%03d_%s_%s.yml', $i, basename($file, '.yml'), md5(uniqid(rand(), true)))); } $i++; } $task = new sfDoctrineBuildTask($this->dispatcher, $this->formatter); $task->setCommandApplication($this->commandApplication); $task->setConfiguration($this->configuration); $task->run(array(), array('no-confirmation' => true, 'db' => !$options['non-recreate-db'], 'model' => true, 'forms' => true, 'filters' => true, 'sql' => !$options['non-recreate-db'], 'and-load' => $options['non-recreate-db'] ? null : $tmpdir, 'application' => $options['application'], 'env' => $options['env'])); if ($options['non-recreate-db']) { $connection = Doctrine_Manager::connection(); $config = $this->getCliConfig(); Doctrine_Core::loadModels($config['models_path'], Doctrine_Core::MODEL_LOADING_CONSERVATIVE); $tables = array(); $relatedTables = array(); $droppedTables = array(); $models = Doctrine_Core::getLoadedModels(); foreach ($models as $model) { $table = Doctrine::getTable($model)->getTableName(); $tables[] = $table; $relations = $connection->import->listTableRelations($table); foreach ($relations as $relation) { if (empty($relatedTables[$relation['table']])) { $relatedTables[$relation['table']] = array(); } $relatedTables[$relation['table']][] = $table; } } // first, non-related tables can be removed $nonRelatedTables = array_diff($tables, array_keys($relatedTables)); foreach ($nonRelatedTables as $targetTable) { $droppedTables[] = $targetTable; if ($connection->import->tableExists($targetTable)) { $connection->export->dropTable($targetTable); } } // second, related tables uasort($relatedTables, create_function('$a, $b', '$_a = count($a); $_b = count($b); if ($_a == $_b) return 0; return ($_a < $_b) ? -1 : 1;')); foreach ($relatedTables as $relatedTable => &$relation) { $this->dropRelations($relatedTable, $relatedTables, $droppedTables); } $this->initDb($tmpdir); } $this->getFilesystem()->remove(sfFinder::type('file')->in(array($tmpdir))); $this->getFilesystem()->remove($tmpdir); }
/** * Load builders * * @return array Loaded models */ protected function loadModels() { Doctrine_Core::loadModels(array(sfConfig::get('sf_lib_dir') . '/model')); $this->models = $this->filterModels(Doctrine_Core::filterInvalidModels(Doctrine_Core::initializeModels(Doctrine_Core::getLoadedModels()))); return $this->models; }
/** Flush the database and reload base fixtures. * * @param bool $rebuild * true: The database will be dropped and rebuilt. * false: The method will try just to flush the data. * * Note that the first time flushDatabase() is called (per execution), the * database will be rebuilt regardless of $rebuild. * * @return static */ public function flushDatabase($rebuild = false) { if ($this->_connection) { /* The first time we run a test case, drop and rebuild the database. * * After that, we can simply truncate all tables for speed. */ if (empty(self::$_dbRebuilt) or $rebuild) { /* Don't try to drop the database unless it exists. */ $name = $this->getDatabaseName(); /** @noinspection PhpUndefinedFieldInspection */ if ($name and $this->_connection->import->databaseExists($name)) { $this->_connection->dropDatabase(); } $this->_connection->createDatabase(); Doctrine_Core::loadModels(sfConfig::get('sf_lib_dir') . '/model/doctrine', Doctrine_Core::MODEL_LOADING_CONSERVATIVE); Doctrine_Core::createTablesFromArray(Doctrine_Core::getLoadedModels()); self::$_dbRebuilt = true; } else { /* Determine the order we need to load models. */ if (!isset(self::$_dbFlushTree)) { /** @noinspection PhpUndefinedFieldInspection */ $models = $this->_connection->unitOfWork->buildFlushTree(Doctrine_Core::getLoadedModels()); self::$_dbFlushTree = array_reverse($models); } $this->_doPreFlush(); /* Delete records, paying special attention to SoftDelete. */ foreach (self::$_dbFlushTree as $model) { $table = Doctrine_Core::getTable($model); if ($table->hasTemplate('SoftDelete')) { /** @var $record Doctrine_Template_SoftDelete */ foreach ($table->createQuery()->execute() as $record) { $record->hardDelete(); } } $table->createQuery()->delete()->execute(); $table->clear(); } $this->_doPostFlush(); /** Clear all Doctrine table repositories to prevent memory leaks * between tests. */ $this->_connection->clear(); } } return $this; }