Passed
Push — master ( 598445...fef947 )
by Andreas
11:12
created

midgard_admin_asgard_stylehelper   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Test Coverage

Coverage 13.58%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 71
dl 0
loc 153
ccs 11
cts 81
cp 0.1358
rs 10
c 1
b 0
f 0
wmc 25

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B render_help() 0 16 7
A _get_help_element() 0 29 6
A _get_nodes_inheriting_style() 0 14 2
A _get_style_elements_and_nodes() 0 26 3
A _get_component_default_elements() 0 17 3
A _get_nodes_using_style() 0 17 3
1
<?php
2
/**
3
 * @package midgard.admin.asgard
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
/**
10
 * Style helper methods
11
 *
12
 * @package midgard.admin.asgard
13
 */
14
class midgard_admin_asgard_stylehelper
15
{
16
    /**
17
     * The current request data
18
     */
19
    private array $_data;
20
21 7
    public function __construct(array &$data)
22
    {
23 7
        $this->_data =& $data;
24 7
        midcom::get()->head->enable_jquery_ui(['accordion']);
25
    }
26
27 4
    public function render_help()
28
    {
29 4
        if (empty($this->_data['object'])) {
30 1
            return;
31
        }
32
33 3
        if (   midcom::get()->dbfactory->is_a($this->_data['object'], 'midgard_style')
34 3
            && (   $this->_data['handler_id'] !== 'object_create'
35 3
                || $this->_data['current_type'] == 'midgard_element')) {
36
            // Suggest element names to create under a style
37
            $this->_data['help_style_elementnames'] = $this->_get_style_elements_and_nodes($this->_data['object']->id);
38
            midcom_show_style('midgard_admin_asgard_stylehelper_elementnames');
39
40 3
        } elseif (   midcom::get()->dbfactory->is_a($this->_data['object'], 'midgard_element')
41 3
                  && $this->_get_help_element()) {
42
            midcom_show_style('midgard_admin_asgard_stylehelper_element');
43
        }
44
    }
45
46
    private function _get_help_element() : bool
47
    {
48
        if (   empty($this->_data['object']->name)
49
            || empty($this->_data['object']->style)) {
50
            // We cannot help with empty elements
51
            return false;
52
        }
53
54
        if ($this->_data['object']->name == 'ROOT') {
55
            $this->_data['help_style_element'] = [
56
                'component' => 'midcom',
57
                'default'   => file_get_contents(MIDCOM_ROOT . '/midcom/style/ROOT.php'),
58
            ];
59
            return true;
60
        }
61
62
        // Find the element we're looking for
63
        $style_elements = $this->_get_style_elements_and_nodes($this->_data['object']->style);
64
        foreach ($style_elements['elements'] as $component => $elements) {
65
            if (!empty($elements[$this->_data['object']->name])) {
66
                $element_path = $elements[$this->_data['object']->name];
67
                $this->_data['help_style_element'] = [
68
                    'component' => $component,
69
                    'default'   => file_get_contents($element_path),
70
                ];
71
                return true;
72
            }
73
        }
74
        return false;
75
    }
76
77
    private function _get_style_elements_and_nodes(int $style_id) : array
78
    {
79
        $results = [
80
            'elements' => [
81
                'midcom' => [
82
                    'style-init' => '',
83
                    'style-finish' => '',
84
                 ]
85
            ],
86
            'nodes' => [],
87
        ];
88
89
        if (!$style_id) {
90
            return $results;
91
        }
92
        $style_path = midcom_db_style::path_from_id($style_id);
93
        $style_nodes = $this->_get_nodes_using_style($style_path);
94
95
        foreach ($style_nodes as $node) {
96
            // Get the list of style elements for the component
97
            $results['elements'][$node->component] ??= $this->_get_component_default_elements($node->component);
98
99
            $results['nodes'][$node->component][] = $node;
100
        }
101
102
        return $results;
103
    }
104
105
    /**
106
     * Get list of topics using a particular style
107
     *
108
     * @return midcom_db_topic[] List of folders
109
     */
110
    private function _get_nodes_using_style(string $style) : array
111
    {
112
        $style_nodes = [];
113
        // Get topics directly using the style
114
        $qb = midcom_db_topic::new_query_builder();
115
        $qb->add_constraint('style', '=', $style);
116
117
        foreach ($qb->execute() as $node) {
118
            $style_nodes[] = $node;
119
120
            if ($node->styleInherit) {
121
                $child_nodes = $this->_get_nodes_inheriting_style($node);
122
                $style_nodes = array_merge($style_nodes, $child_nodes);
123
            }
124
        }
125
126
        return $style_nodes;
127
    }
128
129
    private function _get_nodes_inheriting_style(midcom_db_topic $node) : array
130
    {
131
        $nodes = [];
132
        $qb = midcom_db_topic::new_query_builder();
133
        $qb->add_constraint('up', '=', $node->id);
134
        $qb->add_constraint('style', '=', '');
135
136
        foreach ($qb->execute() as $child_node) {
137
            $nodes[] = $child_node;
138
            $subnodes = $this->_get_nodes_inheriting_style($child_node);
139
            $nodes = array_merge($nodes, $subnodes);
140
        }
141
142
        return $nodes;
143
    }
144
145
    /**
146
     * List the default template elements shipped with a component
147
     *
148
     * @return array List of elements found indexed by the element name
149
     */
150
    private function _get_component_default_elements(string $component) : array
151
    {
152
        $elements = [];
153
154
        // Path to the file system
155
        $path = midcom::get()->componentloader->path_to_snippetpath($component) . '/style';
156
157
        if (!is_dir($path)) {
158
            debug_add("Directory {$path} not found.");
159
            return $elements;
160
        }
161
162
        foreach (glob($path . '/*.php') as $filepath) {
163
            $elements[basename($filepath, '.php')] = $filepath;
164
        }
165
166
        return $elements;
167
    }
168
}
169