getHelperPluginManager(); $escape = $plugins->get('escapeHtml'); $assetUrl = $plugins->get('assetUrl'); $translate = $plugins->get('translate'); $file = $this->blockMetadata('file'); if (empty($file)): ?>

blockMetadata('theme_dir') . '/asset/data/' . $file; if (!file_exists($filepath) || !is_readable($filepath)) return; $file = basename($filepath); endif; ini_set('auto_detect_line_endings', '1'); $handle = fopen($filepath, 'rb'); if ($handle === false) return; $extension = pathinfo($file, PATHINFO_EXTENSION); if ($extension === 'tsv'): $delimiter = "\t"; $enclosure = '"'; $escaper = chr(0); else: $delimiter = ','; $enclosure = '"'; $escaper = '\\'; endif; // In order to separate folder and leaf, the data are loaded first. It avoids a recursive process too. $tree = []; $row = 0; $parents = []; $parent = null; while (($data = fgetcsv($handle, 100000, $delimiter, $enclosure, $escaper)) !== false) { $data = array_map('trim', $data); // Skip empty rows. if (!count(array_filter($data, 'strlen'))) continue; ++$row; $countColumns = count($data); $depth = -1; while (++$depth < $countColumns && !strlen($data[$depth])) {}; if ($depth === 0) { $parents = [0 => $row]; $parent = null; } elseif (isset($parents[$depth - 1])) { $parents = array_slice($parents, 0, $depth + 1); $parents[$depth] = $row; $parent = $parents[$depth - 1]; $tree[$parent]['children'][] = $row; } else { // Sometime the row is not well built. $parents = array_fill(0, $depth - 1, $row); $parent = null; } $tree[$row] = [ 'row' => $row, 'depth' => $depth, 'self' => $data[$depth], 'parent' => $parent, 'children' => [], ]; } fclose($handle); $this->headLink() ->appendStylesheet($assetUrl('vendor/jslists/jsLists.css', 'BlockPlus')) ->appendStylesheet($assetUrl('css/block-plus.css', 'BlockPlus')); $this->headScript() // Not deferable and script should be set after the div. ->appendFile($assetUrl('vendor/jslists/jsLists.js', 'BlockPlus')); $liBranch = '
  • %s
  • '; ?>