master

laravel/framework

Last updated at: 29/12/2023 09:24

NamespacedItemResolver.php

TLDR

This file implements the NamespacedItemResolver class, which is responsible for parsing and caching configuration keys. It provides methods for parsing a key into namespace, group, and item, setting the parsed value of a key, and flushing the cache of parsed keys.

Methods

parseKey

This method takes a key as input and parses it into namespace, group, and item. It checks if the key has already been parsed and returns the cached version if so. If the key does not contain a double colon, it parses it as a regular configuration item. Otherwise, it parses it as a namespaced configuration item.

parseBasicSegments

This method takes an array of segments as input and parses them into a group and an item. If there is only one segment, it returns the group as null. If there are multiple segments, it returns the item as the concatenation of the remaining segments.

parseNamespacedSegments

This method takes a key as input and parses it into a namespace and an item. It first explodes the key at the double colon to get the namespace and the item. Then it further parses the item into a group and an item using the parseBasicSegments method, and merges the namespace with the resulting array.

setParsedKey

This method allows setting the parsed value of a key. It takes a key and a parsed array as input and assigns the parsed array to the key in the $parsed property.

flushParsedKeys

This method flushes the cache of parsed keys by resetting the $parsed property to an empty array.

Classes

No classes in this file

<?php

namespace Illuminate\Support;

class NamespacedItemResolver
{
    /**
     * A cache of the parsed items.
     *
     * @var array
     */
    protected $parsed = [];

    /**
     * Parse a key into namespace, group, and item.
     *
     * @param  string  $key
     * @return array
     */
    public function parseKey($key)
    {
        // If we've already parsed the given key, we'll return the cached version we
        // already have, as this will save us some processing. We cache off every
        // key we parse so we can quickly return it on all subsequent requests.
        if (isset($this->parsed[$key])) {
            return $this->parsed[$key];
        }

        // If the key does not contain a double colon, it means the key is not in a
        // namespace, and is just a regular configuration item. Namespaces are a
        // tool for organizing configuration items for things such as modules.
        if (! str_contains($key, '::')) {
            $segments = explode('.', $key);

            $parsed = $this->parseBasicSegments($segments);
        } else {
            $parsed = $this->parseNamespacedSegments($key);
        }

        // Once we have the parsed array of this key's elements, such as its groups
        // and namespace, we will cache each array inside a simple list that has
        // the key and the parsed array for quick look-ups for later requests.
        return $this->parsed[$key] = $parsed;
    }

    /**
     * Parse an array of basic segments.
     *
     * @param  array  $segments
     * @return array
     */
    protected function parseBasicSegments(array $segments)
    {
        // The first segment in a basic array will always be the group, so we can go
        // ahead and grab that segment. If there is only one total segment we are
        // just pulling an entire group out of the array and not a single item.
        $group = $segments[0];

        // If there is more than one segment in this group, it means we are pulling
        // a specific item out of a group and will need to return this item name
        // as well as the group so we know which item to pull from the arrays.
        $item = count($segments) === 1
                    ? null
                    : implode('.', array_slice($segments, 1));

        return [null, $group, $item];
    }

    /**
     * Parse an array of namespaced segments.
     *
     * @param  string  $key
     * @return array
     */
    protected function parseNamespacedSegments($key)
    {
        [$namespace, $item] = explode('::', $key);

        // First we'll just explode the first segment to get the namespace and group
        // since the item should be in the remaining segments. Once we have these
        // two pieces of data we can proceed with parsing out the item's value.
        $itemSegments = explode('.', $item);

        $groupAndItem = array_slice(
            $this->parseBasicSegments($itemSegments), 1
        );

        return array_merge([$namespace], $groupAndItem);
    }

    /**
     * Set the parsed value of a key.
     *
     * @param  string  $key
     * @param  array  $parsed
     * @return void
     */
    public function setParsedKey($key, $parsed)
    {
        $this->parsed[$key] = $parsed;
    }

    /**
     * Flush the cache of parsed keys.
     *
     * @return void
     */
    public function flushParsedKeys()
    {
        $this->parsed = [];
    }
}