table = $table; $this->columns = Column::columnsFromJson($table->revision->columns); } protected function getHeaderComment($prefix = " ") { $table = $this->table; $owner = $this->table->owner; $s = $prefix."Table \"$table->title\" by $owner->title\n". $prefix."exported ".date('M n, Y \\a\\t G:i')."\n". $prefix."\n". $prefix."License: ". str_replace("\n", "\n$prefix", $table->license ?: 'CC0') ."\n". $prefix."\n". $prefix."Upstream: https://datatable.directory/$owner->handle/$table->name\n"; $s .= $prefix."\n". $prefix."Columns:\n"; foreach ($this->columns as $c) { $s .= $prefix." - $c->name ... $c->title\n"; } return $s; } /** * @return string - mime type for the downloaded file */ protected abstract function getMimeType(); /** * @return string - file extension for the downloaded file */ protected abstract function getFileExtension(); /** * @return string - file name without extension, by default the table name */ protected function getFileBasename() { return $this->table->name; } /** * Generate a response that appears as a file download to the browser * * @param bool $download - force download, otherwise the browser may show it in the window */ public function exportToBrowser($download = true) { $this->wantDownload = $download; $mimeType = $this->getMimeType(); $filename = $this->getFileBasename() . '.' . $this->getFileExtension(); ob_end_clean(); // Redirect output to a client’s web browser header("Content-Type: $mimeType; charset=utf-8"); if ($download) { header("Content-Disposition: attachment;filename=\"$filename\""); } // Cache headers header('Cache-Control: max-age=0'); // IE9 header('Cache-Control: max-age=1'); // Other IE headers header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified header('Cache-Control: cache, must-revalidate'); // HTTP/1.1 header('Pragma: no-cache'); // HTTP/1.0 $this->writeDocument(); exit; } /** * Generator that produces PHP arrays for all rows, fetched from the DB in given chunks. * * @param int $chunkSize - size of one chunk * @return \Generator|array[] */ protected function iterateRows($chunkSize = 1000) { $revision = $this->table->revision; $count = $revision->rows()->count(); $start = 0; while ($start < $count) { // TODO raw query to allow selecting aggregates, column subsets, etc $rows = $revision->rowsData($this->columns, false) ->offset($start)->limit($chunkSize)->get()->toArray(); foreach ($rows as $row) { unset($row['_row_pivot']); yield $row; } $start += $chunkSize; } } /** * Write the document to stdout ('php://output') */ protected abstract function writeDocument(); }