1<?php
2/**
3 * Utility class for handling border properties.
4 * Only works with properties stored in an array as delivered from
5 * class cssimportnew, e.g. from method getPropertiesForElement().
6 *
7 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
8 * @author     LarsDW223
9 */
10
11/**
12 * Class cssborder.
13 *
14 * @package CSS\CSSAttributeSelector
15 */
16class cssborder {
17    static public function getWidthShorthandValues ($value, &$top, &$right, &$bottom, &$left) {
18        $top    = NULL;
19        $right  = NULL;
20        $bottom = NULL;
21        $left   = NULL;
22
23        $values = preg_split ('/\s+/', $value);
24        switch (count($values)) {
25            case 1:
26                $top    = $values [0];
27                $bottom = $values [0];
28                $right  = $values [0];
29                $left   = $values [0];
30                break;
31            case 2:
32                $top    = $values [0];
33                $bottom = $values [0];
34                $right  = $values [1];
35                $left   = $values [1];
36                break;
37            case 3:
38                $top    = $values [0];
39                $right  = $values [1];
40                $left   = $values [1];
41                $bottom = $values [2];
42                break;
43            case 4:
44            default:
45                $top    = $values [0];
46                $right  = $values [1];
47                $bottom = $values [2];
48                $left   = $values [3];
49                break;
50        }
51    }
52
53    static public function getShorthandValues ($value, &$width, &$style, &$color) {
54        $width = NULL;
55        $style = NULL;
56        $color = NULL;
57        if (empty($value)) {
58            return;
59        }
60        if ($value == 'initial' || $value == 'inherit') {
61            $width = $value;
62            $style = $value;
63            $color = $value;
64            return;
65        }
66        $values = preg_split ('/\s+/', $value);
67        $index = 0;
68        $border_width_set = false;
69        $border_style_set = false;
70        $border_color_set = false;
71        while ( $index < 3 ) {
72            if ( $border_width_set === false ) {
73                switch ($values [$index]) {
74                    case 'thin':
75                    case 'medium':
76                    case 'thick':
77                        $width = $values [$index];
78                        $index++;
79                    break;
80                    default:
81                        $unit = substr ($values [$index], -2);
82                        if ( ctype_digit($values [$index]) ||
83                             $unit == 'px' ||
84                             $unit == 'pt' ||
85                             $unit == 'cm' ) {
86                            $width = $values [$index];
87                            $index++;
88                        } else {
89                            // There is no default value? So leave it unset.
90                        }
91                    break;
92                }
93                $border_width_set = true;
94                continue;
95            }
96            if ( $border_style_set === false ) {
97                switch ($values [$index]) {
98                    case 'none':
99                    case 'hidden':
100                    case 'dotted':
101                    case 'dashed':
102                    case 'solid':
103                    case 'double':
104                    case 'groove':
105                    case 'ridge':
106                    case 'inset':
107                    case 'outset':
108                    case 'initial':
109                    case 'inherit':
110                        $style = $values [$index];
111                        $index++;
112                    break;
113                }
114                $border_style_set = true;
115                continue;
116            }
117            if ( $border_color_set === false ) {
118                if (!empty($values [$index])) {
119                    $color = $values [$index];
120                }
121
122                // This is the last value.
123                break;
124            }
125        }
126    }
127
128    /**
129     * The function checks if this atrribute selector matches the
130     * attributes given in $attributes as key - value pairs.
131     *
132     * @param    string $attributes String containing the selector
133     * @return   boolean
134     */
135    static public function normalize (array &$properties) {
136        $border_sides = array ('border-left', 'border-right', 'border-top', 'border-bottom');
137
138        $bl_width = '0px';
139        $br_width = '0px';
140        $bb_width = '0px';
141        $bt_width = '0px';
142        $bl_style = 'none';
143        $br_style = 'none';
144        $bb_style = 'none';
145        $bt_style = 'none';
146        $bl_color = NULL;
147        $br_color = NULL;
148        $bb_color = NULL;
149        $bt_color = NULL;
150
151        if (!empty($properties ['border'])) {
152            $width = NULL;
153            $style = NULL;
154            $color = NULL;
155            self::getShorthandValues ($properties ['border'], $width, $style, $color);
156            if (!empty($width)) {
157                $bl_width = $width;
158                $br_width = $width;
159                $bb_width = $width;
160                $bt_width = $width;
161            }
162            if (!empty($style)) {
163                $bl_style = $style;
164                $br_style = $style;
165                $bb_style = $style;
166                $bt_style = $style;
167            }
168            if (!empty($color)) {
169                $bl_color = $color;
170                $br_color = $color;
171                $bb_color = $color;
172                $bt_color = $color;
173            }
174            unset ($properties ['border']);
175        }
176
177        if (!empty($properties ['border-left'])) {
178            $width = NULL;
179            $style = NULL;
180            $color = NULL;
181            self::getShorthandValues ($properties ['border-left'], $width, $style, $color);
182            if (!empty($width)) {
183                $bl_width = $width;
184            }
185            if (!empty($style)) {
186                $bl_style = $style;
187            }
188            if (!empty($color)) {
189                $bl_color = $color;
190            }
191            unset ($properties ['border-left']);
192        }
193
194        if (!empty($properties ['border-right'])) {
195            $width = NULL;
196            $style = NULL;
197            $color = NULL;
198            self::getShorthandValues ($properties ['border-right'], $width, $style, $color);
199            if (!empty($width)) {
200                $br_width = $width;
201            }
202            if (!empty($style)) {
203                $br_style = $style;
204            }
205            if (!empty($color)) {
206                $br_color = $color;
207            }
208            unset ($properties ['border-right']);
209        }
210
211        if (!empty($properties ['border-top'])) {
212            $width = NULL;
213            $style = NULL;
214            $color = NULL;
215            self::getShorthandValues ($properties ['border-top'], $width, $style, $color);
216            if (!empty($width)) {
217                $bt_width = $width;
218            }
219            if (!empty($style)) {
220                $bt_style = $style;
221            }
222            if (!empty($color)) {
223                $bt_color = $color;
224            }
225            unset ($properties ['border-top']);
226        }
227
228        if (!empty($properties ['border-bottom'])) {
229            $width = NULL;
230            $style = NULL;
231            $color = NULL;
232            self::getShorthandValues ($properties ['border-bottom'], $width, $style, $color);
233            if (!empty($width)) {
234                $bb_width = $width;
235            }
236            if (!empty($style)) {
237                $bb_style = $style;
238            }
239            if (!empty($color)) {
240                $bb_color = $color;
241            }
242            unset ($properties ['border-bottom']);
243        }
244
245        if (!empty($properties ['border-width'])) {
246            $top    = NULL;
247            $right  = NULL;
248            $bottom = NULL;
249            $left   = NULL;
250            self::getWidthShorthandValues ($properties ['border-width'], $top, $right, $bottom, $left);
251            if (!empty($top)) {
252                $bt_width = $top;
253            }
254            if (!empty($right)) {
255                $br_width = $right;
256            }
257            if (!empty($bottom)) {
258                $bb_width = $bottom;
259            }
260            if (!empty($left)) {
261                $bl_width = $left;
262            }
263            unset ($properties ['border-width']);
264        }
265
266        // Now normalize and minimize the collected properties values
267
268        // Re-assemble border properties to per side shorthand.
269        if (!empty($bt_width) || !empty($bt_style) || !empty($bt_color)) {
270            $properties ['border-top'] = $bt_width.' '.$bt_style.' '.$bt_color;
271        }
272        if (!empty($br_width) || !empty($br_style) || !empty($br_color)) {
273            $properties ['border-right'] = $br_width.' '.$br_style.' '.$br_color;
274        }
275        if (!empty($bb_width) || !empty($bb_style) || !empty($bb_color)) {
276            $properties ['border-bottom'] = $bb_width.' '.$bb_style.' '.$bb_color;
277        }
278        if (!empty($bl_width) || !empty($bl_style) || !empty($bl_color)) {
279            $properties ['border-left'] = $bl_width.' '.$bl_style.' '.$bl_color;
280        }
281
282        // If all sides are the same we can put them all together as a single border shorthand
283        if ($properties ['border-top'] == $properties ['border-right'] &&
284            $properties ['border-top'] == $properties ['border-bottom'] &&
285            $properties ['border-top'] == $properties ['border-left']) {
286            $properties ['border'] = $properties ['border-top'];
287            unset ($properties ['border-top']);
288            unset ($properties ['border-right']);
289            unset ($properties ['border-bottom']);
290            unset ($properties ['border-left']);
291        }
292    }
293}
294