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();
 | |
| }
 | |
| 
 |