Project

General

Profile

Download (8.69 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3

    
4
class DerivationTreeComposer {
5

    
6
  private $root_unit_dtos;
7
  private $focused_unit_uuid = null;
8
  private $with_details = false;
9
  private $collapsible = false;
10
  private $use_field_unit_short_label = null;
11

    
12
  /**
13
   * @return bool
14
   */
15
  public function isCollapsible() {
16
    return $this->collapsible;
17
  }
18

    
19
  /**
20
   * @param bool $collapsible
21
   */
22
  public function setCollapsible($collapsible) {
23
    $this->collapsible = $collapsible;
24
  }
25

    
26
  /**
27
   * @return bool
28
   */
29
  public function isWithDetails() {
30
    return $this->with_details;
31
  }
32

    
33
  private function useFieldUnitShortLabel() {
34
      if($this->use_field_unit_short_label === null){
35
        $specimen_derivate_tree_options = get_array_variable_merged(CDM_SPECIMEN_DERIVATE_TREE_OPTIONS, CDM_SPECIMEN_DERIVATE_TREE_OPTIONS_DEFAULT);
36
        $this->use_field_unit_short_label = $specimen_derivate_tree_options['field_unit_short_label'];
37
      }
38
      return $this->use_field_unit_short_label;
39
  }
40

    
41
  public function collapsibleItemClassAttribute($has_sub_derivatives) {
42
    return $this->isCollapsible() & $has_sub_derivatives === TRUE ? ' tree-item-collapsible' : '';
43

    
44
  }
45

    
46
  public function subItemsClassAttribute($has_sub_derivatives) {
47
    return $has_sub_derivatives === true ? ' with-sub-items' : '';
48
  }
49

    
50
  public function itemCollapsedStateClassAttribute() {
51
    return $this->isCollapsible() ? ' collapsed' : '';
52
  }
53

    
54
  /**
55
   * @param bool $with_details
56
   */
57
  public function setWithDetails($with_details) {
58
    $this->with_details = $with_details;
59
  }
60

    
61
  /**
62
   * DerivationTreeComposer constructor.
63
   */
64
  public function __construct($root_unit_dtos ) {
65
    $this->root_unit_dtos = $root_unit_dtos;
66
  }
67

    
68
  /**
69
   * @return array
70
   *     list of SpecimenOrObservationDTOs
71
   */
72
  public function getRootUnitDtos() {
73
    return $this->root_unit_dtos;
74
  }
75

    
76
  /**
77
   * @param array $root_unit_dtos
78
   *     list of SpecimenOrObservationDTOs
79
   */
80
  public function setRootUnitDtos($root_unit_dtos) {
81
    $this->root_unit_dtos = $root_unit_dtos;
82
  }
83

    
84
  /**
85
   * @return null
86
   */
87
  public function getFocusedUnitUuid() {
88
    return $this->focused_unit_uuid;
89
  }
90

    
91
  /**
92
   * @param null $focused_unit_uuid
93
   */
94
  public function setFocusedUnitUuid($focused_unit_uuid) {
95
    $this->focused_unit_uuid = $focused_unit_uuid;
96
  }
97

    
98
  public function compose() {
99
    $derivation_tree = $this->derived_units_tree($this->root_unit_dtos);
100

    
101
    $render_array = [];
102
    $render_array['derived-unit-tree'] = $derivation_tree;
103

    
104
    _add_js_derivation_tree('.item-tree');
105

    
106
    return $render_array;
107
  }
108

    
109
  /* =======  member compose  methods ========== */
110

    
111

    
112
  /**
113
   * Creates the root levels and trees for all subordinate derivatives.
114
   *
115
   * See derived_units_sub_tree()
116
   *
117
   * @return array
118
   *    An array which can be used in render arrays to be passed to the
119
   * theme_table() and theme_list().
120
   */
121

    
122
  private function derived_units_tree() {
123
    RenderHints::pushToRenderStack('derived-unit-tree');
124
    RenderHints::setFootnoteListKey('derived-unit-tree');
125

    
126
    $list_items = $this->derived_units_as_list_items($this->root_unit_dtos);
127

    
128
    $root_items = [
129
      '#theme' => 'item_list',
130
      '#type' => 'ul',
131
      '#prefix' => '<div class="item-tree">',
132
      '#suffix' => '</div>',
133
      '#attributes' => [
134
      ],
135
      '#items' => $list_items,
136
    ];
137

    
138
    $root_items['footnotes'] = markup_to_render_array(render_footnotes());
139
    RenderHints::popFromRenderStack();
140

    
141
    return $root_items;
142

    
143
  }
144

    
145
  /**
146
   * Creates render array items for FieldUnitDTO or DerivedUnitDTO.
147
   *
148
   * @param array $root_unit_dtos
149
   *     list of SpecimenOrObservationDTOs
150
   *
151
   * @return array
152
   *    An array which can be used in render arrays to be passed to the
153
   * theme_table() and theme_list().
154
   */
155
   private function derived_units_as_list_items(array $root_unit_dtos) {
156

    
157
    $list_items = [];
158
    //we need one more item to contain the items of one level (fieldunit, derivate data etc.)
159
    foreach ($root_unit_dtos as &$sob_dto) {
160
      $has_sub_derivatives = isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0;
161
      $item = [];
162
      $item['class'] = [
163
        'derived-unit-item ',
164
        html_class_attribute_ref($sob_dto),
165
        $this->itemCollapsedStateClassAttribute(),
166
        $this->collapsibleItemClassAttribute($has_sub_derivatives),
167
        $this->subItemsClassAttribute($has_sub_derivatives)
168
      ];
169
      // data" element of the array is used as the contents of the list item
170
      $item['data'] = [];
171
      $unit_content_markup = '';
172
      if($this->with_details){
173
        $unit_dto_render_array = compose_cdm_specimen_or_observation_dto_details_grid($sob_dto);
174
        $this->applyUnitContentGrid($unit_dto_render_array);
175
        $unit_content_markup = drupal_render($unit_dto_render_array);
176
      }
177
      $item['data'] = $this->applyItemWrapper(
178
        $this->derived_units_tree_node_header($sob_dto)
179
        . $unit_content_markup
180
        , $has_sub_derivatives);
181
      if ($has_sub_derivatives) {
182
        usort($sob_dto->derivatives, 'compare_specimen_or_observation_dtos');
183
        // children are displayed in a nested list.
184
        $item['children'] = $this->derived_units_as_list_items($sob_dto->derivatives);
185
      }
186
      $list_items[] = $item;
187
    }
188

    
189
    return $list_items;
190
  }
191

    
192

    
193
  /**
194
   * @param $unit_dto_render_array
195
   *
196
   * @return mixed
197
   *
198
   * FIXME: merge into compose_cdm_specimen_or_observation_dto_details_grid() again
199
   */
200
  function applyUnitContentGrid(&$unit_dto_render_array){
201
    $unit_dto_render_array['#prefix'] = '<div class="unit-content derived-unit-details-grid">';
202
    $unit_dto_render_array['#suffix'] = '</div>';
203
    return $unit_dto_render_array;
204
  }
205

    
206
  function applyItemWrapper($item_markup, $has_children){
207
    $sub_item_line_class_attribute = $has_children ? ' item-wrapper-with-sub-items' : '';
208
    return '<div class="item-wrapper' . $sub_item_line_class_attribute . '">' // allows to apply the borders between .derived-unit-tree-root and .unit-content
209
      . $item_markup
210
    . '</div>';
211
  }
212

    
213
  /**
214
   * @param $sob_dto
215
   *
216
   * @return string
217
   */
218
  function derived_units_tree_node_header($sob_dto) {
219
    $link = '';
220
    $focused_attribute = '';
221
    $hover_effect_attribute = '';
222
    $collapse_open_icons = '';
223
    $unit_header_wrapper_sub_items_class_attr = '';
224
    if(is_uuid($this->getFocusedUnitUuid()) & $sob_dto->uuid == $this->getFocusedUnitUuid()) {
225
      $focused_attribute = " focused_item";
226
    } else {
227
      $link = cdm_internal_link(path_to_specimen($sob_dto->uuid), NULL);
228
    }
229
    if($this->isWithDetails()){
230
      $hover_effect_attribute = ' unit-label-hover-effect';
231
    }
232
    $icon_link_markup = '';
233
    if($link) {
234
      $icon_link_markup = '<span class="page-link">' . $link . '</span>';
235
    }
236
    $has_sub_derivatives = isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0;
237
    if($has_sub_derivatives){
238
      if($this->isCollapsible()){
239
        $collapse_open_icons = '<span class="tree-node-symbol tree-node-symbol-collapsible">'
240
          . font_awesome_icon_markup('fa-' . SYMBOL_COLLAPSIBLE_CLOSED)
241
          . '</span>';
242
      } else {
243
        $collapse_open_icons = '<span class="tree-node-symbol">'
244
          . font_awesome_icon_markup('fa-' . SYMBOL_COLLAPSIBLE_OPEN)
245
          . '</span>';
246
      }
247
    }
248
    if($has_sub_derivatives){
249
      $unit_header_wrapper_sub_items_class_attr = ' unit-header-wrapper-with-sub-items';
250
    }
251
    if( $sob_dto->type == 'FieldUnit' ){
252
      if($this->useFieldUnitShortLabel() && isset_not_empty($sob_dto->collectingString)){
253
        $label = $sob_dto->collectingString;
254
      } else {
255
        $label = $sob_dto->label;
256
      }
257
    } else {
258
      $label = $sob_dto->specimenShortTitle;
259
    }
260
    return '<div class="unit-header-wrapper' . $unit_header_wrapper_sub_items_class_attr . $focused_attribute . '"><div class="unit-header"><div class="unit-label' . $hover_effect_attribute .' ">' . $collapse_open_icons . '<span class="symbol">' . $this->symbol_markup($sob_dto) . '</span>' . $label . $icon_link_markup . '</div></div></div>';
261
  }
262

    
263
  /**
264
   * @param $sob_dto
265
   *
266
   * @return String
267
   */
268
  public function symbol_markup($sob_dto) {
269
    if(count($sob_dto->specimenTypeDesignations)){
270
      $base_of_record_symbol = font_awesome_icon_stack([
271
        symbol_for_base_of_record($sob_dto->recordBase->uuid,
272
          [
273
          'class' => ['fas', 'fa-stack-1x'],
274
          'style' => ['--fa-primary-color: red;']
275
        ]),
276
        font_awesome_icon_markup('fa-tag',
277
          [
278
            'class' => ['fas', 'fa-rotate-180', 'fa-stack-1x'],
279
            'style' => ['color: red; vertical-align:bottom; text-align:left; font-size:.75em; bottom: -0.35em;']
280
          ]
281
        )
282
      ]);
283
    } else {
284
      $base_of_record_symbol = symbol_for_base_of_record($sob_dto->recordBase->uuid);
285
    }
286
    return $base_of_record_symbol;
287
  }
288

    
289
}
(3-3/14)