public function execute()
 {
     $this->init();
     $this->reader->seek(max(0, waRequest::request('row', 0, waRequest::TYPE_INT)));
     $limit = max(1, waRequest::request('limit', 50, waRequest::TYPE_INT));
     $this->reader->columns(array(array('shopCsvProductviewController', 'tableRowHandler'), array(__CLASS__, 'columns')));
     $n = 0;
     $this->response['tbody'] = '';
     while (++$n <= $limit && $this->reader->next()) {
         $this->response['tbody'] .= $this->reader->getTableRow();
     }
     $this->response['rows_count'] = $this->reader->count();
     $this->response['current'] = $this->reader->key();
 }
 protected function info()
 {
     $interval = 0;
     if (!empty($this->data['timestamp'])) {
         $interval = time() - $this->data['timestamp'];
     }
     $response = array('time' => sprintf('%d:%02d:%02d', floor($interval / 3600), floor($interval / 60) % 60, $interval % 60), 'processId' => $this->processId, 'progress' => 0.0, 'ready' => $this->isDone(), 'count' => empty($this->data['count']) ? false : $this->data['count'], 'memory' => sprintf('%0.2fMByte', $this->data['memory'] / 1048576), 'memory_avg' => sprintf('%0.2fMByte', $this->data['memory_avg'] / 1048576));
     $stage_count = 0;
     //count($this->data['current']);
     foreach ($this->data['current'] as $stage => $current) {
         if ($this->data['count'][$stage]) {
             if ($stage == self::STAGE_SKU) {
                 if ($this->data['drection'] == 'import') {
                     $response['progress'] += 100.0 * (1.0 * $current / $this->data['count'][$stage] - 1.0) / $this->data['count'][self::STAGE_PRODUCT];
                 }
             } else {
                 ++$stage_count;
                 $response['progress'] += 100.0 * (1.0 * $current / $this->data['count'][$stage]);
             }
         }
     }
     $response['progress'] = sprintf('%0.3f%%', $response['progress'] / max(1, $stage_count));
     $response['stage_count'] = $stage_count;
     $response['current_count'] = $this->data['current'];
     $response['processed_count'] = $this->data['processed_count'];
     $this->getResponse()->addHeader('Content-type', 'application/json');
     $this->getResponse()->sendHeaders();
     if ($this->writer) {
         $response['file'] = urlencode(basename($this->writer->file()));
     }
     if ($response['ready']) {
         $response['report'] = $this->report();
         if (!empty($this->data['emulate'])) {
             $callback = create_function('$a', 'return count($a)>1;');
             $emulate = array();
             foreach ($this->data['emulate'] as $row => $key) {
                 if (!isset($emulate[$key])) {
                     $emulate[$key] = array();
                 }
                 $emulate[$key][] = $row;
             }
             $params = array();
             if ($collision = array_filter($emulate, $callback)) {
                 $response['collision'] = array();
                 foreach ($collision as $key => $rows) {
                     $rows = array_map('intval', $rows);
                     asort($rows);
                     $response['collision'][] = array('key' => $key, 'rows' => $rows);
                     $params[$key] = $rows;
                 }
             } else {
                 $response['collision'] = true;
             }
             if (!empty($this->reader)) {
                 $response['rows_count'] = $this->reader->count();
                 shopCsvReader::snapshot($this->reader, $params);
                 unset($params);
             }
         }
     }
     echo $this->json($response);
 }
 protected function save(waRequestFile $file)
 {
     $path = wa()->getTempPath('csv/upload/');
     waFiles::create($path);
     $original_name = $file->name;
     if ($name = tempnam($path, 'csv')) {
         unlink($name);
         if (($ext = pathinfo($original_name, PATHINFO_EXTENSION)) && preg_match('/^\\w+$/', $ext)) {
             $name .= '.' . $ext;
         }
         $file->moveTo($name);
     } else {
         throw new waException(_w('Error file upload'));
     }
     $encoding = waRequest::post('encoding', 'UTF-8');
     $delimiter = waRequest::post('delimiter');
     try {
         $this->reader = new shopCsvReader($name, $delimiter, $encoding);
         $delimiters = array(';', ',', 'tab');
         $used_delimiters = array($delimiter);
         while (count($this->reader->header()) < 2 && ($delimiter = array_diff($delimiters, $used_delimiters))) {
             $delimiter = reset($delimiter);
             $used_delimiters[] = $delimiter;
             $this->reader->delete();
             $this->reader = new shopCsvReader($name, $delimiter, $encoding);
         }
         if (count($this->reader->header()) < 2) {
             $this->reader->delete();
             $delimiter = waRequest::post('delimiter');
             $this->reader = new shopCsvReader($name, $delimiter, $encoding);
         }
         $encodings = array('UTF-8', 'Windows-1251', 'ISO-8859-1');
         $used_encodings = array($encoding);
         while (in_array(false, (array) $this->reader->header(), true) && ($encoding = array_diff($encodings, $used_encodings))) {
             $encoding = reset($encoding);
             $used_encodings[] = $encoding;
             $this->reader->delete();
             $this->reader = new shopCsvReader($name, $delimiter, $encoding);
         }
         if (in_array(false, (array) $this->reader->header(), true) || count($this->reader->header()) < 2) {
             throw new waException($this->reader->header() ? _w('No data columns were located in the uploaded file. Make sure right separator and encoding were chosen for this upload.') : _w('Unsupported CSV file structure'));
         }
         $profile_helper = new shopImportexportHelper('csv:product:import');
         $profile = $profile_helper->getConfig();
         $profile['config'] += array('encoding' => $encoding, 'delimiter' => ';', 'map' => array());
         $params = array();
         $params['id'] = 'csvproducts';
         $params['title_wrapper'] = '%s';
         $params['description_wrapper'] = '<br><span class="hint">%s</span>';
         $params['control_wrapper'] = '<div class="field"><div class="name">%s</div><div class="value">%s %s</div></div>';
         $params['options'] = $this->options();
         $control = true ? shopCsvReader::TABLE_CONTROL : shopCsvReader::MAP_CONTROL;
         switch ($control) {
             case shopCsvReader::TABLE_CONTROL:
                 $params['preview'] = 50;
                 $params['columns'] = array(array('shopCsvProductviewController', 'tableRowHandler'), '&nbsp;');
                 $params['control_wrapper'] = '<div class="field"><div class="value" style="overflow-x:auto;margin-left:0;">%s %s</div></div>';
                 $params['title_wrapper'] = false;
                 $params['row_handler'] = 'csv_product/rows/';
                 $params['row_handler_string'] = true;
                 $params['autocomplete_handler'] = 'csv_product/autocomplete/reset/';
                 break;
             case shopCsvReader::MAP_CONTROL:
             default:
                 $control = shopCsvReader::MAP_CONTROL;
                 break;
         }
         return array('name' => htmlentities(basename($this->reader->file()), ENT_QUOTES, 'utf-8'), 'original_name' => htmlentities(basename($original_name), ENT_QUOTES, 'utf-8'), 'size' => waFiles::formatSize($this->reader->size()), 'original_size' => waFiles::formatSize($file->size), 'controls' => waHtmlControl::getControl($control, 'csv_map', $params), 'control' => $control, 'header' => $this->reader->header(), 'columns_offset' => count(ifset($params['columns'], array())), 'delimiter' => $delimiter, 'encoding' => $encoding);
     } catch (waException $ex) {
         if ($this->reader) {
             $this->reader->delete(true);
         }
         throw $ex;
     }
 }