blastcloud/chassis

View on GitHub
src/Filters/Filters.php

Summary

Maintainability
A
45 mins
Test Coverage
A
100%
<?php

namespace BlastCloud\Chassis\Filters;

use BlastCloud\Chassis\Interfaces\With;

trait Filters
{
    protected $filters = [];
    protected static $namespaces = [__NAMESPACE__];

    /**
     * Add a namespace to look through when dynamically looking for filters.
     *
     * @param string $namespace
     */
    public static function addNamespace(string $namespace)
    {
        if (!in_array($namespace, self::$namespaces)) {
            array_unshift(self::$namespaces, $namespace);
        }
    }

    /**
     * Return the array of namespaces to search through for With* filters.
     *
     * @return array
     */
    public static function namespaces()
    {
        return self::$namespaces;
    }

    /**
     * Determine if the method called is a filter, a.k.a. starts with "with".
     *
     * @param $name
     * @return bool|With
     */
    protected function isFilter($name)
    {
        $parts = preg_split('/(?=[A-Z])/',$name);
        if ($parts[0] == 'with') {
            return $this->findFilter([$parts[1], rtrim($parts[1], 's')]);
        }

        return false;
    }

    /**
     * Iterate through all namespaces to find a matching class.
     *
     * @param array $names
     * @return bool
     */
    protected function findFilter(array $names) {
        foreach ($names as $name) {
            if (isset($this->filters[$name])) {
                return $this->filters[$name];
            }

            foreach (self::$namespaces as $namespace) {
                $class = rtrim($namespace, '\\'). "\\With" . $name;

                if (class_exists($class)) {
                    $this->filters[$name] = $filter = new $class;
                    return $filter;
                }
            }
        }

        return false;
    }
}