src/Menu/MenuModulesInterpreter.php
protected function mergeNormalizedMenuPresences($oldPresences, $newPresences)
    {
        if (false === $oldPresences) {
            // @codeCoverageIgnoreStart
            return $newPresences;
            // @codeCoverageIgnoreEnd
        }

        // Should not matter, since setting the presence to false (instead of an array)
        // will disable the presences entirely
        if (false === $newPresences) {
            // @codeCoverageIgnoreStart
            return $oldPresences;
            // @codeCoverageIgnoreEnd
        }

        // Since menu presences are normalized as non-associative arrays, we must
        // assume that overrides or modifications are intended index for index.
        // The first presence will be enriched or overwritten with the first presence
        // listed, unless it is specifically flagged to be added.

        // Treat additions separately, splitting them off from the overriding/modifying/deleting definitions
        $additions = [];
        $removals  = [];

        /** @var MenuPresenceInterface[] $newPresences */
        $newPresences = array_values($newPresences);

        $splitForAddition = [];

        foreach ($newPresences as $index => $presence) {
            if ($presence->mode() == MenuPresenceMode::ADD) {
                $additions[] = $presence;
                $splitForAddition[] = $index;
            }
        }

        if (count($splitForAddition)) {
            foreach (array_reverse($splitForAddition) as $index) {
                unset($newPresences[$index]);
            }
        }


        /** @var MenuPresenceInterface[] $oldPresences */
        /** @var MenuPresenceInterface[] $newPresences */
        $oldPresences = array_values($oldPresences);
        $newPresences = array_values($newPresences);

        // Perform deletions, replacements or modifications
        foreach ($newPresences as $index => $presence) {

            if ( ! array_key_exists($index, $oldPresences)) {
                continue;
            }

            switch ($presence->mode()) {

                case MenuPresenceMode::DELETE:
                    $removals[] = $index;
                    continue 2;

                case MenuPresenceMode::REPLACE:
                    $this->enrichConfiguredPresenceData($presence);
                    $oldPresences[ $index] = $presence;
                    continue 2;

                // Modify is the default mode
                default:

                    // Merge children for groups that have further nested definitions
                    if (    $oldPresences[ $index ]->type() == MenuPresenceType::GROUP
                        &&  (   $presence->type() == MenuPresenceType::GROUP
                            ||  ! in_array('type', $presence->explicitKeys() ?: [])
                            )
                        &&  count($presence->children())
                    ) {
                        // Set the merged children in the new presence, so they will be merged in
                        // for the upcoming mergeMenuPresenceData call
                        if (count($oldPresences[ $index]->children())) {
                            $presence->setChildren(
                                $this->mergeNormalizedMenuPresences(
                                    $oldPresences[ $index]->children(),
                                    $presence->children()
                                )
                            );
                        }
                    }

                    $oldPresences[ $index ] = $this->mergeMenuPresenceData($oldPresences[ $index ], $presence);
                    continue 2;
            }
        }

        if (count($removals)) {
            foreach (array_reverse($removals) as $index) {
                unset($oldPresences[$index]);
            }
        }

        foreach ($additions as $presence) {
            $this->enrichConfiguredPresenceData($presence);
            $oldPresences[] = $presence;
        }

        return $oldPresences;
    }
protected function mergeNormalizedMenuPresences($oldPresences, $newPresences)
    {
        if (false === $oldPresences) {
            // @codeCoverageIgnoreStart
            return $newPresences;
            // @codeCoverageIgnoreEnd
        }

        // Should not matter, since setting the presence to false (instead of an array)
        // will disable the presences entirely
        if (false === $newPresences) {
            // @codeCoverageIgnoreStart
            return $oldPresences;
            // @codeCoverageIgnoreEnd
        }

        // Since menu presences are normalized as non-associative arrays, we must
        // assume that overrides or modifications are intended index for index.
        // The first presence will be enriched or overwritten with the first presence
        // listed, unless it is specifically flagged to be added.

        // Treat additions separately, splitting them off from the overriding/modifying/deleting definitions
        $additions = [];
        $removals  = [];

        /** @var MenuPresenceInterface[] $newPresences */
        $newPresences = array_values($newPresences);

        $splitForAddition = [];

        foreach ($newPresences as $index => $presence) {
            if ($presence->mode() == MenuPresenceMode::ADD) {
                $additions[] = $presence;
                $splitForAddition[] = $index;
            }
        }

        if (count($splitForAddition)) {
            foreach (array_reverse($splitForAddition) as $index) {
                unset($newPresences[$index]);
            }
        }


        /** @var MenuPresenceInterface[] $oldPresences */
        /** @var MenuPresenceInterface[] $newPresences */
        $oldPresences = array_values($oldPresences);
        $newPresences = array_values($newPresences);

        // Perform deletions, replacements or modifications
        foreach ($newPresences as $index => $presence) {

            if ( ! array_key_exists($index, $oldPresences)) {
                continue;
            }

            switch ($presence->mode()) {

                case MenuPresenceMode::DELETE:
                    $removals[] = $index;
                    continue 2;

                case MenuPresenceMode::REPLACE:
                    $this->enrichConfiguredPresenceData($presence);
                    $oldPresences[ $index] = $presence;
                    continue 2;

                // Modify is the default mode
                default:

                    // Merge children for groups that have further nested definitions
                    if (    $oldPresences[ $index ]->type() == MenuPresenceType::GROUP
                        &&  (   $presence->type() == MenuPresenceType::GROUP
                            ||  ! in_array('type', $presence->explicitKeys() ?: [])
                            )
                        &&  count($presence->children())
                    ) {
                        // Set the merged children in the new presence, so they will be merged in
                        // for the upcoming mergeMenuPresenceData call
                        if (count($oldPresences[ $index]->children())) {
                            $presence->setChildren(
                                $this->mergeNormalizedMenuPresences(
                                    $oldPresences[ $index]->children(),
                                    $presence->children()
                                )
                            );
                        }
                    }

                    $oldPresences[ $index ] = $this->mergeMenuPresenceData($oldPresences[ $index ], $presence);
                    continue 2;
            }
        }

        if (count($removals)) {
            foreach (array_reverse($removals) as $index) {
                unset($oldPresences[$index]);
            }
        }

        foreach ($additions as $presence) {
            $this->enrichConfiguredPresenceData($presence);
            $oldPresences[] = $presence;
        }

        return $oldPresences;
    }
protected function mergeNormalizedMenuPresences ( $ oldPresences , $ newPresences ) { if ( false === $ oldPresences ) { // @codeCoverageIgnoreStart return $ newPresences ; // @codeCoverageIgnoreEnd } // Should not matter, since setting the presence to false (instead of an array) // will disable the presences entirely if ( false === $ newPresences ) { // @codeCoverageIgnoreStart return $ oldPresences ; // @codeCoverageIgnoreEnd } // Since menu presences are normalized as non-associative arrays, we must // assume that overrides or modifications are intended index for index. // The first presence will be enriched or overwritten with the first presence // listed, unless it is specifically flagged to be added. // Treat additions separately, splitting them off from the overriding/modifying/deleting definitions $ additions = [ ] ; $ removals = [ ] ; /** @var MenuPresenceInterface[] $newPresences */ $ newPresences = array_values ( $ newPresences ) ; $ splitForAddition = [ ] ; foreach ( $ newPresences as $ index => $ presence ) { if ( $ presence -> mode ( ) == MenuPresenceMode :: ADD ) { $ additions [ ] = $ presence ; $ splitForAddition [ ] = $ index ; } } if ( count ( $ splitForAddition ) ) { foreach ( array_reverse ( $ splitForAddition ) as $ index ) { unset ( $ newPresences [ $ index ] ) ; } } /** @var MenuPresenceInterface[] $oldPresences */ /** @var MenuPresenceInterface[] $newPresences */ $ oldPresences = array_values ( $ oldPresences ) ; $ newPresences = array_values ( $ newPresences ) ; // Perform deletions, replacements or modifications foreach ( $ newPresences as $ index => $ presence ) { if ( ! array_key_exists ( $ index , $ oldPresences ) ) { continue ; } switch ( $ presence -> mode ( ) ) { case MenuPresenceMode :: DELETE : $ removals [ ] = $ index ; continue 2 ; case MenuPresenceMode :: REPLACE : $ this -> enrichConfiguredPresenceData ( $ presence ) ; $ oldPresences [ $ index ] = $ presence ; continue 2 ; // Modify is the default mode default : // Merge children for groups that have further nested definitions if ( $ oldPresences [ $ index ] -> type ( ) == MenuPresenceType :: GROUP && ( $ presence -> type ( ) == MenuPresenceType :: GROUP || ! in_array ( 'type' , $ presence -> explicitKeys ( ) ? : [ ] ) ) && count ( $ presence -> children ( ) ) ) { // Set the merged children in the new presence, so they will be merged in // for the upcoming mergeMenuPresenceData call if ( count ( $ oldPresences [ $ index ] -> children ( ) ) ) { $ presence -> setChildren ( $ this -> mergeNormalizedMenuPresences ( $ oldPresences [ $ index ] -> children ( ) , $ presence -> children ( ) ) ) ; } } $ oldPresences [ $ index ] = $ this -> mergeMenuPresenceData ( $ oldPresences [ $ index ] , $ presence ) ; continue 2 ; } } if ( count ( $ removals ) ) { foreach ( array_reverse ( $ removals ) as $ index ) { unset ( $ oldPresences [ $ index ] ) ; } } foreach ( $ additions as $ presence ) { $ this -> enrichConfiguredPresenceData ( $ presence ) ; $ oldPresences [ ] = $ presence ; } return $ oldPresences ; }
Merges two normalized menu presences into one.

@param false|MenuPresenceInterface[] $oldPresences
@param false|MenuPresenceInterface[] $newPresences
@return MenuPresenceInterface[]
Merges two normalized menu presences into one .