Completed
Push — master ( 63292c...e36017 )
by Askupa
01:33
created

AbstractComponent.php (5 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
        $this->on_created();
51
    }
52
    
53
    /**
54
     * The default model to use when none is provided to the constructor.
55
     * This method should be overriden by child class to define the default
56
     * model.
57
     * 
58
     * @return array
59
     */
60
    public function default_model()
61
    {
62
        return array();
63
    }
64
    
65
    /**
66
     * The list of required model arguments.
67
     * This method should be overriden by child class to specify required model
68
     * arguments.
69
     * 
70
     * @return array
71
     */
72
    public function required_arguments()
73
    {
74
        return array();
75
    }
76
    
77
    /**
78
     * Set the model data for this component.
79
     * 
80
     * @return array
81
     */
82
    public function set_model( $model )
83
    {
84
        // Check that the required arguments are provided.
85
        foreach( $this->required_arguments() as $key )
86
        {
87
            if ( !isset($model[$key]) )
88
            {
89
                throw new \RuntimeException('The required argument "'.$key.'" was not provided for '.get_called_class());
90
            }
91
        }
92
        
93
        // Assign the name of the component as the id if no id was specified
94
        if( !isset($model['id']) && isset($model['name']) )
95
        {
96
            $model['id'] = $model['name'];
97
        }
98
        
99
        $this->model = array_merge( $this->default_model(), $model );
100
    }
101
    
102
    /**
103
     * Get the name for this component by parsing the name template.
104
     * 
105
     * @return string
106
     */
107
    public function get_name()
108
    {
109
        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...
110
    }
111
    
112
    /**
113
     * Add an HTML class to the list of HTML classes to be printed when the
114
     * component is rendered. 
115
     * 
116
     * @param string $class
117
     */
118
    public function add_html_class( $class )
119
    {
120
        if( !in_array($class, $this->html_classes) )
121
        {
122
            $this->html_classes[] = $class;
123
        }
124
    }
125
    
126
    /**
127
     * Remove an HTML class to the list of HTML classes to be printed when the
128
     * component is rendered. 
129
     * 
130
     * @param string $class
131
     */
132
    public function remove_html_class( $class )
133
    {
134
        $i = 0;
135
        foreach( $this->html_classes as $c )
136
        {
137
            if( $c === $class )
138
            {
139
                array_splice($this->html_classes,$i,1);
140
                break;
141
            }
142
            $i++;
143
        }
144
    }
145
    
146
    /**
147
     * Set the validity of this component if it supports validation.
148
     * 
149
     * @param type $validity
150
     */
151
    Public function set_validity( $validity )
152
    {
153
        $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...
154
        if($validity === $this::INVALID)
155
        {
156
            $this->add_html_class('amarkal-ui-component-error');
157
        }
158
    }
159
    
160
    /**
161
     * Generate common UI component wrapper attributes
162
     */
163
    public function component_attributes()
164
    {
165
        return sprintf(
166
            'class="%s" amarkal-component-name="%s"',
167
            implode(' ', $this->html_classes),
168
            $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...
169
        );
170
    }
171
    
172
    /**
173
     * Enqueue component's script and render it.
174
     * 
175
     * {@inheritdoc}
176
     */
177
    public function render( $echo = false )
178
    {
179
        $this->enqueue_scripts();
180
        
181
        ob_start();
182
        include dirname(__FILE__).'/AbstractComponent.phtml';
183
        $html = ob_get_clean();
184
185
        if( !$echo )
186
        {
187
            return $html;
188
        }
189
        echo $html;
190
    }
191
    
192
    /**
193
     * Enqueue styles/scripts required for this element.
194
     */
195
    public function enqueue_scripts()
196
    {
197
        \wp_enqueue_script('amarkal-ui');
198
        \wp_enqueue_style('amarkal-ui');
199
    }
200
    
201
    /**
202
     * A hook that is called once the component has been created.
203
     */
204
    protected function on_created() {}
205
}