Completed
Push — master ( 37b087...b08a55 )
by Mihail
02:34
created

Listing::buildDropdown()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
rs 8.5806
cc 4
eloc 17
nc 3
nop 2
1
<?php
2
3
namespace Ffcms\Core\Helper\HTML;
4
5
use Ffcms\Core\Helper\HTML\System\Dom;
6
use Ffcms\Core\Helper\HTML\System\NativeGenerator;
7
use Ffcms\Core\Helper\Type\Arr;
8
use Ffcms\Core\Helper\Type\Obj;
9
use Ffcms\Core\Helper\Type\Str;
10
11
/**
12
 * Class Listing - build html listing carcase
13
 * @package Ffcms\Core\Helper\HTML
14
 */
15
class Listing extends NativeGenerator
16
{
17
18
    /**
19
     * Construct listing elements,property's and future's
20
     * @param array $elements
21
     * @return string
22
     */
23
    public static function display($elements)
24
    {
25
        // check input elements
26
        if (!Arr::in($elements['type'], ['ul', 'ol']) || count($elements['items']) < 1) {
27
            return null;
28
        }
29
30
        // initialize new DOM model
31
        $dom = new Dom();
32
        // return DOM-HTML, build based on closures!
33
        return $dom->{$elements['type']}(function () use ($dom, $elements) {
34
            // prepare output avg variable
35
            $itemHTML = null;
36
            // get active order level
37
            $orderActiveLink = false;
38
            if (isset($elements['activeOrder'])) {
39
                $orderActiveLink = $elements['activeOrder'];
40
                unset($elements['activeOrder']);
41
            }
42
43
            foreach ($elements['items'] as $item) {
44
                // sounds like dropdown array
45
                if (isset($item['dropdown']) && isset($item['items'])) {
46
                    $itemHTML .= self::buildDropdown($dom, $item);
47
                } elseif (isset($item['link'])) { // looks like link item
48
                    $itemHTML .= self::buildLink($dom, $item, $orderActiveLink);
49
                } else { // just text item
50
                    $itemHTML .= self::buildText($dom, $item);
51
                }
52
            }
53
            return $itemHTML;
54
        }, $elements['property']);
55
    }
56
57
    /**
58
     * Build dropdown dom element
59
     * @param Dom $dom
60
     * @param array $item
61
     * @return string
62
     */
63
    private static function buildDropdown($dom, $item)
64
    {
65
        if (!Obj::isArray($item['items'])) {
66
            return null;
67
        }
68
69
        if (!isset($item['menuProperty']['class']))
70
            $item['menuProperty']['class'] = 'dropdown-menu';
71
72
        return $dom->li(function() use($dom, $item){
73
            $dropdownLink = $dom->a(function() use ($dom, $item){
74
                return self::applyEscape($item['text'], $item['html'], $item['!secure']) . ' ' . $dom->span(function(){}, ['class' => 'caret']);
75
            }, $item['dropdown']);
76
77
            $dropdownElements = $dom->ul(function() use ($dom, $item){
78
                $resp = null;
79
                foreach ($item['items'] as $obj) {
80
                    $resp .= self::buildLink($dom, $obj, false);
81
                }
82
                return $resp;
83
            }, $item['menuProperty']);
84
85
            return $dropdownLink . $dropdownElements;
86
        }, $item['property']);
87
88
    }
89
90
    /**
91
     * Build text item
92
     * @param Dom $dom
93
     * @param array $item
94
     * @return string
95
     */
96
    private static function buildText($dom, $item)
97
    {
98
        $text = self::applyEscape($item['text'], $item['html'], $item['!secure']);
99
        return $dom->li(function() use ($text){
100
            return $text;
101
        }, $item['property']);
102
    }
103
104
    /**
105
     * Build link with active definition in listing
106
     * @param Dom $dom
107
     * @param array $item
108
     * @param bool $orderActiveLink
109
     * @return string
110
     */
111
    private static function buildLink($dom, $item, $orderActiveLink = false)
112
    {
113
        // set default link data - text and properties
114
        $text = self::applyEscape($item['text'], $item['html'], $item['!secure']);
115
        $properties = $item['property'];
116
117
        // try to parse link format for controller/action definition (must be array: 'main/index' to ['main/index'])
118
        if (!Obj::isArray($item['link']) && !Str::startsWith('http', $item['link']) && !Str::startsWith('#', $item['link'])) {
119
            $item['link'] = [$item['link']];
120
        }
121
122
        // if its a controller/action definition try to work with active class
123
        if (Obj::isArray($item['link'])) {
124
            // check if css class for active item is defined
125
            if (!isset($item['activeClass'])) {
126
                $item['activeClass'] = 'active';
127
            }
128
129
            // check if element is active on current URI
130
            if (self::isCurrentLink($item['link'], $item['activeOn'], $orderActiveLink) === true) {
131
                $properties['class'] = Str::concat(' ', $item['activeClass'], $properties['class']);
132
            }
133
        }
134
135
        // set href source for link
136
        $item['linkProperty']['href'] = self::convertLink($item['link']);
137
138
        // build output <li@params><a @params>@text</li>
139
        return $dom->li(function () use ($dom, $text, $item) {
140
            return $dom->a(function() use ($text) {
141
                return $text;
142
            }, $item['linkProperty']);
143
        }, $properties);
144
    }
145
}