/**
	 * 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;
	}
Example #3
0
// 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';