datatable.directory codebase
				https://datatable.directory/
			
			
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							148 lines
						
					
					
						
							3.9 KiB
						
					
					
				
			
		
		
	
	
							148 lines
						
					
					
						
							3.9 KiB
						
					
					
				<?php
 | 
						|
 | 
						|
 | 
						|
namespace App\Tables;
 | 
						|
 | 
						|
 | 
						|
use App\Models\Table;
 | 
						|
 | 
						|
/**
 | 
						|
 * Table exporter base class
 | 
						|
 */
 | 
						|
abstract class BaseExporter
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var Table the table to export
 | 
						|
     */
 | 
						|
    protected $table;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var Column[] - parsed columns for the table
 | 
						|
     */
 | 
						|
    protected $columns;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var bool - true if user wants download; can e.g. change mime type to text/plain if not
 | 
						|
     */
 | 
						|
    protected $wantDownload;
 | 
						|
 | 
						|
    /**
 | 
						|
     * TODO export options from enabled columns, sorts, etc
 | 
						|
     *
 | 
						|
     * @param Table $table
 | 
						|
     */
 | 
						|
    public function __construct(Table $table)
 | 
						|
    {
 | 
						|
        $this->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();
 | 
						|
}
 | 
						|
 |