Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.30% covered (success)
97.30%
36 / 37
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
TraitReflection
97.30% covered (success)
97.30%
36 / 37
0.00% covered (danger)
0.00%
0 / 1
19
0.00% covered (danger)
0.00%
0 / 1
 parse
97.30% covered (success)
97.30%
36 / 37
0.00% covered (danger)
0.00%
0 / 1
19
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Code\Reflection;
15
16use Pop\Code\Generator;
17use ReflectionException;
18
19/**
20 * Property reflection code class
21 *
22 * @category   Pop
23 * @package    Pop\Code
24 * @author     Nick Sagona, III <dev@nolainteractive.com>
25 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
26 * @license    http://www.popphp.org/license     New BSD License
27 * @version    5.0.0
28 */
29class TraitReflection extends AbstractReflection
30{
31
32    /**
33     * Method to parse a trait
34     *
35     * @param  mixed   $code
36     * @param  ?string $name
37     * @throws Exception|ReflectionException
38     * @return Generator\TraitGenerator
39     */
40    public static function parse(mixed $code, ?string $name = null): Generator\TraitGenerator
41    {
42        $reflection     = new \ReflectionClass($code);
43        $reflectionName = $reflection->getShortName();
44        $reflectionFile = $reflection->getFileName();
45        $fileContents   = null;
46
47        if (!empty($reflectionFile) && file_exists($reflectionFile)) {
48            $fileContents = file_get_contents($reflectionFile);
49        }
50
51        if (($name === null) && !empty($reflectionName)) {
52            $name = $reflectionName;
53        }
54
55        if (!$reflection->isTrait()) {
56            throw new Exception('Error: The code is not a trait.');
57        }
58
59        $trait = new Generator\TraitGenerator($name);
60
61        // Detect and set namespace
62        if (($reflection->inNamespace()) && ($fileContents !== null)) {
63            $trait->setNamespace(NamespaceReflection::parse($fileContents, $reflection->getNamespaceName()));
64        }
65
66        // Detect and set the class doc block
67        $traitDocBlock = $reflection->getDocComment();
68        if (!empty($traitDocBlock) && (str_contains($traitDocBlock, '/*'))) {
69            $trait->setDocblock(DocblockReflection::parse($traitDocBlock));
70        }
71
72        // Detect used traits
73        if ($fileContents !== null) {
74            $uses = [];
75            preg_match_all('/[ ]+use(.*);$/m', $fileContents, $uses);
76
77            if (isset($uses[1])) {
78                foreach ($uses[1] as $u) {
79                    $useAry = array_map('trim', explode(',', trim($u)));
80                    foreach ($useAry as $useValue) {
81                        if (strpos($useValue, ' as ') !== false) {
82                            [$use, $as] = explode(' as ', $useValue);
83                        } else {
84                            $use = $useValue;
85                            $as  = null;
86                        }
87                        $trait->addUse($use, $as);
88                    }
89                }
90            }
91        }
92
93        // Detect properties
94        $properties = $reflection->getDefaultProperties();
95        if (count($properties) > 0) {
96            foreach ($properties as $name => $value) {
97                $trait->addProperty(PropertyReflection::parse($reflection->getProperty($name), $name, $value));
98            }
99        }
100
101        // Detect methods
102        $methods = $reflection->getMethods();
103        if (count($methods) > 0) {
104            foreach ($methods as $method) {
105                $trait->addMethod(MethodReflection::parse($method, $method->name));
106            }
107        }
108
109        return $trait;
110    }
111
112}