Created
February 11, 2022 00:41
-
-
Save kadamwhite/eaca92a6629daf7be6e007b28bc8a793 to your computer and use it in GitHub Desktop.
A PHP trait to write data from WP-CLI to a CSV, in a memory-friendly and won't-lose-data-if-CLI-errors way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Simplify progressive generation of a CSV output file. Permits a command to | |
* write each row to a CSV as records are considered, avoiding the need to | |
* maintain the entire dataset in memory. | |
*/ | |
/* phpcs:disable HM.Files.ClassFileName.MismatchedName */ | |
// (HM's standards want this to be class-*, which is misleading.) | |
namespace MyProject\CLI; | |
trait CSV_Report { | |
/** | |
* Dictionary of CSV resources, keyed by file path. | |
* | |
* @var array | |
*/ | |
private $csv_report_handles; | |
/** | |
* Create and store a file resource at a particular path. | |
* | |
* @param string $path Path of CSV to create. | |
*/ | |
private function csv_report_open( string $path ) : void { | |
if ( ! isset( $this->csv_report_handles ) ) { | |
$this->csv_report_handles = []; | |
} | |
$this->csv_report_handles[ $path ] = fopen( $path, 'w' ); | |
} | |
/** | |
* Append a row of data to the CSV at a specific path. If the CSV resouve | |
* does not yet exist, a file handler will be opened and the array keys | |
* of the received data object will be written as the first row in the file. | |
* | |
* @param string $path The path of the CSV file to write to. | |
* @param array $data Associative array of data to write to the CSV file. | |
*/ | |
protected function csv_report_append( string $path, array $data ) : void { | |
if ( ! isset( $this->csv_report_handles[ $path ] ) ) { | |
$this->csv_report_open( $path ); | |
fputcsv( $this->csv_report_handles[ $path ], array_keys( $data ) ); | |
} | |
fputcsv( $this->csv_report_handles[ $path ], $data ); | |
} | |
/** | |
* Create and store a file resource at a particular path. | |
* | |
* @param string $path Path of CSV to create. | |
*/ | |
protected function csv_report_close( string $path ) : void { | |
if ( isset( $this->csv_report_handles[ $path ] ) ) { | |
fclose( $this->csv_report_handles[ $path ] ); | |
} | |
} | |
/** | |
* Wrap a bulk_task callback with a handler which will write the return | |
* value of each callback execution to a specified CSV. Return "false" | |
* from the passed callable to omit the result from the output file. | |
* | |
* @param callable $callback Alley_CLI_Bulk_Task bulk_task callback. | |
* @param string $path The path of the CSV file to write to. | |
* @return callable Wrapped callback. | |
*/ | |
protected function csv_report_from_callback( callable $callback, string $path = '' ) : callable { | |
if ( empty( $path ) ) { | |
return $callback; | |
} | |
return function( $post ) use ( $callback, $path ) { | |
$result = $callback( $post ); | |
if ( $result ) { | |
$this->csv_report_append( $path, $result ); | |
} | |
return $result; | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment