initialize(); return; } /** * Singleton. * To use the `hoa://` protocol shared by everyone. */ public static function getInstance(): Protocol { if (null === static::$_instance) { static::$_instance = new static(); } return static::$_instance; } /** * Initialize the protocol. */ protected function initialize() { $root = dirname(__DIR__, 3); $argv0 = realpath($_SERVER['argv'][0]); $cwd = 'cli' === PHP_SAPI ? false !== $argv0 ? dirname($argv0) : '' : getcwd(); $this[] = new Node( 'Application', $cwd . DS, [ new Node('Public', 'Public' . DS) ] ); $this[] = new Node( 'Data', dirname($cwd) . DS, [ new Node( 'Etc', 'Etc' . DS, [ new Node('Configuration', 'Configuration' . DS), new Node('Locale', 'Locale' . DS) ] ), new Node('Lost+found', 'Lost+found' . DS), new Node('Temporary', 'Temporary' . DS), new Node( 'Variable', 'Variable' . DS, [ new Node('Cache', 'Cache' . DS), new Node('Database', 'Database' . DS), new Node('Log', 'Log' . DS), new Node('Private', 'Private' . DS), new Node('Run', 'Run' . DS), new Node('Test', 'Test' . DS) ] ) ] ); $this[] = new Node\Library( 'Library', $root . DS . 'Hoathis' . DS . RS . $root . DS . 'Hoa' . DS ); } /** * Resolve (unfold) an `hoa://` path to its real resource. * * If `$exists` is set to `true`, try to find the first that exists, * otherwise returns the first solution. If `$unfold` is set to `true`, * it returns all the paths. */ public function resolve(string $path, bool $exists = true, bool $unfold = false) { if (substr($path, 0, 6) !== 'hoa://') { if (true === is_dir($path)) { $path = rtrim($path, '/\\'); if (0 === strlen($path)) { $path = '/'; } } return $path; } if (isset(self::$_cache[$path])) { $handle = self::$_cache[$path]; } else { $out = $this->_resolve($path, $handle); // Not a path but a resource. if (!is_array($handle)) { return $out; } $handle = array_values(array_unique($handle, SORT_REGULAR)); foreach ($handle as &$entry) { if (true === is_dir($entry)) { $entry = rtrim($entry, '/\\'); if (0 === strlen($entry)) { $entry = '/'; } } } self::$_cache[$path] = $handle; } if (true === $unfold) { if (true !== $exists) { return $handle; } $out = []; foreach ($handle as $solution) { if (file_exists($solution)) { $out[] = $solution; } } return $out; } if (true !== $exists) { return $handle[0]; } foreach ($handle as $solution) { if (file_exists($solution)) { return $solution; } } return static::NO_RESOLUTION; } /** * Clear the cache. */ public static function clearCache() { self::$_cache = []; } } /** * Flex entity. */ Consistency::flexEntity(Protocol::class);