[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/ -> csvlib.class.php (source)

   1  <?php
   2  /*
   3   * General csv import library.
   4   * @author Petr Skoda
   5   * @version $Id: csvlib.class.php,v 1.1.2.2 2007/11/05 00:49:29 skodak Exp $
   6   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
   7   * @package moodlecore
   8   */
   9  
  10  /**
  11   * Utitily class for importing of CSV files.
  12   */
  13  class csv_import_reader {
  14      var $_iid;
  15      var $_type;
  16      var $_error;
  17      var $_columns; //cached columns
  18      var $_fp;
  19  
  20      /**
  21       * Contructor
  22       * @param int $iid import identifier
  23       * @param string $type which script imports?
  24       */
  25      function csv_import_reader($iid, $type) {
  26          $this->_iid  = $iid;
  27          $this->_type = $type;
  28      }
  29  
  30      /**
  31       * Parse this content
  32       * @param string &$content passed by ref for memory reasons, unset after return
  33       * @param string $encoding content encoding
  34       * @param string $delimiter_name separator (comma, semicolon, colon, cfg)
  35       * @param string $column_validation name of function for columns validation, must have one param $columns
  36       * @return false if error, count of data lines if ok; use get_error() to get error string
  37       */
  38      function load_csv_content(&$content, $encoding, $delimiter_name, $column_validation=null) {
  39          global $USER, $CFG;
  40  
  41          $this->close();
  42          $this->_error = null;
  43  
  44          $textlib = textlib_get_instance();
  45  
  46          $content = $textlib->convert($content, $encoding, 'utf-8');
  47          // remove Unicode BOM from first line
  48          $content = $textlib->trim_utf8_bom($content);
  49          // Fix mac/dos newlines
  50          $content = preg_replace('!\r\n?!', "\n", $content);
  51          // is there anyting in file?
  52          $columns = strtok($content, "\n");
  53          if ($columns === false) {
  54              $this->_error = get_string('csvemptyfile', 'error');
  55              return false;
  56          }
  57          $csv_delimiter = csv_import_reader::get_delimiter($delimiter_name);
  58          $csv_encode    = csv_import_reader::get_encoded_delimiter($delimiter_name);
  59  
  60          // process header - list of columns
  61          $columns   = explode($csv_delimiter, $columns);
  62          $col_count = count($columns);
  63          if ($col_count === 0) {
  64              $this->_error = get_string('csvemptyfile', 'error');
  65              return false;
  66          }
  67  
  68          foreach ($columns as $key=>$value) {
  69              $columns[$key] = str_replace($csv_encode, $csv_delimiter, trim($value));
  70          }
  71          if ($column_validation) {
  72              $result = $column_validation($columns);
  73              if ($result !== true) {
  74                  $this->_error = $result;
  75                  return false;
  76              }
  77          }
  78          $this->_columns = $columns; // cached columns
  79  
  80          // open file for writing
  81          $filename = $CFG->dataroot.'/temp/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid;
  82          $fp = fopen($filename, "w");
  83          fwrite($fp, serialize($columns)."\n");
  84  
  85          // again - do we have any data for processing?
  86          $line = strtok("\n");
  87          $data_count = 0;
  88          while ($line !== false) {
  89              $line = explode($csv_delimiter, $line);
  90              foreach ($line as $key=>$value) {
  91                  $line[$key] = str_replace($csv_encode, $csv_delimiter, trim($value));
  92              }
  93              if (count($line) !== $col_count) {
  94                  // this is critical!!
  95                  $this->_error = get_string('csvweirdcolumns', 'error');
  96                  fclose($fp);
  97                  $this->cleanup();
  98                  return false;
  99              }
 100              fwrite($fp, serialize($line)."\n");
 101              $data_count++;
 102              $line = strtok("\n");
 103          }
 104  
 105          fclose($fp);
 106          return $data_count;
 107      }
 108  
 109      /**
 110       * Returns list of columns
 111       * @return array
 112       */
 113      function get_columns() {
 114          if (isset($this->_columns)) {
 115              return $this->_columns;
 116          }
 117  
 118          global $USER, $CFG;
 119  
 120          $filename = $CFG->dataroot.'/temp/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid;
 121          if (!file_exists($filename)) {
 122              return false;
 123          }
 124          $fp = fopen($filename, "r");
 125          $line = fgets($fp);
 126          fclose($fp);
 127          if ($line === false) {
 128              return false;
 129          }
 130          $this->_columns = unserialize($line);
 131          return $this->_columns;
 132      }
 133  
 134      /**
 135       * Init iterator.
 136       */
 137      function init() {
 138          global $CFG, $USER;
 139  
 140          if (!empty($this->_fp)) {
 141              $this->close();
 142          }
 143          $filename = $CFG->dataroot.'/temp/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid;
 144          if (!file_exists($filename)) {
 145              return false;
 146          }
 147          if (!$this->_fp = fopen($filename, "r")) {
 148              return false;
 149          }
 150          //skip header
 151          return (fgets($this->_fp) !== false);
 152      }
 153  
 154      /**
 155       * Get next line
 156       * @return array of values
 157       */
 158      function next() {
 159          if (empty($this->_fp) or feof($this->_fp)) {
 160              return false;
 161          }
 162          if ($ser = fgets($this->_fp)) {
 163              return unserialize($ser);
 164          } else {
 165              return false;
 166          }
 167      }
 168  
 169      /**
 170       * Release iteration related resources
 171       */
 172      function close() {
 173          if (!empty($this->_fp)) {
 174              fclose($this->_fp);
 175              $this->_fp = null;
 176          }
 177      }
 178  
 179      /**
 180       * Get last error
 181       * @return string error text of null if none
 182       */
 183      function get_error() {
 184          return $this->_error;
 185      }
 186  
 187      /**
 188       * Cleanup temporary data
 189       * @static if $full=true
 190       * @param boolean true menasdo a full cleanup - all sessions for current user, false only the active iid
 191       */
 192      function cleanup($full=false) {
 193          global $USER, $CFG;
 194  
 195          if ($full) {
 196              @remove_dir($CFG->dataroot.'/temp/csvimport/'.$this->_type.'/'.$USER->id);
 197          } else {
 198              @unlink($CFG->dataroot.'/temp/csvimport/'.$this->_type.'/'.$USER->id.'/'.$this->_iid);
 199          }
 200      }
 201  
 202      /**
 203       * Get list of cvs delimiters
 204       * @static
 205       * @return array suitable for selection box
 206       */
 207      function get_delimiter_list() {
 208          $delimiters = array('comma'=>',', 'semicolon'=>';', 'colon'=>':', 'tab'=>'\\t');
 209          if (isset($CFG->CSV_DELIMITER) and strlen($CFG->CSV_DELIMITER) === 1 and !in_array($CFG->CSV_DELIMITER, $delimiters)) {
 210              $delimiters['cfg'] = $CFG->CSV_DELIMITER;
 211          }
 212          return $delimiters;
 213      }
 214  
 215      /**
 216       * Get delimiter character
 217       * @static
 218       * @param string separator name
 219       * @return char delimiter char
 220       */
 221      function get_delimiter($delimiter_name) {
 222          switch ($delimiter_name) {
 223              case 'colon':     return ':';
 224              case 'semicolon': return ';';
 225              case 'tab':       return "\t";
 226              case 'cfg':       if (isset($CFG->CSV_DELIMITER)) { return $CFG->CSV_DELIMITER; } // no break; fall back to comma
 227              case 'comma':     return ',';
 228          }
 229      }
 230  
 231      /**
 232       * Get encoded delimiter character
 233       * @static
 234       * @param string separator name
 235       * @return char encoded delimiter char
 236       */
 237      function get_encoded_delimiter($delimiter_name) {
 238          global $CFG;
 239          if ($delimiter_name == 'cfg' and isset($CFG->CSV_ENCODE)) {
 240              return $CFG->CSV_ENCODE;
 241          }
 242          $delimiter = csv_import_reader::get_delimiter($delimiter_name);
 243          return '&#'.ord($delimiter);
 244      }
 245  
 246      /**
 247       * Create new import id
 248       * @static
 249       * @param string who imports?
 250       * @return int iid
 251       */
 252      function get_new_iid($type) {
 253          global $USER;
 254  
 255          if (!$filename = make_upload_directory('temp/csvimport/'.$type.'/'.$USER->id, false)) {
 256              error('Can not create temporary upload directory - verify moodledata permissions!');
 257          }
 258  
 259          // use current (non-conflicting) time stamp
 260          $iiid = time();
 261          while (file_exists($filename.'/'.$iiid)) {
 262              $iiid--;
 263          }
 264  
 265          return $iiid;
 266      }
 267  }
 268  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7