Completed
Push — master ( 5ac3d3...00813e )
by Askupa
02:22
created

AbstractComponent::remove_html_class()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
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
Coding Style introduced by
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
    public $html_classes = array();
30
    
31
    /**
32
     * Constructor
33
     * 
34
     * @param array $model
35
     */
36
    public function __construct( array $model = array() ) 
37
    {
38
        parent::__construct($model);
39
        
40
        $this->add_html_class(sprintf(
41
            'amarkal-ui-component amarkal-ui-component-%s',
42
            $this->component_type
0 ignored issues
show
Documentation introduced by
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...
43
        ));
44
        
45
        $this->on_created();
46
    }
47
    
48
    /**
49
     * The default model to use when none is provided to the constructor.
50
     * This method should be overriden by child class to define the default
51
     * model.
52
     * 
53
     * @return array
54
     */
55
    public function default_model()
56
    {
57
        return array();
58
    }
59
    
60
    /**
61
     * The list of required model arguments.
62
     * This method should be overriden by child class to specify required model
63
     * arguments.
64
     * 
65
     * @return array
66
     */
67
    public function required_arguments()
68
    {
69
        return array();
70
    }
71
    
72
    /**
73
     * Set the model data for this component.
74
     * 
75
     * @return array
76
     */
77
    public function set_model( $model )
78
    {
79
        // Check that the required arguments are provided.
80
        foreach( $this->required_arguments() as $key )
81
        {
82
            if ( !isset($model[$key]) )
83
            {
84
                throw new \RuntimeException('The required argument "'.$key.'" was not provided for '.get_called_class());
85
            }
86
        }
87
        
88
        // Assign the name of the component as the id if no id was specified
89
        if( !isset($model['id']) )
90
        {
91
            $model['id'] = $model['name'];
92
        }
93
        
94
        $this->model = array_merge( $this->default_model(), $model );
95
    }
96
    
97
    /**
98
     * Get the name for this component by parsing the name template.
99
     * 
100
     * @return string
101
     */
102
    public function get_name()
103
    {
104
        return \str_replace('{{name}}', $this->name, $this->name_template);
0 ignored issues
show
Documentation introduced by
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...
105
    }
106
    
107
    /**
108
     * Add an HTML class to the list of HTML classes to be printed when the
109
     * component is rendered. 
110
     * 
111
     * @param string $class
112
     */
113
    public function add_html_class( $class )
114
    {
115
        if( !in_array($class, $this->html_classes) )
116
        {
117
            $this->html_classes[] = $class;
118
        }
119
    }
120
    
121
    /**
122
     * Remove an HTML class to the list of HTML classes to be printed when the
123
     * component is rendered. 
124
     * 
125
     * @param string $class
126
     */
127
    public function remove_html_class( $class )
128
    {
129
        $i = 0;
130
        foreach( $this->html_classes as $c )
131
        {
132
            if( $c === $class )
133
            {
134
                array_splice($this->html_classes,$i,1);
135
                break;
136
            }
137
            $i++;
138
        }
139
    }
140
    
141
    /**
142
     * Set the validity of this component if it supports validation.
143
     * 
144
     * @param type $validity
145
     */
146
    Public function set_validity( $validity )
147
    {
148
        $this->validity = $validity;
0 ignored issues
show
Documentation introduced by
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...
149
        if($validity === $this::INVALID)
150
        {
151
            $this->add_html_class('amarkal-ui-component-error');
152
        }
153
    }
154
    
155
    /**
156
     * Generate common UI component wrapper attributes
157
     */
158
    public function component_attributes()
159
    {
160
        return sprintf(
161
            'class="%s" amarkal-component-name="%s"',
162
            implode(' ', $this->html_classes),
163
            $this->name
0 ignored issues
show
Documentation introduced by
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...
164
        );
165
    }
166
    
167
    /**
168
     * Enqueue component's script and render it.
169
     * 
170
     * {@inheritdoc}
171
     */
172
    public function render( $echo = false )
173
    {
174
        $this->enqueue_scripts();
175
        return parent::render($echo);
176
    }
177
    
178
    /**
179
     * Enqueue styles/scripts required for this element.
180
     */
181
    public function enqueue_scripts()
182
    {
183
        \wp_enqueue_script('amarkal-ui');
184
        \wp_enqueue_style('amarkal-ui');
185
    }
186
    
187
    /**
188
     * A hook that is called once the component has been created.
189
     */
190
    protected function on_created() {}
191
}