|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00029 defined('MOODLE_INTERNAL') || die(); 00030 00037 class csv_import_reader { 00041 var $_iid; 00045 var $_type; 00049 var $_error; 00053 var $_columns; 00057 var $_fp; 00058 00065 function csv_import_reader($iid, $type) { 00066 $this->_iid = $iid; 00067 $this->_type = $type; 00068 } 00069 00081 function load_csv_content(&$content, $encoding, $delimiter_name, $column_validation=null) { 00082 global $USER, $CFG; 00083 00084 $this->close(); 00085 $this->_error = null; 00086 00087 $textlib = textlib_get_instance(); 00088 00089 $content = $textlib->convert($content, $encoding, 'utf-8'); 00090 // remove Unicode BOM from first line 00091 $content = $textlib->trim_utf8_bom($content); 00092 // Fix mac/dos newlines 00093 $content = preg_replace('!\r\n?!', "\n", $content); 00094 // is there anyting in file? 00095 $columns = strtok($content, "\n"); 00096 if ($columns === false) { 00097 $this->_error = get_string('csvemptyfile', 'error'); 00098 return false; 00099 } 00100 $csv_delimiter = csv_import_reader::get_delimiter($delimiter_name); 00101 $csv_encode = csv_import_reader::get_encoded_delimiter($delimiter_name); 00102 00103 // process header - list of columns 00104 $columns = explode($csv_delimiter, $columns); 00105 $col_count = count($columns); 00106 if ($col_count === 0) { 00107 $this->_error = get_string('csvemptyfile', 'error'); 00108 return false; 00109 } 00110 00111 foreach ($columns as $key=>$value) { 00112 $columns[$key] = str_replace($csv_encode, $csv_delimiter, trim($value)); 00113 } 00114 if ($column_validation) { 00115 $result = $column_validation($columns); 00116 if ($result !== true) { 00117 $this->_error = $result; 00118 return false; 00119 } 00120 } 00121 $this->_columns = $columns; // cached columns 00122 00123 // open file for writing 00124 $filename = $CFG->tempdir.'/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid; 00125 $fp = fopen($filename, "w"); 00126 fwrite($fp, serialize($columns)."\n"); 00127 00128 // again - do we have any data for processing? 00129 $line = strtok("\n"); 00130 $data_count = 0; 00131 while ($line !== false) { 00132 $line = explode($csv_delimiter, $line); 00133 foreach ($line as $key=>$value) { 00134 $line[$key] = str_replace($csv_encode, $csv_delimiter, trim($value)); 00135 } 00136 if (count($line) !== $col_count) { 00137 // this is critical!! 00138 $this->_error = get_string('csvweirdcolumns', 'error'); 00139 fclose($fp); 00140 $this->cleanup(); 00141 return false; 00142 } 00143 fwrite($fp, serialize($line)."\n"); 00144 $data_count++; 00145 $line = strtok("\n"); 00146 } 00147 00148 fclose($fp); 00149 return $data_count; 00150 } 00151 00157 function get_columns() { 00158 if (isset($this->_columns)) { 00159 return $this->_columns; 00160 } 00161 00162 global $USER, $CFG; 00163 00164 $filename = $CFG->tempdir.'/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid; 00165 if (!file_exists($filename)) { 00166 return false; 00167 } 00168 $fp = fopen($filename, "r"); 00169 $line = fgets($fp); 00170 fclose($fp); 00171 if ($line === false) { 00172 return false; 00173 } 00174 $this->_columns = unserialize($line); 00175 return $this->_columns; 00176 } 00177 00185 function init() { 00186 global $CFG, $USER; 00187 00188 if (!empty($this->_fp)) { 00189 $this->close(); 00190 } 00191 $filename = $CFG->tempdir.'/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid; 00192 if (!file_exists($filename)) { 00193 return false; 00194 } 00195 if (!$this->_fp = fopen($filename, "r")) { 00196 return false; 00197 } 00198 //skip header 00199 return (fgets($this->_fp) !== false); 00200 } 00201 00207 function next() { 00208 if (empty($this->_fp) or feof($this->_fp)) { 00209 return false; 00210 } 00211 if ($ser = fgets($this->_fp)) { 00212 return unserialize($ser); 00213 } else { 00214 return false; 00215 } 00216 } 00217 00223 function close() { 00224 if (!empty($this->_fp)) { 00225 fclose($this->_fp); 00226 $this->_fp = null; 00227 } 00228 } 00229 00235 function get_error() { 00236 return $this->_error; 00237 } 00238 00246 function cleanup($full=false) { 00247 global $USER, $CFG; 00248 00249 if ($full) { 00250 @remove_dir($CFG->tempdir.'/csvimport/'.$this->_type.'/'.$USER->id); 00251 } else { 00252 @unlink($CFG->tempdir.'/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid); 00253 } 00254 } 00255 00261 static function get_delimiter_list() { 00262 global $CFG; 00263 $delimiters = array('comma'=>',', 'semicolon'=>';', 'colon'=>':', 'tab'=>'\\t'); 00264 if (isset($CFG->CSV_DELIMITER) and strlen($CFG->CSV_DELIMITER) === 1 and !in_array($CFG->CSV_DELIMITER, $delimiters)) { 00265 $delimiters['cfg'] = $CFG->CSV_DELIMITER; 00266 } 00267 return $delimiters; 00268 } 00269 00276 static function get_delimiter($delimiter_name) { 00277 global $CFG; 00278 switch ($delimiter_name) { 00279 case 'colon': return ':'; 00280 case 'semicolon': return ';'; 00281 case 'tab': return "\t"; 00282 case 'cfg': if (isset($CFG->CSV_DELIMITER)) { return $CFG->CSV_DELIMITER; } // no break; fall back to comma 00283 case 'comma': return ','; 00284 } 00285 } 00286 00294 function get_encoded_delimiter($delimiter_name) { 00295 global $CFG; 00296 if ($delimiter_name == 'cfg' and isset($CFG->CSV_ENCODE)) { 00297 return $CFG->CSV_ENCODE; 00298 } 00299 $delimiter = csv_import_reader::get_delimiter($delimiter_name); 00300 return '&#'.ord($delimiter); 00301 } 00302 00310 function get_new_iid($type) { 00311 global $USER; 00312 00313 $filename = make_temp_directory('csvimport/'.$type.'/'.$USER->id); 00314 00315 // use current (non-conflicting) time stamp 00316 $iiid = time(); 00317 while (file_exists($filename.'/'.$iiid)) { 00318 $iiid--; 00319 } 00320 00321 return $iiid; 00322 } 00323 }