Componentable   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 8
c 0
b 0
f 0
lcom 1
cbo 2
dl 0
loc 110
rs 10
ccs 24
cts 24
cp 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A component() 0 4 1
A hasComponent() 0 4 1
A renderComponent() 0 9 1
A getComponentData() 0 17 3
A __call() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arcanedev\LaravelHtml\Traits;
6
7
use BadMethodCallException;
8
use Illuminate\Support\{Arr, HtmlString};
9
10
/**
11
 * Trait     Componentable
12
 *
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
trait Componentable
16
{
17
    /* -----------------------------------------------------------------
18
     |  Properties
19
     | -----------------------------------------------------------------
20
     */
21
22
    /**
23
     * The registered components.
24
     *
25
     * @var array
26
     */
27
    protected static $components = [];
28
29
    /* -----------------------------------------------------------------
30
     |  Main Methods
31
     | -----------------------------------------------------------------
32
     */
33
34
    /**
35
     * Register a custom component.
36
     *
37
     * @param  string  $name
38
     * @param  string  $view
39
     * @param  array   $signature
40
     */
41 12
    public static function component(string $name, string $view, array $signature)
42
    {
43 12
        static::$components[$name] = compact('view', 'signature');
44 12
    }
45
46
    /**
47
     * Check if a component is registered.
48
     *
49
     * @param  string  $name
50
     *
51
     * @return bool
52
     */
53 18
    public static function hasComponent(string $name): bool
54
    {
55 18
        return isset(static::$components[$name]);
56
    }
57
58
    /* -----------------------------------------------------------------
59
     |  Other Methods
60
     | -----------------------------------------------------------------
61
     */
62
63
    /**
64
     * Render a custom component.
65
     *
66
     * @param  string  $name
67
     * @param  array   $arguments
68
     *
69
     * @return \Illuminate\Support\HtmlString
70
     */
71 6
    protected function renderComponent(string $name, array $arguments): HtmlString
72
    {
73 6
        $component = static::$components[$name];
74 6
        $data      = $this->getComponentData($component['signature'], $arguments);
75
76 6
        return new HtmlString(
77 6
            view()->make($component['view'], $data)->render()
0 ignored issues
show
Bug introduced by
The method make does only exist in Illuminate\Contracts\View\Factory, but not in Illuminate\Contracts\View\View.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
78
        );
79
    }
80
81
    /**
82
     * Prepare the component data, while respecting provided defaults.
83
     *
84
     * @param  array  $signature
85
     * @param  array  $arguments
86
     *
87
     * @return array
88
     */
89 6
    protected function getComponentData(array $signature, array $arguments): array
90
    {
91 6
        $data = [];
92 6
        $i    = 0;
93
94 6
        foreach ($signature as $variable => $default) {
95 6
            if (is_numeric($variable)) {
96 6
                $variable = $default;
97 6
                $default  = null;
98
            }
99
100 6
            $data[$variable] = Arr::get($arguments, $i, $default);
101 6
            $i++;
102
        }
103
104 6
        return $data;
105
    }
106
107
    /**
108
     * Dynamically handle calls to the class.
109
     *
110
     * @param  string  $method
111
     * @param  array   $parameters
112
     *
113
     * @return \Illuminate\Support\HtmlString|mixed
114
     *
115
     * @throws \BadMethodCallException
116
     */
117 12
    public function __call($method, $parameters)
118
    {
119 12
        if ( ! static::hasComponent($method))
120 6
            throw new BadMethodCallException("Method {$method} does not exist.");
121
122 6
        return $this->renderComponent($method, $parameters);
123
    }
124
}
125