columns[] = new Column(0, $pageType, 0, true, $this->schema->getTable()); parent::readHeaders(); if (!in_array('pid', $this->header)) throw new StructException('There is no "pid" header in the CSV. Schema not imported.'); } /** * Creates the insert string for the single value table * * @return string */ protected function getSQLforAllValues() { $colnames = array(); foreach ($this->columns as $i => $col) { $colnames[] = 'col' . $col->getColref(); } //replace first column with pid $colnames[0] = 'pid'; //insert rev at the end $colnames[] = 'rev'; $placeholds = join(', ', array_fill(0, count($colnames), '?')); $colnames = join(', ', $colnames); $table = $this->schema->getTable(); return "INSERT INTO data_$table ($colnames, latest) VALUES ($placeholds, 1)"; } /** * Add the revision. * * @param string[] $values * @param $line * @param string $single * @param string $multi */ protected function saveLine($values, $line, $single, $multi) { //create new page revision $pid = cleanID($values[0]); if ($this->createPage[$pid]) { $this->createPage($pid, $line); } $helper = plugin_load('helper', 'struct'); $revision = $helper->createPageRevision($pid, 'CSV data imported'); p_get_metadata($pid); // reparse the metadata of the page top update the titles/rev/lasteditor table // make sure this schema is assigned /** @noinspection PhpUndefinedVariableInspection */ Assignments::getInstance()->assignPageSchema( $pid, $this->schema->getTable() ); //add page revision to values $values[] = $revision; parent::saveLine($values, $line, $single, $multi); } /** * Create a page from a namespace template and replace column-label-placeholders * * This is intended to use the same placeholders as bureaucracy in their most basic version * (i.e. without default values, formatting, etc. ) * * @param string $pid * @param array $line */ protected function createPage($pid, $line) { $text = pageTemplate($pid); if (trim($text) === '') { $pageParts = explode(':', $pid); $pagename = end($pageParts); $text = "====== $pagename ======\n"; } $keys = array_reduce( $this->columns, function ($keys, Column $col) { if (!in_array($col->getLabel(), $keys, true)) { return $keys; } $index = array_search($col->getLabel(), $keys, true); $keys[$index] = $col->getFullQualifiedLabel(); return $keys; }, $this->header ); $keysAt = array_map(function ($key) { return "@@$key@@"; }, $keys); $keysHash = array_map(function ($key) { return "##$key##"; }, $keys); $flatValues = array_map( function ($value) { if (is_array($value)) { return implode(', ', $value); } return $value; }, $line ); $text = $this->evaluateIfNotEmptyTags($text, $keys, $flatValues); $text = str_replace($keysAt, $flatValues, $text); /** @noinspection CascadeStringReplacementInspection */ $text = str_replace($keysHash, $flatValues, $text); saveWikiText($pid, $text, 'Created by struct csv import'); } /** * Replace conditional tags * * @param string $text The template * @param string[] $keys The array of qualified headers * @param string[] $values The flat array of corresponding values * * @return string The template with the tags replaced */ protected function evaluateIfNotEmptyTags($text, $keys, $values) { return preg_replace_callback( '/([^<]*?)<\/ifnotempty>/', function ($matches) use ($keys, $values) { list (,$blockKey, $textIfNotEmpty) = $matches; $index = array_search($blockKey, $keys, true); if ($index === false) { msg('Import error: Key "' . hsc($blockKey) . '" not found!', -1); return ''; } if (trim($values[$index]) === '') { return ''; } return $textIfNotEmpty; }, $text ); } /** * In the paga schemas primary key is a touple of (pid, rev) * * @param string[] $values * @param string $single * @return array(pid, rev) */ protected function insertIntoSingle($values, $single) { $pid = $values[0]; $rev = $values[count($values) - 1]; //update latest $table = $this->schema->getTable(); $this->sqlite->query("UPDATE data_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid)); //insert into table parent::insertIntoSingle($values, $single); //primary key is touple of (pid, rev) return array($pid, $rev); } /** * Add pid and rev to insert query parameters * * @param string $multi * @param string $pk * @param string $column * @param string $row * @param string $value */ protected function insertIntoMulti($multi, $pk, $column, $row, $value) { list($pid, $rev) = $pk; //update latest $table = $this->schema->getTable(); $this->sqlite->query("UPDATE multi_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid)); $this->sqlite->query($multi, array($pid, $rev, $column->getColref(), $row + 1, $value)); } /** * In page schemas we use REPLACE instead of INSERT to prevent ambiguity * * @return string */ protected function getSQLforMultiValue() { $table = $this->schema->getTable(); /** @noinspection SqlResolve */ return "INSERT INTO multi_$table (pid, rev, colref, row, value, latest) VALUES (?,?,?,?,?,1)"; } /** * Check if page id realy exists * * @param Column $col * @param mixed $rawvalue * @return bool */ protected function validateValue(Column $col, &$rawvalue) { //check if page id exists and schema is bounded to the page if ($col->getLabel() == 'pid') { $pid = cleanID($rawvalue); if (isset($this->importedPids[$pid])) { $this->errors[] = 'Page "' . $pid . '" already imported. Skipping the row.'; return false; } if (page_exists($pid)) { $this->importedPids[$pid] = true; return true; } global $INPUT; if ($INPUT->bool('createPage')) { $this->createPage[$pid] = true; return true; } $this->errors[] = 'Page "' . $pid . '" does not exists. Skipping the row.'; return false; } return parent::validateValue($col, $rawvalue); } }