/** * Handle orphaned rows in intermediate many_many tables. */ public function handleBrokenManyManyRelations() { JanitorDebug::message("handleBrokenManyManyRelations()"); $dbTables = DataObjectOnDeleteDecorator::get_db_tables(); foreach ((array)$this->dataObject->many_many() as $relationName => $relationClass) { list($parentClass, $componentClass, $parentField, $componentField, $table) = $this->dataObject->many_many($relationName); if (!in_array($table, DataObjectOnDeleteDecorator_ManyManyCleaner::get_ignored_tables()) && in_array(strtolower($table), $dbTables)) { $oneWayTables = DataObjectOnDeleteDecorator_ManyManyCleaner::get_one_way_tables(); $oneWayTable = array_key_exists($table, $oneWayTables); if ($oneWayTable && $oneWayTables[$table] != $relationName) { JanitorDebug::message("Handling one-way table \"{$table}\" from \"{$relationName}\", aborting"); continue; } $query = "SELECT \"{$parentField}\" FROM \"{$table}\" WHERE 1=1"; $relations = DB::query($query)->column($parentField); foreach ((array)$relations as $ID) { $baseDataObject = DataObject::get_by_id($this->baseClassName, $ID); if ($baseDataObject) continue; $query = "DELETE FROM \"{$table}\" WHERE \"{$parentField}\" = {$ID}"; JanitorDebug::message("Running query: {$query}", 'p', 'color:#ff0000'); DB::query($query); } } } }
/** * @param array $tables * @see self::$one_way_tables */ public static function set_one_way_tables(array $tables) { self::$one_way_tables = $tables; }
// Deleted members do not need passwords. Object::add_static_var('MemberPassword', 'has_one_on_delete', array( 'Member' => 'delete' )); // Complete the SiteTree <=> Group many_many relationship. Object::add_static_var('Group', 'belongs_many_many', array( '__Janitor_ViewerSiteTrees' => 'SiteTree', '__Janitor_EditorSiteTrees' => 'SiteTree' )); // These intermediate tables must only be cleaned if the // "correct" side of the relation is being deleted to prevent // the cleaning from breaking SilverStripe functionality. DataObjectOnDeleteDecorator_ManyManyCleaner::set_one_way_tables(array_merge( array( // LinkTracking can only be cleaned when the deletion takes // place at the many_many side of relation. The relation // must be allowed to break in certain Versioned situations. 'SiteTree_LinkTracking' => 'LinkTracking', // Can only be cleaned when the SiteTree side of the relation // is deleted, since the relation must be allowed to break. 'SiteTree_ImageTracking' => 'ImageTracking' ), DataObjectOnDeleteDecorator_ManyManyCleaner::get_one_way_tables() )); if (class_exists('UserDefinedForm')) require_once 'modules/userforms/_config.php'; if (class_exists('BlogEntry')) require_once 'modules/blog/_config.php'; if (class_exists('Forum')) require_once 'modules/forum/_config.php';