Search code examples
cakephppluginscakephp-2.0cakephp-2.1cakedc

How do I use fixed fields in CakeDC's csvUpload behavior in Util plugin


I am using the csvUpload behavior of the Utils plugin by CakeDC, on a CakePHP 2.2.1 install.

I have it working great it's processing a rather large csv successfully. However there are two fields in my table / Model that would be considered fixed, as they are based on ID's from from associated models that are not consistent. So I need to get these fixed values via variables which is easy enough.

So my question is, how do I use the fixed fields aspect of csvUpload? I have tried that following and many little variation, which obviously didn't work.

public function upload_csv($Id = null) {
    $unique_add = 69;
    if ( $this->request->is('POST') ) {
        $records_count = $this->Model->find( 'count' );
        try {
            $fixed = array('Model' => array('random_id' => $Id, 'unique_add' => $unique_add));
            $this->Model->importCSV($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
        } catch (Exception $e) {
            $import_errors = $this->Model->getImportErrors();
            $this->set( 'import_errors', $import_errors );
            $this->Session->setFlash( __('Error Importing') . ' ' . $this->request->data['Model']['CsvFile']['name'] . ', ' . __('column name mismatch.')  );
            $this->redirect( array('action'=>'import') );
        }

        $new_records_count = $this->Model->find( 'count' ) - $records_count;
        $this->Session->setFlash(__('Successfully imported') . ' ' . $new_records_count .  ' records from ' . $this->request->data['Model']['CsvFile']['name'] );
        $this->redirect(array('plugin'=>'usermgmt', 'controller'=>'users', 'action'=>'dashboard'));
    }
}

Any help would be greatly appreciated as I have only found 1 post concerning this behavior when I searching...


Solution

  • I made my custom method to achieve the same task. Define the following method in app\Plugin\Utils\Model\Behavior

    public function getCSVData(Model &$Model, $file, $fixed = array())
    {
        $settings = array(
                  'delimiter' => ',',
                  'enclosure' => '"',
                  'hasHeader' => true
                );
        $this->setup($Model, $settings);
        $handle = new SplFileObject($file, 'rb');       
        $header = $this->_getHeader($Model, $handle);
        $db = $Model->getDataSource();
        $db->begin($Model);
        $saved = array();
        $data = array();
        $i = 0;
        while (($row = $this->_getCSVLine($Model, $handle)) !== false)
        {
            foreach ($header as $k => $col)
            {
                // get the data field from Model.field              
                $col = str_replace('.', '-', trim($col));
                if (strpos($col, '.') !== false)
                {
                    list($model,$field) = explode('.', $col);
                    $data[$i][$model][$field] = (isset($row[$k])) ? $row[$k] : '';
                }
                else
                {
                    $col = str_replace(' ','_', $col);
                    $data[$i][$Model->alias][$col] = (isset($row[$k])) ? $row[$k] : '';
                }
            }
            $is_valid_row = false;
    
            foreach($data[$i][$Model->alias] as $col => $value )
            {
                if(!empty($data[$i][$Model->alias][$col]))
                {
                    $is_valid_row = true;                   
                }
            }
            if($is_valid_row == true)
            {
                $i++;
                $data = Set::merge($data, $fixed);  
            }
            else
            {
                unset($data[$i]);
            }
        }
        return $data;
    }   
    

    And you can use it using:

      $csv_data = $this->Model->getCSVData($this->request->data['Model']['CsvFile']['tmp_name'], $fixed);
    

    Here $csv_data will contain an array of all of those records from the csv file which are not empty and with the fixed field in each record index.