1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4use dokuwiki\plugin\struct\types\Page; 5 6class CSVPageImporter extends CSVImporter { 7 8 protected $importedPids = array(); 9 10 /** 11 * Chceck if schema is page schema 12 * 13 * @throws StructException 14 * @param string $table 15 * @param string $file 16 */ 17 public function __construct($table, $file) { 18 parent::__construct($table, $file); 19 20 if($this->schema->isLookup()) throw new StructException($table.' is not a page schema'); 21 } 22 23 /** 24 * Import page schema only when the pid header is present. 25 */ 26 protected function readHeaders() { 27 28 //add pid to struct 29 $pageType = new Page(null, 'pid'); 30 $this->columns[] = new Column(0, $pageType); 31 32 parent::readHeaders(); 33 34 if(!in_array('pid', $this->header)) throw new StructException('There is no "pid" header in the CSV. Schema not imported.'); 35 } 36 37 /** 38 * Creates the insert string for the single value table 39 * 40 * @return string 41 */ 42 protected function getSQLforAllValues() { 43 $colnames = array(); 44 foreach($this->columns as $i => $col) { 45 $colnames[] = 'col' . $col->getColref(); 46 } 47 //replace first column with pid 48 $colnames[0] = 'pid'; 49 //insert rev at the end 50 $colnames[] = 'rev'; 51 52 $placeholds = join(', ', array_fill(0, count($colnames), '?')); 53 $colnames = join(', ', $colnames); 54 $table = $this->schema->getTable(); 55 56 return "INSERT INTO data_$table ($colnames, latest) VALUES ($placeholds, 1)"; 57 } 58 59 /** 60 * Add the revision. 61 * 62 * @param string[] $values 63 * @param $line 64 * @param string $single 65 * @param string $multi 66 */ 67 protected function saveLine($values, $line, $single, $multi) { 68 //create new page revision 69 $pid = $values[0]; 70 $helper = plugin_load('helper', 'struct'); 71 $revision = $helper->createPageRevision($pid, 'CSV data imported'); 72 p_get_metadata($pid); // reparse the metadata of the page top update the titles/rev/lasteditor table 73 74 // make sure this schema is assigned 75 /** @noinspection PhpUndefinedVariableInspection */ 76 Assignments::getInstance()->assignPageSchema( 77 $pid, 78 $this->schema->getTable() 79 ); 80 81 //add page revision to values 82 $values[] = $revision; 83 84 parent::saveLine($values, $line, $single, $multi); 85 } 86 87 /** 88 * In the paga schemas primary key is a touple of (pid, rev) 89 * 90 * @param string[] $values 91 * @param string $single 92 * @return array(pid, rev) 93 */ 94 protected function insertIntoSingle($values, $single) { 95 $pid = $values[0]; 96 $rev = $values[count($values) - 1]; 97 98 //update latest 99 $table = $this->schema->getTable(); 100 $this->sqlite->query("UPDATE data_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid)); 101 102 //insert into table 103 parent::insertIntoSingle($values, $single); 104 105 //primary key is touple of (pid, rev) 106 return array($pid, $rev); 107 } 108 109 /** 110 * Add pid and rev to insert query parameters 111 * 112 * @param string $multi 113 * @param string $pk 114 * @param string $column 115 * @param string $row 116 * @param string $value 117 */ 118 protected function insertIntoMulti($multi, $pk, $column, $row, $value) { 119 list($pid, $rev) = $pk; 120 121 //update latest 122 $table = $this->schema->getTable(); 123 $this->sqlite->query("UPDATE multi_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid)); 124 125 $this->sqlite->query($multi, array($pid, $rev, $column->getColref(), $row + 1, $value)); 126 } 127 128 /** 129 * In page schemas we use REPLACE instead of INSERT to prevent ambiguity 130 * 131 * @return string 132 */ 133 protected function getSQLforMultiValue() { 134 $table = $this->schema->getTable(); 135 /** @noinspection SqlResolve */ 136 return "INSERT INTO multi_$table (pid, rev, colref, row, value, latest) VALUES (?,?,?,?,?,1)"; 137 } 138 139 /** 140 * Check if page id realy exists 141 * 142 * @param Column $col 143 * @param mixed $rawvalue 144 * @return bool 145 */ 146 protected function validateValue(Column $col, &$rawvalue) { 147 //check if page id exists and schema is bounded to the page 148 if($col->getLabel() == 'pid') { 149 $pid = cleanID($rawvalue); 150 if (isset($this->importedPids[$pid])) { 151 $this->errors[] = 'Page "'.$pid.'" already imported. Skipping the row.'; 152 return false; 153 } 154 if(page_exists($pid)) { 155 //check if schema is assigned to page 156 $tables = Assignments::getInstance()->getPageAssignments($pid, true); 157 if (!in_array($this->schema->getTable(), $tables)) { 158 $this->errors[] = 'Schema not assigned to page "'.$pid.'"'; 159 return false; 160 } 161 $this->importedPids[$pid] = true; 162 return true; 163 } 164 $this->errors[] = 'Page "'.$pid.'" does not exists. Skipping the row.'; 165 return false; 166 } 167 168 return parent::validateValue($col, $rawvalue); 169 } 170} 171