column('FileID'); // Get all classes that aren't folder $fileClasses = array_diff_key( ClassInfo::subclassesFor(File::class), ClassInfo::subclassesFor(Folder::class) ); // Search on a class-by-class basis $classes = ClassInfo::subclassesFor(SiteTree::class); $schema = DataObject::getSchema(); foreach ($classes as $className) { // Build query based on all direct has_ones on this class $hasOnes = Config::inst()->get($className, 'has_one', Config::UNINHERITED); if (empty($hasOnes)) { continue; } $where = []; $columns = []; foreach ($hasOnes as $relName => $joinClass) { if (in_array($joinClass, $fileClasses)) { $column = $relName . 'ID'; $columns[] = $column; $quotedColumn = $schema->sqlColumnForField($className, $column); $where[] = "{$quotedColumn} > 0"; } } // Get all records with any file ID in the searched columns $recordsArray = DataList::create($className)->whereAny($where)->toArray(); $records = ArrayList::create($recordsArray); foreach ($columns as $column) { $usedFiles = array_unique(array_merge($usedFiles, $records->column($column))); } } // Create filter based on class and id $classFilter = sprintf( "(\"File\".\"ClassName\" IN (%s))", implode(", ", Convert::raw2sql($fileClasses, true)) ); if ($usedFiles) { return "\"File\".\"ID\" NOT IN (" . implode(', ', $usedFiles) . ") AND $classFilter"; } else { return $classFilter; } } }