Вход Регистрация
Файл: concrete5.7.5.6/concrete/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
Строк: 269
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyComponentDebugFatalErrorHandler;

use 
SymfonyComponentDebugExceptionClassNotFoundException;
use 
SymfonyComponentDebugExceptionFatalErrorException;
use 
SymfonyComponentDebugDebugClassLoader;
use 
ComposerAutoloadClassLoader as ComposerClassLoader;
use 
SymfonyComponentClassLoaderClassLoader as SymfonyClassLoader;
use 
SymfonyComponentClassLoaderUniversalClassLoader as SymfonyUniversalClassLoader;

/**
 * ErrorHandler for classes that do not exist.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
{
    
/**
     * {@inheritdoc}
     */
    
public function handleError(array $errorFatalErrorException $exception)
    {
        
$messageLen strlen($error['message']);
        
$notFoundSuffix '' not found';
        $notFoundSuffixLen = strlen($notFoundSuffix);
        if ($notFoundSuffixLen > $messageLen) {
            return;
        }

        if (0 !== substr_compare($error['
message'], $notFoundSuffix, -$notFoundSuffixLen)) {
            return;
        }

        foreach (array('
class', 'interface', 'trait') as $typeName) {
            $prefix = ucfirst($typeName).' ''
;
            
$prefixLen strlen($prefix);
            if (
!== strpos($error['message'], $prefix)) {
                continue;
            }

            
$fullyQualifiedClassName substr($error['message'], $prefixLen, -$notFoundSuffixLen);
            if (
false !== $namespaceSeparatorIndex strrpos($fullyQualifiedClassName'\')) {
                $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
                $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
                $message = sprintf('
Attempted to load %"%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
                $tail = ' 
for another namespace?';
            } else {
                $className = $fullyQualifiedClassName;
                $message = sprintf('
Attempted to load %"%s" from the global namespace.', $typeName, $className);
                $tail = '
?';
            }

            if ($candidates = $this->getClassCandidates($className)) {
                $tail = array_pop($candidates).'"?';
                if (
$candidates) {
                    
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
                } else {
                    $tail = ' 
for "'.$tail;
                }
            }
            
$message .= "nDid you forget a "use" statement".$tail;

            return new ClassNotFoundException(
$message$exception);
        }
    }

    /**
     * Tries to guess the full namespace for a given class name.
     *
     * By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer
     * autoloader (that should cover all common cases).
     *
     * @param string 
$class A class name (without its namespace)
     *
     * @return array An array of possible fully qualified class names
     */
    private function getClassCandidates(
$class)
    {
        if (!is_array(
$functions = spl_autoload_functions())) {
            return array();
        }

        // find Symfony and Composer autoloaders
        
$classes = array();

        foreach (
$functions as $function) {
            if (!is_array(
$function)) {
                continue;
            }
            // get class loaders wrapped by DebugClassLoader
            if (
$function[0] instanceof DebugClassLoader) {
                
$function = $function[0]->getClassLoader();

                // @deprecated since version 2.5. Returning an object from DebugClassLoader::getClassLoader() is deprecated.
                if (is_object(
$function)) {
                    
$function = array($function);
                }

                if (!is_array(
$function)) {
                    continue;
                }
            }

            if (
$function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) {
                foreach (
$function[0]->getPrefixes() as $prefix => $paths) {
                    foreach (
$paths as $path) {
                        
$classes = array_merge($classes$this->findClassInPath($path$class$prefix));
                    }
                }
            }
            if (
$function[0] instanceof ComposerClassLoader) {
                foreach (
$function[0]->getPrefixesPsr4() as $prefix => $paths) {
                    foreach (
$paths as $path) {
                        
$classes = array_merge($classes$this->findClassInPath($path$class$prefix));
                    }
                }
            }
        }

        return array_unique(
$classes);
    }

    /**
     * @param string 
$path
     * @param string 
$class
     * @param string 
$prefix
     *
     * @return array
     */
    private function findClassInPath(
$path$class$prefix)
    {
        if (!
$path = realpath($path.'/'.strtr($prefix, '\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\_', '//'))) ?: realpath($path)) {
            return array();
        }

        
$classes = array();
        
$filename = $class.'.php';
        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(
$path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
            if (
$filename == $file->getFileName() && $class = $this->convertFileToClass($path$file->getPathName(), $prefix)) {
                
$classes[] = $class;
            }
        }

        return 
$classes;
    }

    /**
     * @param string 
$path
     * @param string 
$file
     * @param string 
$prefix
     *
     * @return string|null
     */
    private function convertFileToClass(
$path$file$prefix)
    {
        
$candidates = array(
            // namespaced class
            
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\'), $file),
            // namespaced class (with target dir)
            
$prefix.$namespacedClass,
            // namespaced class (with target dir and separator)
            
$prefix.'\'.$namespacedClass,
            // PEAR class
            str_replace('\', '_', 
$namespacedClass),
            // PEAR class (with target dir)
            str_replace('\', '_', 
$prefix.$namespacedClass),
            // PEAR class (with target dir and separator)
            str_replace('\', '_', 
$prefix.'\'.$namespacedClass),
        );

        if (
$prefix) {
            
$candidates = array_filter($candidates, function ($candidate) use ($prefix) {return 0 === strpos($candidate$prefix);});
        }

        // We cannot use the autoloader here as most of them use require; but if the class
        // is not found, the new autoloader call will require the file again leading to a
        // "
cannot redeclare class" error.
        foreach (
$candidates as $candidate) {
            if (
$this->classExists($candidate)) {
                return 
$candidate;
            }
        }

        require_once 
$file;

        foreach (
$candidates as $candidate) {
            if (
$this->classExists($candidate)) {
                return 
$candidate;
            }
        }
    }

    /**
     * @param string 
$class
     *
     * @return bool
     */
    private function classExists(
$class)
    {
        return class_exists(
$class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
    }
}
Онлайн: 1
Реклама