ScannerTrait.php

<?php

namespace Lia\CompoTrait;

/**
 * Wire methods with prefixes to their relevant APIs.
 *
 * @tag component, internals
 */
trait Scanner {

    /**
     * Get `prefix=>api` mappings from Liaison. Override to provide custom mappings
     *
     * @return array like `['prefix' => 'ns:api.name']` 
     *
     * @warning If a method is 'onSomeThing', and there are two prefixes 'on' and 'onSome', the 'onSomeThing' may match 'on' instead of 'onSome'. You may override `getPrefixes()` & return an array with `'onSome'` before `'on'` to work around this. Fixing this permanently would require additional sorting (more cpu cycles) so I don't intend to change this behavior.
     */
    public function getPrefixes(): array{
        $lia = $this->lia;
        $prefixes = $lia->getApiPrefixes();
        return $prefixes;
    }

    /**
     * Pass prefixed functions to the correct APIs.
     * Override `getPrefixes()` on your component to provide custom `prefix=>api` mappings
     *
     */
    public function setupPrefixes(){
        $prefixes = $this->getPrefixes();
        $methods = get_class_methods($this);

        $found = [];

        foreach ($prefixes as $prefix => $api){
            $len = strlen($prefix);
            foreach ($methods as $methodIndex => $methodName){
                if (substr($methodName, 0, $len)!=$prefix)continue;
                $ord = ord(substr($methodName, $len, 1));

                // ord>96 means its a lowercase letter, so continue
                // if its a lowercase letter continue
                if ($ord==0 || $ord > 96)continue;

                // ord == 95 means its an underscore
                // if is an underscore, remove that from the method name
                // else just remove the prefix
                if ($ord == 95)$cleanName = substr($methodName, $len+1);
                else $cleanName = substr($methodName, $len);

                /**
                 * A method can only match one prefix 
                 */
                unset($methods[$methodIndex]);

//
                // var_dump($api);
                // var_dump($cleanName);
                // var_dump($methodName);
                // exit;
                $this->lia->api($api, $cleanName, [$this, $methodName]);
            }
        }
    }

}