Completed
Push — master ( c8219e...d46307 )
by Askupa
01:31
created

AbstractComponent.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Amarkal\UI;
4
5
/**
6
 * Defines an abstract UI component
7
 */
8
abstract class AbstractComponent
9
extends Template
0 ignored issues
show
The extends keyword must be on the same line as the class name
Loading history...
10
{
11
    /**
12
     * This template is used to generate the name for this component. the token 
13
     * {{name}} will be replaced by the component's name during runtime.
14
     * 
15
     * @var string
16
     */
17
    public $name_template = '{{name}}';
18
    
19
    /**
20
     * This template is used to generate the name for this component when it is
21
     * used as a child component in a composite component. The token 
22
     * {{parent_name}} will be replaced with the name of the parent (composite)
23
     * component.
24
     * 
25
     * @var string
26
     */
27
    public $composite_name_template = '{{parent_name}}[{{name}}]';
28
    
29
    /**
30
     * A list of HTML classes to be added to the wrapper div of this component.
31
     *
32
     * @var array
33
     */
34
    public $html_classes = array();
35
    
36
    /**
37
     * Constructor
38
     * 
39
     * @param array $model
40
     */
41
    public function __construct( array $model = array() ) 
42
    {
43
        parent::__construct($model);
44
        
45
        $this->add_html_class(sprintf(
46
            'amarkal-ui-component amarkal-ui-component-%s',
47
            $this->component_type
0 ignored issues
show
The property component_type does not exist on object<Amarkal\UI\AbstractComponent>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
48
        ));
49
50
        if($this instanceof DisableableComponentInterface && $this->disabled)
0 ignored issues
show
The property disabled does not exist on object<Amarkal\UI\AbstractComponent>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
51
        {
52
            $this->add_html_class('amarkal-ui-disabled');
53
        }
54
        
55
        $this->on_created();
56
    }
57
    
58
    /**
59
     * The default model to use when none is provided to the constructor.
60
     * This method should be overriden by child class to define the default
61
     * model.
62
     * 
63
     * @return array
64
     */
65
    public function default_model()
66
    {
67
        return array();
68
    }
69
    
70
    /**
71
     * The list of required model arguments.
72
     * This method should be overriden by child class to specify required model
73
     * arguments.
74
     * 
75
     * @return array
76
     */
77
    public function required_arguments()
78
    {
79
        return array();
80
    }
81
    
82
    /**
83
     * Set the model data for this component.
84
     * 
85
     * @return array
86
     */
87
    public function set_model( $model )
88
    {
89
        // Check that the required arguments are provided.
90
        foreach( $this->required_arguments() as $key )
91
        {
92
            if ( !isset($model[$key]) )
93
            {
94
                throw new \RuntimeException('The required argument "'.$key.'" was not provided for '.get_called_class());
95
            }
96
        }
97
        
98
        // Assign the name of the component as the id if no id was specified
99
        if( !isset($model['id']) && isset($model['name']) )
100
        {
101
            $model['id'] = $model['name'];
102
        }
103
        
104
        $this->model = array_merge( $this->default_model(), $model );
105
    }
106
    
107
    /**
108
     * Get the name for this component by parsing the name template.
109
     * 
110
     * @return string
111
     */
112
    public function get_name()
113
    {
114
        return \str_replace('{{name}}', $this->name, $this->name_template);
0 ignored issues
show
The property name does not exist on object<Amarkal\UI\AbstractComponent>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
    }
116
    
117
    /**
118
     * Add an HTML class to the list of HTML classes to be printed when the
119
     * component is rendered. 
120
     * 
121
     * @param string $class
122
     */
123
    public function add_html_class( $class )
124
    {
125
        if( !in_array($class, $this->html_classes) )
126
        {
127
            $this->html_classes[] = $class;
128
        }
129
    }
130
    
131
    /**
132
     * Remove an HTML class to the list of HTML classes to be printed when the
133
     * component is rendered. 
134
     * 
135
     * @param string $class
136
     */
137
    public function remove_html_class( $class )
138
    {
139
        $i = 0;
140
        foreach( $this->html_classes as $c )
141
        {
142
            if( $c === $class )
143
            {
144
                array_splice($this->html_classes,$i,1);
145
                break;
146
            }
147
            $i++;
148
        }
149
    }
150
    
151
    /**
152
     * Set the validity of this component if it supports validation.
153
     * 
154
     * @param type $validity
155
     */
156
    Public function set_validity( $validity )
157
    {
158
        $this->validity = $validity;
0 ignored issues
show
The property validity does not exist on object<Amarkal\UI\AbstractComponent>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
159
        if($validity === $this::INVALID)
160
        {
161
            $this->add_html_class('amarkal-ui-component-error');
162
        }
163
    }
164
    
165
    /**
166
     * Generate common UI component wrapper attributes
167
     */
168
    public function component_attributes()
169
    {
170
        return sprintf(
171
            'class="%s" amarkal-component-name="%s"',
172
            implode(' ', $this->html_classes),
173
            $this->name
0 ignored issues
show
The property name does not exist on object<Amarkal\UI\AbstractComponent>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
174
        );
175
    }
176
    
177
    /**
178
     * Enqueue component's script and render it.
179
     * 
180
     * {@inheritdoc}
181
     */
182
    public function render( $echo = false )
183
    {
184
        $this->enqueue_scripts();
185
        
186
        ob_start();
187
        include dirname(__FILE__).'/AbstractComponent.phtml';
188
        $html = ob_get_clean();
189
190
        if( !$echo )
191
        {
192
            return $html;
193
        }
194
        echo $html;
195
    }
196
    
197
    /**
198
     * Enqueue styles/scripts required for this element.
199
     */
200
    public function enqueue_scripts()
201
    {
202
        \wp_enqueue_script('amarkal-ui');
203
        \wp_enqueue_style('amarkal-ui');
204
    }
205
    
206
    /**
207
     * A hook that is called once the component has been created.
208
     */
209
    protected function on_created() {}
210
}