src/ORM/DataObjectSchema.php
public function manyManyComponent($class, $component)
    {
        $classes = ClassInfo::ancestry($class);
        foreach ($classes as $parentClass) {
            // Check if the component is defined in many_many on this class
            $otherManyMany = Config::inst()->get($parentClass, 'many_many', Config::UNINHERITED);
            if (isset($otherManyMany[$component])) {
                return $this->parseManyManyComponent($parentClass, $component, $otherManyMany[$component]);
            }

            // Check if the component is defined in belongs_many_many on this class
            $belongsManyMany = Config::inst()->get($parentClass, 'belongs_many_many', Config::UNINHERITED);
            if (!isset($belongsManyMany[$component])) {
                continue;
            }

            // Extract class and relation name from dot-notation
            $belongs = $this->parseBelongsManyManyComponent(
                $parentClass,
                $component,
                $belongsManyMany[$component]
            );

            // Build inverse relationship from other many_many, and swap parent/child
            $otherManyMany = $this->manyManyComponent($belongs['childClass'], $belongs['relationName']);
            return [
                'relationClass' => $otherManyMany['relationClass'],
                'parentClass' => $otherManyMany['childClass'],
                'childClass' => $otherManyMany['parentClass'],
                'parentField' => $otherManyMany['childField'],
                'childField' => $otherManyMany['parentField'],
                'join' => $otherManyMany['join'],
            ];
        }
        return null;
    }
public function manyManyComponent($class, $component)
    {
        $classes = ClassInfo::ancestry($class);
        foreach ($classes as $parentClass) {
            // Check if the component is defined in many_many on this class
            $otherManyMany = Config::inst()->get($parentClass, 'many_many', Config::UNINHERITED);
            if (isset($otherManyMany[$component])) {
                return $this->parseManyManyComponent($parentClass, $component, $otherManyMany[$component]);
            }

            // Check if the component is defined in belongs_many_many on this class
            $belongsManyMany = Config::inst()->get($parentClass, 'belongs_many_many', Config::UNINHERITED);
            if (!isset($belongsManyMany[$component])) {
                continue;
            }

            // Extract class and relation name from dot-notation
            $belongs = $this->parseBelongsManyManyComponent(
                $parentClass,
                $component,
                $belongsManyMany[$component]
            );

            // Build inverse relationship from other many_many, and swap parent/child
            $otherManyMany = $this->manyManyComponent($belongs['childClass'], $belongs['relationName']);
            return [
                'relationClass' => $otherManyMany['relationClass'],
                'parentClass' => $otherManyMany['childClass'],
                'childClass' => $otherManyMany['parentClass'],
                'parentField' => $otherManyMany['childField'],
                'childField' => $otherManyMany['parentField'],
                'join' => $otherManyMany['join'],
            ];
        }
        return null;
    }
public function manyManyComponent ( $ class , $ component ) { $ classes = ClassInfo :: ancestry ( $ class ) ; foreach ( $ classes as $ parentClass ) { // Check if the component is defined in many_many on this class $ otherManyMany = Config :: inst ( ) -> get ( $ parentClass , 'many_many' , Config :: UNINHERITED ) ; if ( isset ( $ otherManyMany [ $ component ] ) ) { return $ this -> parseManyManyComponent ( $ parentClass , $ component , $ otherManyMany [ $ component ] ) ; } // Check if the component is defined in belongs_many_many on this class $ belongsManyMany = Config :: inst ( ) -> get ( $ parentClass , 'belongs_many_many' , Config :: UNINHERITED ) ; if ( ! isset ( $ belongsManyMany [ $ component ] ) ) { continue ; } // Extract class and relation name from dot-notation $ belongs = $ this -> parseBelongsManyManyComponent ( $ parentClass , $ component , $ belongsManyMany [ $ component ] ) ; // Build inverse relationship from other many_many, and swap parent/child $ otherManyMany = $ this -> manyManyComponent ( $ belongs [ 'childClass' ] , $ belongs [ 'relationName' ] ) ; return [ 'relationClass' => $ otherManyMany [ 'relationClass' ] , 'parentClass' => $ otherManyMany [ 'childClass' ] , 'childClass' => $ otherManyMany [ 'parentClass' ] , 'parentField' => $ otherManyMany [ 'childField' ] , 'childField' => $ otherManyMany [ 'parentField' ] , 'join' => $ otherManyMany [ 'join' ] , ] ; } return null ; }
Return information about a specific many_many component. Returns a numeric array.
The first item in the array will be the class name of the relation.

Standard many_many return type is:

array(
<manyManyClass>,        Name of class for relation. E.g. "Categories"
<classname>,            The class that relation is defined in e.g. "Product"
<candidateName>,        The target class of the relation e.g. "Category"
<parentField>,          The field name pointing to <classname>'s table e.g. "ProductID".
<childField>,           The field name pointing to <candidatename>'s table e.g. "CategoryID".
<joinTableOrRelation>   The join table between the two classes e.g. "Product_Categories".
If the class name is 'ManyManyThroughList' then this is the name of the
has_many relation.
)

@param string $class Name of class to get component for
@param string $component The component name

@return array|null
Return information about a specific many_many component . Returns a numeric array . The first item in the array will be the class name of the relation .