thecodingmachine /
graphql-controllers
| 1 | <?php |
||||
| 2 | |||||
| 3 | |||||
| 4 | namespace TheCodingMachine\GraphQL\Controllers\Reflection; |
||||
| 5 | |||||
| 6 | use function filemtime; |
||||
| 7 | use phpDocumentor\Reflection\DocBlock; |
||||
| 8 | use phpDocumentor\Reflection\DocBlockFactory; |
||||
| 9 | use phpDocumentor\Reflection\Types\Context; |
||||
| 10 | use phpDocumentor\Reflection\Types\ContextFactory; |
||||
| 11 | use Psr\SimpleCache\CacheInterface; |
||||
| 12 | use ReflectionMethod; |
||||
| 13 | |||||
| 14 | /** |
||||
| 15 | * Creates DocBlocks and puts these in cache. |
||||
| 16 | */ |
||||
| 17 | class CachedDocBlockFactory |
||||
| 18 | { |
||||
| 19 | /** |
||||
| 20 | * @var CacheInterface |
||||
| 21 | */ |
||||
| 22 | private $cache; |
||||
| 23 | /** |
||||
| 24 | * @var DocBlockFactory|null |
||||
| 25 | */ |
||||
| 26 | private $docBlockFactory; |
||||
| 27 | /** |
||||
| 28 | * @var array<string, DocBlock> |
||||
| 29 | */ |
||||
| 30 | private $docBlockArrayCache = []; |
||||
| 31 | /** |
||||
| 32 | * @var array<string, Context> |
||||
| 33 | */ |
||||
| 34 | private $contextArrayCache = []; |
||||
| 35 | /** |
||||
| 36 | * @var ContextFactory |
||||
| 37 | */ |
||||
| 38 | private $contextFactory; |
||||
| 39 | |||||
| 40 | /** |
||||
| 41 | * @param CacheInterface $cache The cache we fetch data from. Note this is a SAFE cache. It does not need to be purged. |
||||
| 42 | * @param DocBlockFactory|null $docBlockFactory |
||||
| 43 | */ |
||||
| 44 | public function __construct(CacheInterface $cache, ?DocBlockFactory $docBlockFactory = null) |
||||
| 45 | { |
||||
| 46 | $this->cache = $cache; |
||||
| 47 | $this->docBlockFactory = $docBlockFactory ?: DocBlockFactory::createInstance(); |
||||
| 48 | $this->contextFactory = new ContextFactory(); |
||||
| 49 | } |
||||
| 50 | |||||
| 51 | /** |
||||
| 52 | * Fetches a DocBlock object from a ReflectionMethod |
||||
| 53 | * |
||||
| 54 | * @param ReflectionMethod $refMethod |
||||
| 55 | * @return DocBlock |
||||
| 56 | */ |
||||
| 57 | public function getDocBlock(ReflectionMethod $refMethod): DocBlock |
||||
| 58 | { |
||||
| 59 | $key = 'docblock_'.md5($refMethod->getDeclaringClass()->getName().'::'.$refMethod->getName()); |
||||
| 60 | if (isset($this->docBlockArrayCache[$key])) { |
||||
| 61 | return $this->docBlockArrayCache[$key]; |
||||
| 62 | } |
||||
| 63 | |||||
| 64 | if ($cacheItem = $this->cache->get($key)) { |
||||
| 65 | [ |
||||
| 66 | 'time' => $time, |
||||
| 67 | 'docblock' => $docBlock |
||||
| 68 | ] = $cacheItem; |
||||
| 69 | |||||
| 70 | if (filemtime($refMethod->getFileName()) === $time) { |
||||
| 71 | $this->docBlockArrayCache[$key] = $docBlock; |
||||
| 72 | return $docBlock; |
||||
| 73 | } |
||||
| 74 | } |
||||
| 75 | |||||
| 76 | $docBlock = $this->doGetDocBlock($refMethod); |
||||
| 77 | |||||
| 78 | $this->cache->set($key, [ |
||||
| 79 | 'time' => filemtime($refMethod->getFileName()), |
||||
| 80 | 'docblock' => $docBlock |
||||
| 81 | ]); |
||||
| 82 | $this->docBlockArrayCache[$key] = $docBlock; |
||||
| 83 | |||||
| 84 | return $docBlock; |
||||
| 85 | } |
||||
| 86 | |||||
| 87 | private function doGetDocBlock(ReflectionMethod $refMethod): DocBlock |
||||
| 88 | { |
||||
| 89 | $docComment = $refMethod->getDocComment() ?: '/** */'; |
||||
| 90 | |||||
| 91 | $refClass = $refMethod->getDeclaringClass(); |
||||
| 92 | $refClassName = $refClass->getName(); |
||||
| 93 | |||||
| 94 | if (!isset($this->contextArrayCache[$refClassName])) { |
||||
| 95 | $this->contextArrayCache[$refClassName] = $this->contextFactory->createFromReflector($refMethod); |
||||
| 96 | } |
||||
| 97 | |||||
| 98 | return $this->docBlockFactory->create($docComment, $this->contextArrayCache[$refClassName]); |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
The method
create() does not exist on null.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||||
| 99 | } |
||||
| 100 | } |
||||
| 101 |