public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new File_CSV(); } return self::$instance; }
function parseContenDetail($url, $data, &$x) { global $logger, $filename, $conf; $content = getContent($url); if ($content != "") { $row_data = array(); foreach ($data as $key => $value) { $row_data[] = StringHelper::handleStrNewline(parseTag($value, $content)); } $row_data[] = $url; if (trim($row_data[0]) || trim($row_data[1]) || trim($row_data[2])) { File_CSV::write($filename, $row_data, $conf); echo "{$x} [Ok].\n"; $logger->log("Get {$url} content.[Ok]"); } else { echo "{$x} [Fail].\n"; $logger->log("Get {$url} content.[Fail]"); } $x++; } }
/** * Front to call getPointer and moving the resource to the * beginning of the file * Reset it if you like. * * @param string $file The name of the file * @param array &$conf The configuration * @param string $mode The open node (ex: FILE_MODE_READ or FILE_MODE_WRITE) * * @return boolean true on success false on failure */ function resetPointer($file, &$conf, $mode) { if (!File_CSV::getPointer($file, $conf, $mode, true)) { return false; } return true; }
/** * Discover the format of a CSV file (the number of fields, the separator * and if it quote string fields) * * @param string the CSV file name * @return mixed Assoc array or false */ function discoverFormat($file) { if (!($fp = @fopen($file, 'r'))) { return File_CSV::raiseError("Could not open file: {$file}"); } $seps = array("\t", ';', ':', ','); $matches = array(); // Take the first 10 lines and store the number of ocurrences // for each separator in each line for ($i = 0; $i < 10 && ($line = fgets($fp, 4096)); $i++) { foreach ($seps as $sep) { $matches[$sep][$i] = substr_count($line, $sep); } } $final = array(); // Group the results by amount of equal ocurrences foreach ($matches as $sep => $res) { $times = array(); $times[0] = 0; foreach ($res as $k => $num) { if ($num > 0) { $times[$num] = isset($times[$num]) ? $times[$num] + 1 : 1; } } arsort($times); $fields[$sep] = key($times); $amount[$sep] = $times[key($times)]; } arsort($amount); $sep = key($amount); $fields = $fields[$sep]; if (empty($fields)) { return File_CSV::raiseError('Could not discover the separator'); } $conf['fields'] = $fields + 1; $conf['sep'] = $sep; // Test if there are fields with quotes arround in the first 5 lines $quotes = '"\''; $quote = null; rewind($fp); for ($i = 0; $i < 5 && ($line = fgets($fp, 4096)); $i++) { if (preg_match("|{$sep}([{$quotes}]).*([{$quotes}]){$sep}|U", $line, $match)) { if ($match[1] == $match[2]) { $quote = $match[1]; break; } } if (preg_match("|^([{$quotes}]).*([{$quotes}]){$sep}|", $line, $match) || preg_match("|([{$quotes}]).*([{$quotes}]){$sep}\\s\$|Us", $line, $match)) { if ($match[1] == $match[2]) { $quote = $match[1]; break; } } } $conf['quote'] = $quote; fclose($fp); // XXX What about trying to discover the "header"? return $conf; }
/** * Discover the format of a CSV file (the number of fields, the separator * and if it quote string fields) * * @param string the CSV file name * @param array extra separators that should be checked for. * @return mixed Assoc array or false */ function discoverFormat($file, $extraSeps = array()) { if (!($fp = @fopen($file, 'r'))) { return File_CSV::raiseError("Could not open file: {$file}"); } $seps = array("\t", ';', ':', ','); $seps = array_merge($seps, $extraSeps); $matches = array(); // Set auto detect line ending for Mac EOL support if < PHP 4.3.0. $phpver = version_compare('4.1.0', phpversion(), '<'); if ($phpver) { $oldini = ini_get('auto_detect_line_endings'); ini_set('auto_detect_line_endings', '1'); } // Take the first 10 lines and store the number of ocurrences // for each separator in each line $lines = file($file); if (count($lines) > 10) { $lines = array_slice($lines, 0, 10); } if ($phpver) { ini_set('auto_detect_line_endings', $oldini); } foreach ($lines as $line) { foreach ($seps as $sep) { $matches[$sep][] = substr_count($line, $sep); } } $final = array(); // Group the results by amount of equal ocurrences foreach ($matches as $sep => $res) { $times = array(); $times[0] = 0; foreach ($res as $k => $num) { if ($num > 0) { $times[$num] = isset($times[$num]) ? $times[$num] + 1 : 1; } } arsort($times); // Use max fields count. $fields[$sep] = max(array_flip($times)); $amount[$sep] = $times[key($times)]; } arsort($amount); $sep = key($amount); $conf['fields'] = $fields[$sep] + 1; $conf['sep'] = $sep; // Test if there are fields with quotes arround in the first 5 lines $quotes = '"\''; $quote = null; if (count($lines) > 5) { $lines = array_slice($lines, 0, 5); } foreach ($lines as $line) { if (preg_match("|{$sep}([{$quotes}]).*([{$quotes}]){$sep}|U", $line, $match)) { if ($match[1] == $match[2]) { $quote = $match[1]; break; } } if (preg_match("|^([{$quotes}]).*([{$quotes}]){$sep}|", $line, $match) || preg_match("|([{$quotes}]).*([{$quotes}]){$sep}\\s\$|Us", $line, $match)) { if ($match[1] == $match[2]) { $quote = $match[1]; break; } } } $conf['quote'] = $quote; fclose($fp); // XXX What about trying to discover the "header"? return $conf; }
require_once 'Log.php'; require_once 'File/CSV.php'; require_once $ClassDir . 'StringHelper.class.php'; $PattenDataDir = "data/"; $conf = array('fields' => 15, 'sep' => ";", 'quote' => '"', 'header' => false, 'crlf' => "\r\n"); // read data //2006_10_19_02_03.txt //2006_10_19_05_56.txt //2006_10_19_07_10.txt //2006_10_20_08_42.txt //2006_10_20_12_42.txt //2006_10_20_16_49.txt //2006_10_25_11_10.txt $filename = "D:/data_temp/ÆóÒµÊý¾Ý/2006_10_20_16_49.txt"; $x = 1; while ($fields = File_CSV::read($filename, $conf)) { $apf_company = DB_DataObject::factory('ApfCompany'); $apf_company->setName($fields[0]); $apf_company->setAddrees($fields[1]); $apf_company->setPhone($fields[2]); $apf_company->setFax($fields[3]); $apf_company->setHomepage($fields[5]); $apf_company->setLinkMan($fields[8]); $apf_company->setMemo($fields[14]); $apf_company->setName($fields[0]); $apf_company->setAddrees($fields[1]); $apf_company->setPhone($fields[2]); $apf_company->setFax($fields[3]); $apf_company->setEmail($fields[4]); $apf_company->setHomepage($fields[5]); $apf_company->setEmployee($fields[6]);
$csv_format_column[$val['csv_format_column_number']] = $val['csv_column_id']; } } } // read uploaded file if ($action == 'save') { if (isset($_FILES['file']) && $_FILES['file']['size'] > 0) { $tempfile = DIR_FS_CATALOG . '/temp/csv_format_' . date('YmdHis'); $_SESSION['product_csv']['upfile'] = $tempfile; move_uploaded_file($_FILES['file']['tmp_name'], $tempfile); } if (is_readable($_SESSION['product_csv']['upfile'])) { $tempfile = $_SESSION['product_csv']['upfile']; $conf = File_CSV::discoverFormat($tempfile); File_CSV::getPointer($tempfile, $conf); $data = File_CSV::read($tempfile, $conf); } if ($data != false) { $hidden_fields .= zen_draw_hidden_field('csv_format_name', $csv_format_name); $disable_format_name = ' disabled="disabled"'; $name_csv_format_name = 'current_csv_format_name'; $setting_new = '<table border="1">'; $setting_new .= '<tr><th>' . FORM_FORMAT_COLUMN_HEADER1 . '</th><th>' . FORM_FORMAT_COLUMN_HEADER2 . '</th><th>' . FORM_FORMAT_COLUMN_HEADER3 . '</th></tr>'; $count = 0; foreach ($data as $val) { $count++; $setting_new .= ' <tr><td>' . sprintf(FORM_FORMAT_COLUMN_NAME, $count) . '</td><td>' . mb_convert_encoding($val, MODULE_PRODUCT_CSV_INTERNAL_CHARACTER, 'auto') . '</td><td>' . zen_draw_pull_down_menu('csv_format_column[' . $count . ']', $format_columns, isset($csv_format_column) ? $csv_format_column[$count] : $format_columns[$count - 1]['id']); } $setting_new .= '</table>'; switch ($csv_format_type_id) {
/** * 連想配列の取得 * * <pre> * PHPの連想配列を指定すればそのまま、ファイルパスを指定すれば * 設定ファイルから読み込み連想配列として渡します。 * またURLのクエリー形式も使用できます。 * BEARで広く使われています。BEARの全てのクラスのコンストラクタ * (シングルトン含む)、リソースへの引数、 * オプションにこの連想配列フォーマットが使われます。 * * array -- 連想配列としてオプションが入力されます * * string -- ファイルから拡張子によりフォーマットが異なります * URLクエリー形式 ?foo1=bar1&hoge=fugaのようなフォーマットを連想配列にします * *.ini iniフォーマット * *.xml XMLフォーマット * *.php phpのdefineが連想配列として読み込まれます * *.yml yamlファイル * * $options * 'extention' string オーバーロード拡張子 * </pre> * * @param mixed $target ターゲット ファイルパス,URLなど * @param array $options オプション * * @return array * * @see http://pear.php.net/manual/ja/package.configuration.config.php * @see BEAR/test/files/example.ini * @see BEAR/test/files/example.xml * @see BEAR/test/files/example.php * @throws BEAR_Exception */ public static function loadValues($target, $options = array()) { if (!is_file((string) $target)) { // arrayならそのまま if (is_array($target) || is_object($target)) { return (array) $target; } // false | null なら 設定な if (!$target) { return null; } // クエリーがあるときはクエリーをパースした連想配列を返す $parseUrl = parse_url($target); if (isset($parseUrl['query'])) { $options = array(); parse_str($parseUrl['query'], $options); return $options; } else { return null; } } else { $cache = self::factory('BEAR_Cache'); $cache->setLife(BEAR_Cache::LIFE_UNLIMITED); $key = $target . filemtime($target); $cacheResult = $cache->get($key); if ($cacheResult) { return $cacheResult; } // PEAR::Configを使って設定ファイルをパース $pathinfo = pathinfo($target); // 相対パスなら絶対パスに (/:linux :win) $target = substr($target, 0, 1) == '/' || substr($target, 1, 1) == ':' ? $target : _BEAR_APP_HOME . '/App/Ro/' . $target; $extension = isset($options['extention']) ? $options['extention'] : $pathinfo['extension']; switch ($extension) { case 'yml': if (function_exists('syck_load')) { $content = file_get_contents($target); $yaml = syck_load($content); } else { include_once 'BEAR/vendors/spyc-0.2.5/spyc.php'; $yaml = Spyc::YAMLLoad($target); } $cache->set($key, $yaml); return $yaml; case 'csv': $conf = File_CSV::discoverFormat($target); $csv = array(); while ($fields = File_CSV::read($target, $conf)) { array_push($csv, $fields); } $result = $cache->set($key, $csv); return $csv; case 'ini': $parse = 'inicommented'; break; case 'xml': $unserializer = new XML_Unserializer(); $unserializer->setOption('parseAttributes', true); $xml = file_get_contents($target); $unserializer->unserialize($xml); $result = $unserializer->getUnserializedData(); return $result; break; case 'php': $parse = 'PHPConstants'; break; default: return file_get_contents($target, FILE_TEXT); break; } $config = new Config(); $root =& $config->parseConfig($target, $parse); if (PEAR::isError($root)) { $msg = '設定を読み込む際のエラー: '; $msg .= $root->getMessage(); $info = array('parse' => $parse, 'input' => $target); throw new BEAR_Exception($msg, compact('info')); return false; } else { $result = $root->toArray(); return $result['root']; } } }
function import($tempfile, $csv_format_type_id, $ignore_first_line, $unlink = true) { global $ProductCSV; global $format; global $data; global $messageStack; global $line_count; global $success_count; global $error_count; global $missing_count; global $body; $format = $ProductCSV->getFormatById($csv_format_type_id); $conf = File_CSV::DiscoverFormat($tempfile); File_CSV::getPointer($tempfile, $conf); // check format if ($conf['fields'] == count($format['columns'])) { $count = 1; // skip first line if ($ignore_first_line) { File_CSV::read($tempfile, $conf); $count++; } // output table header $body = '<tr><td><table border="1">'; $body .= '<tr>'; $body .= '<th>' . PRODUCT_CSV_TABLE_LINE_NUMBER . '</th>'; foreach ($format['columns'] as $val) { $body .= '<th>' . $val['csv_column_name'] . '</th>'; } $body .= '<th>' . PRODUCT_CSV_TABLE_HEADER . '</th>'; $body .= '</tr>'; // init count $line_count = 0; $success_count = 0; $error_count = 0; $missing_count = 0; // read lines while (($data = File_CSV::read($tempfile, $conf)) !== false) { if (count($data) == 0) { continue; } echo ' '; flush(); // convert charactr set to internal encoding foreach ($data as $key => $val) { $data[$key] = mb_convert_encoding($val, MODULE_PRODUCT_CSV_INTERNAL_CHARACTER, MODULE_PRODUCT_CSV_IMPORT_CHARACTER); } $ProductCSV->messageStack->reset(); switch ($format['csv_format_type_id']) { case 1: $import_status = $ProductCSV->importProduct($data, $format); break; case 2: $format = zen_add_number_to_format($format); $import_status = $ProductCSV->importCategory($data, $format); break; case 3: $import_status = $ProductCSV->importOption($data, $format); break; } // store success/error/line count $line_count++; if ($import_status === true) { $success_count++; } elseif ($import_status === false) { $error_count++; } else { $missing_count++; } $body .= '<tr>'; $body .= '<td>' . $count++ . '</td>'; foreach ($data as $val) { if ($val == '') { $val = ' '; } $body .= '<td>' . $val . '</td>'; } $body .= '<td>' . $ProductCSV->messageStack->output() . '</td>'; $body .= '</tr>'; } $body .= '</table></td></tr>'; $messageStack->add(sprintf(PRODUCT_CSV_MESSAGE_IMPORT_STATUS, $line_count, $success_count, $error_count), 'success'); if ($unlink) { unlink($tempfile); } } else { $messageStack->add(PRODUCT_CSV_ERROR_INVALID_FORMAT, 'caution'); } }
$categories_products_id_list = array(); $products_ids = zen_get_categories_products_list($_POST['category_id'], true, true); $products_ids = array_unique($products_ids); // write line foreach ($products_ids as $val) { $attributes_ids = zen_get_attributes($val); foreach ($attributes_ids as $id) { $data = $ProductCSV->getExportDataOption($id, $format); if (count($data) == 0) { continue; } foreach ($data as $key => $d) { $data[$key] = mb_convert_encoding($d, MODULE_PRODUCT_CSV_EXPORT_CHARACTER, MODULE_PRODUCT_CSV_INTERNAL_CHARACTER); $data[$key] = str_replace("\r\n", "\n", $data[$key]); } File_CSV::write($tempfile, $data, $conf); } } break; } // output and delete tempfile if ($request_type == 'NONSSL') { header("Pragma: no-cache"); } else { header("Pragma: "); } header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $prefix . date('YmdHis') . '.csv"'); header('Content-Length: ' . filesize($tempfile)); ob_end_clean(); readfile($tempfile);
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } require_once 'pear/File.php'; require_once 'pear/File/CSV.php'; // Don't be tempted to use 'explode' here. There may be > 1 underscore. $break = strpos($values['authinstance'], '_'); $authinstance = substr($values['authinstance'], 0, $break); $institution = substr($values['authinstance'], $break + 1); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $usernames = array(); $emails = array(); $conf = File_CSV::discoverFormat($values['file']['tmp_name']); $i = 0; while ($line = File_CSV::readQuoted($values['file']['tmp_name'], $conf)) { $i++; if (!is_array($line)) { // Note: the CSV parser returns true on some errors and false on // others! Yes that's retarded. No I didn't write it :( $form->set_error('file', get_string('uploadcsverrorincorrectnumberoffields', 'admin', $i)); return; } // Get the format of the file if ($i == 1) { foreach ($line as &$potentialkey) { $potentialkey = trim($potentialkey); if (!in_array($potentialkey, $ALLOWEDKEYS)) { $form->set_error('file', get_string('uploadcsverrorinvalidfieldname', 'admin', $potentialkey)); return; } } // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'password'); $mandatoryfields = array_merge($mandatoryfields, array_keys(ArtefactTypeProfile::get_mandatory_fields())); if ($lockedprofilefields = get_column('institution_locked_profile_field', 'profilefield', 'name', $institution)) { $mandatoryfields = array_merge($mandatoryfields, $lockedprofilefields); } // Add in the locked profile fields for this institution foreach ($mandatoryfields as $field) { if (!in_array($field, $line)) { $form->set_error('file', get_string('uploadcsverrorrequiredfieldnotspecified', 'admin', $field)); return; } } // The format line is valid $FORMAT = $line; log_info('FORMAT:'); log_info($FORMAT); } else { // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $formatkeylookup = array_flip($FORMAT); $username = $line[$formatkeylookup['username']]; $password = $line[$formatkeylookup['password']]; $email = $line[$formatkeylookup['email']]; $authobj = AuthFactory::create($authinstance); if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('file', get_string('uploadcsverrorinvalidusername', 'admin', $i)); return; } if (record_exists_select('usr', 'LOWER(username) = ?', strtolower($username)) || isset($usernames[strtolower($username)])) { $form->set_error('file', get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username)); return; } if (record_exists('usr', 'email', $email) || isset($emails[$email])) { $form->set_error('file', get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email)); } // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('file', get_string('uploadcsverrorinvalidpassword', 'admin', $i)); return; } $usernames[strtolower($username)] = 1; $emails[$email] = 1; // All OK! $CSVDATA[] = $line; } } if ($i == 1) { // There was only the title row :( $form->set_error('file', get_string('uploadcsverrornorecords', 'admin')); return; } if ($CSVDATA === null) { // Oops! Couldn't get CSV data for some reason $form->set_error('file', get_string('uploadcsverrorunspecifiedproblem', 'admin')); } }
/** * Writes a struc (array) in a file as CSV * * @param string $file The filename where to write the data * @param array $fields Ordered array with the data * @param array &$conf The configuration of the dest CSV * * @return bool True on success false otherwise */ function append($fields, &$conf) { if (count($fields) != $conf['fields']) { File_CSV::raiseError("Wrong fields number count: '" . count($fields) . "' expected " . $conf['fields']); return true; } $write = ''; for ($i = 0; $i < count($fields); $i++) { if (!is_numeric($fields[$i]) && $conf['quote']) { $write .= $conf['quote'] . $fields[$i] . $conf['quote']; } else { $write .= $fields[$i]; } if ($i < count($fields) - 1) { $write .= $conf['sep']; } else { $write .= $conf['crlf']; } } $this->filedata .= $write; }
<?php $path = ini_get('include_path'); ini_set('include_path', realpath('../') . ":{$path}"); require_once 'File/CSV.php'; /*/Example conf: $conf = array( 'fields' => 4, 'sep' => "\t", 'quote' => '"', 'header' => false ); //*/ ob_implicit_flush(true); $argv = $_SERVER['argv']; $file = $argv[1]; $write = isset($argv[2]) ? $argv[2] : false; PEAR::setErrorHandling(PEAR_ERROR_PRINT, "warning: %s\n"); $conf = File_CSV::discoverFormat($file); while ($fields = File_CSV::read($file, $conf)) { if ($write) { File_CSV::write($write, $fields, $conf); } print_r($fields); } var_dump($conf); echo "\n";
<?php /** * var_export(get_class_methods('File_CSV')); * * array ( * 0 => 'raiseError', * 1 => '_conf', * 2 => 'getPointer', * 3 => 'unquote', * 4 => 'readQuoted', * 5 => 'read', * 6 => '_dbgBuff', * 7 => 'write', * 8 => 'discoverFormat', * 9 => 'resetPointer', * ) */ require_once 'File/CSV.php'; $csv = new File_CSV(); $file = 'tests/data/symmetric.csv'; $conf = $csv->discoverFormat($file); foreach (range(0, (int) $conf['fields']) as $iteration) { if ($iteration == 0) { $x = $csv->read($file, $conf); var_export($x); } // rows }
function exportCSV() { global $i18n, $ClassDir; require_once 'File/CSV.php'; require_once $ClassDir . 'StringHelper.class.php'; $header = array("name", "gender", "birthday", "mobile", "phone", "office_phone", "fax", "addrees", "category", "email", "homepage"); $conf = array('fields' => count($header), 'sep' => ";", 'quote' => '"', 'header' => false, 'crlf' => "\r\n"); $filename = date("Y_m_d") . "_contact_export.csv"; $csv = new File_CSV(); // Write contact record $apf_contact = DB_DataObject::factory('ApfContact'); $apf_contact->orderBy('id desc'); $apf_contact->find(); while ($apf_contact->fetch()) { $row_data = array(); foreach ($header as $title) { $coloum_function = "get" . StringHelper::CamelCaseFromUnderscore($title); $row_data[] = $apf_contact->{$coloum_function}(); } $csv->append($row_data, $conf); } $csv->send($filename); exit; }