1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4 5class CSVPageImporter extends CSVImporter 6{ 7 protected $importedPids = array(); 8 9 /** @var bool[] */ 10 protected $createPage = []; 11 12 /** 13 * Import page schema only when the pid header is present. 14 */ 15 protected function readHeaders() 16 { 17 parent::readHeaders(); 18 if (!in_array('pid', $this->header)) throw new StructException('There is no "pid" header in the CSV. Schema not imported.'); 19 } 20 21 /** 22 * Add the revision. 23 * 24 * @param string[] $values 25 */ 26 protected function saveLine($values) 27 { 28 //create new page revision 29 $pid = cleanID($values[0]); 30 if ($this->createPage[$pid]) { 31 $this->createPage($pid, $values); 32 } 33 // make sure this schema is assigned 34 /** @noinspection PhpUndefinedVariableInspection */ 35 Assignments::getInstance()->assignPageSchema( 36 $pid, 37 $this->schema->getTable() 38 ); 39 parent::saveLine($values); 40 } 41 42 /** 43 * Create a page from a namespace template and replace column-label-placeholders 44 * 45 * This is intended to use the same placeholders as bureaucracy in their most basic version 46 * (i.e. without default values, formatting, etc. ) 47 * 48 * @param string $pid 49 * @param array $line 50 */ 51 protected function createPage($pid, $line) 52 { 53 $text = pageTemplate($pid); 54 if (trim($text) === '') { 55 $pageParts = explode(':', $pid); 56 $pagename = end($pageParts); 57 $text = "====== $pagename ======\n"; 58 } 59 $keys = array_reduce( 60 $this->columns, 61 function ($keys, Column $col) { 62 if (!in_array($col->getLabel(), $keys, true)) { 63 return $keys; 64 } 65 $index = array_search($col->getLabel(), $keys, true); 66 $keys[$index] = $col->getFullQualifiedLabel(); 67 return $keys; 68 }, 69 $this->header 70 ); 71 72 $keysAt = array_map(function ($key) { 73 return "@@$key@@"; 74 }, $keys); 75 $keysHash = array_map(function ($key) { 76 return "##$key##"; 77 }, $keys); 78 $flatValues = array_map( 79 function ($value) { 80 if (is_array($value)) { 81 return implode(', ', $value); 82 } 83 return $value; 84 }, 85 $line 86 ); 87 $text = $this->evaluateIfNotEmptyTags($text, $keys, $flatValues); 88 $text = str_replace($keysAt, $flatValues, $text); 89 /** @noinspection CascadeStringReplacementInspection */ 90 $text = str_replace($keysHash, $flatValues, $text); 91 saveWikiText($pid, $text, 'Created by struct csv import'); 92 } 93 94 /** 95 * Replace conditional <ifnotempty fieldname></ifnotempty> tags 96 * 97 * @param string $text The template 98 * @param string[] $keys The array of qualified headers 99 * @param string[] $values The flat array of corresponding values 100 * 101 * @return string The template with the tags replaced 102 */ 103 protected function evaluateIfNotEmptyTags($text, $keys, $values) 104 { 105 return preg_replace_callback( 106 '/<ifnotempty (.+?)>([^<]*?)<\/ifnotempty>/', 107 function ($matches) use ($keys, $values) { 108 list (, $blockKey, $textIfNotEmpty) = $matches; 109 $index = array_search($blockKey, $keys, true); 110 if ($index === false) { 111 msg('Import error: Key "' . hsc($blockKey) . '" not found!', -1); 112 return ''; 113 } 114 if (trim($values[$index]) === '') { 115 return ''; 116 } 117 return $textIfNotEmpty; 118 }, 119 $text 120 ); 121 } 122 123 /** 124 * Check if page id realy exists 125 * 126 * @param Column $col 127 * @param mixed $rawvalue 128 * @return bool 129 */ 130 protected function validateValue(Column $col, &$rawvalue) 131 { 132 //check if page id exists and schema is bound to the page 133 if ($col->getLabel() == 'pid') { 134 $pid = cleanID($rawvalue); 135 if (isset($this->importedPids[$pid])) { 136 $this->errors[] = 'Page "' . $pid . '" already imported. Skipping the row.'; 137 return false; 138 } 139 if (page_exists($pid)) { 140 $this->importedPids[$pid] = true; 141 return true; 142 } 143 global $INPUT; 144 if ($INPUT->bool('createPage')) { 145 $this->createPage[$pid] = true; 146 return true; 147 } 148 $this->errors[] = 'Page "' . $pid . '" does not exists. Skipping the row.'; 149 return false; 150 } 151 152 return parent::validateValue($col, $rawvalue); 153 } 154} 155