/modules/Application/src/Application/Feed/Importer/Csv.php
https://bitbucket.org/delta98/csv-consumer · PHP · 273 lines · 120 code · 38 blank · 115 comment · 9 complexity · 55b809fe4a0a09820e74375501d841b5 MD5 · raw file
- <?php
- /**
- * CSV Consumer Application
- *
- * @author Jason Brown <jason.brown.delta@gmail.com>
- */
- namespace Application\Feed\Importer;
- use Application\Feed\Data;
- use Application\Feed\Importer\ImportInterface;
- use Application\Feed\OptionsProviderInterface;
- use Zend\Stdlib\ArrayUtils;
- /**
- * Class CsvImporter
- * @package Application\Service
- * @TODO Cache processedData
- */
- class Csv implements ImportInterface, OptionsProviderInterface
- {
- /**
- * @var mixed
- */
- protected $filePath;
- /**
- * @var resource
- */
- protected $resource;
- /**
- * @var array
- */
- protected $options = array();
- /**
- * CSV Column Headers
- *
- * @var array
- */
- protected $columnHeaders = array();
- /**
- * Processed feed data
- *
- * @var array
- */
- protected $processedData = array();
- /**
- * Import Data
- *
- * @return mixed
- */
- public function import()
- {
- // Check File was opened successfully
- if($this->open())
- {
- // Process file
- $this->process();
- // Close Handle
- $this->close();
- // Check contents were processed successfully
- if(sizeof($this->getProcessedData()) > 0)
- {
- // Return a valid Feed Data object
- return new Data($this->getProcessedData());
- }
- }
- return false;
- }
- /**
- * Set File Path
- *
- * @param $filePath
- * @return \Application\Feed\Importer\Csv $this
- */
- public function setFilePath($filePath)
- {
- $this->filePath = $filePath;
- return $this;
- }
- /**
- * Get File Path
- */
- public function getFilePath()
- {
- return $this->filePath;
- }
- /**
- * Set Resource used to open file
- *
- * @see http://php.net/manual/en/function.fgetcsv.php
- * @param resource $resource
- */
- public function setResource($resource)
- {
- $this->resource = $resource;
- }
- /**
- * @return resource
- */
- public function getResource()
- {
- return $this->resource;
- }
- /**
- * Set Importer Options
- *
- * @param array $options
- * @return mixed|void
- * @throws \Exception
- */
- public function setOptions(array $options)
- {
- $this->options = $options;
- // Assign required params
- if(isset($this->options['file_path']))
- {
- // Check file path exists
- $this->setFilePath($this->options['file_path']);
- }else{
- throw new \Exception('Required option: file_path not provided');
- }
- }
- /**
- * Get Importer Options
- *
- * @return mixed
- */
- public function getOptions()
- {
- return $this->options;
- }
- /**
- * @return array
- */
- public function getColumnHeaders()
- {
- return $this->columnHeaders;
- }
- /**
- * Get the processed data
- *
- * @return array
- */
- public function getProcessedData()
- {
- return $this->processedData;
- }
- /**
- * Reset File Importer - clears processed column headers and file contents
- */
- public function reset()
- {
- $this->columnHeaders = array();
- $this->processedFile = array();
- }
- /**
- * Opens CSV File using provided mode
- *
- * @param string $mode
- * @return bool|resource
- */
- protected function open($mode = 'r')
- {
- // Open file using path and mode
- $resource = @fopen($this->getFilePath(), $mode);
- // Check for a valid resource
- if($resource !== false)
- {
- $this->setResource($resource);
- }else{
- return false;
- }
- return $this->getResource();
- }
- /**
- * Closes Resource
- */
- protected function close()
- {
- // Check for a resource to close
- if(!is_null($this->resource))
- {
- fclose($this->resource);
- }
- }
- /**
- * Processes provided file into a header/row associate array
- */
- protected function process()
- {
- // Get Resource Handle
- $handle = $this->getResource();
- // Flag to determine if headers have been set
- $headersSet = false;
- // Loop through each row within the provided file
- while (($line = fgetcsv($handle)) !== false)
- {
- // Determine if Headers were set, if not set them
- if($headersSet == false)
- {
- $this->columnHeaders = $line;
- $headersSet = true;
- }else{
- // Process Column Header and associate line value with that header
- $this->processedData[] = $this->_processAssociateLineWithColumnHeaders($this->columnHeaders, $line);
- }
- }
- }
- /**
- * Processes Column Header and splits underscore values into an associate array
- * before associating line value with header
- *
- * @param $columnHeaders
- * @param $line
- * @return array
- */
- protected function _processAssociateLineWithColumnHeaders($columnHeaders, $line)
- {
- $processedLines = array();
- // Create an associate array if underscored column header is detected
- foreach($columnHeaders as $key => $header)
- {
- // Check for an underscore in the Column Header
- if(preg_match('/^[a-z0-9]+_[a-z0-9]+$/i', ucwords($header)))
- {
- // Split header by underscore to separate strings
- $headers = explode('_', $header);
- // Form associate array with key being first string from split array
- $processedLine[$headers[0]] = array($headers[1] => $line[$key]);
- }else{
- $processedLine = array($header => $line[$key]);
- }
- // Merge newly processed line with all the other processed lines
- $processedLines = ArrayUtils::merge($processedLines, $processedLine);
- }
- return $processedLines;
- }
- }