You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
cosmopet.ae/wp-content/plugins copy/wp-all-import/libraries/XmlImportCsvParse.php

1231 lines
34 KiB

<?php
class PMXI_CsvParser
{
public
/**
* csv parsing default-settings
*
* @var array
* @access public
*/
$settings = array(
'delimiter' => ",",
'eol' => '',
'length' => 999999,
'enclosure' => '"',
'escape' => "\\",
),
$tmp_files = array(),
$xpath = '',
$delimiter = '',
$htmlentities = false,
$xml_path = '',
$iteration = 0,
$csv_encoding = 'UTF-8',
$is_csv = false,
$targetDir = '',
$auto_encoding = true;
protected
/**
* imported data from csv
*
* @var array
* @access protected
*/
$rows = array(),
/**
* csv file to parse
*
* @var string
* @access protected
*/
$_filename = '',
/**
* csv headers to parse
*
* @var array
* @access protected
*/
$headers = array();
/**
* data load initialize
*
* @param mixed $filename please look at the load() method
*
* @access public
* @see load()
* @return void
*/
public function __construct( $options = array('filename' => null, 'xpath' => '', 'delimiter' => '', 'encoding' => '', 'xml_path' => '', 'targetDir' => false) ) {
PMXI_Plugin::$csv_path = $options['filename'];
$this->xpath = (!empty($options['xpath']) ? $options['xpath'] : ((!empty($_POST['xpath'])) ? sanitize_text_field($_POST['xpath']) : '/node'));
if ( ! empty($options['delimiter']) ){
$this->delimiter = $options['delimiter'];
} else {
$input = new PMXI_Input();
$id = $input->get('id', 0);
if (!$id){
$id = $input->get('import_id', 0);
}
if ( $id ){
$import = new PMXI_Import_Record();
$import->getbyId($id);
if ( ! $import->isEmpty() ){
$this->delimiter = empty($import->options['delimiter']) ? '' : $import->options['delimiter'];
}
}
}
if ( ! empty($options['encoding'])){
$this->csv_encoding = $options['encoding'];
$this->auto_encoding = false;
}
if (!empty($options['xml_path'])) $this->xml_path = $options['xml_path'];
@ini_set( "display_errors", 0);
@ini_set('auto_detect_line_endings', true);
$file_params = self::analyse_file($options['filename'], 1);
$this->set_settings(array('delimiter' => $file_params['delimiter']['value'], 'eol' => $file_params['line_ending']['value']));
unset($file_params);
$wp_uploads = wp_upload_dir();
$this->targetDir = (empty($options['targetDir'])) ? wp_all_import_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::UPLOADS_DIRECTORY) : $options['targetDir'];
$this->load($options['filename']);
}
/**
* csv file loader
*
* indicates the object which file is to be loaded
*
*
* @param string $filename the csv filename to load
*
* @access public
* @return boolean true if file was loaded successfully
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
*/
public function load($filename)
{
$this->_filename = $filename;
$this->flush();
return $this->parse();
}
/**
* settings alterator
*
* lets you define different settings for scanning
*
*
* @param mixed $array containing settings to use
*
* @access public
* @return boolean true if changes where applyed successfully
* @see $settings
*/
public function set_settings($array)
{
$this->settings = apply_filters('wp_all_import_csv_parser_settings', array_merge($this->settings, $array));
}
/**
* header fetcher
*
* gets csv headers into an array
*
* @access public
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* header counter
*
* retrives the total number of loaded headers
*
* @access public
* @return integer gets the length of headers
*/
public function countHeaders()
{
return count($this->headers);
}
/**
* header and row relationship builder
*
* Attempts to create a relationship for every single cell that
* was captured and its corresponding header. The sample below shows
* how a connection/relationship is built.
*
* @param array $columns the columns to connect, if nothing
* is given all headers will be used to create a connection
*
* @access public
* @return array If the data is not symmetric an empty array
* will be returned instead
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), getHeaders()
*/
public function connect($columns = array())
{
if (!$this->isSymmetric()) {
return array();
}
if (!is_array($columns)) {
return array();
}
if ($columns === array()) {
$columns = $this->headers;
}
$ret_arr = array();
foreach ($this->rows as $record) {
$item_array = array();
foreach ($record as $column => $value) {
$header = $this->headers[$column];
if (in_array($header, $columns)) {
$item_array[$header] = $value;
}
}
// do not append empty results
if ($item_array !== array()) {
array_push($ret_arr, $item_array);
}
}
return $ret_arr;
}
/**
* data length/symmetry checker
*
* tells if the headers and all of the contents length match.
* Note: there is a lot of methods that won't work if data is not
* symmetric this method is very important!
*
* @access public
* @return boolean
* @see symmetrize(), getAsymmetricRows(), isSymmetric()
*/
public function isSymmetric()
{
$hc = count($this->headers);
foreach ($this->rows as $row) {
if (count($row) != $hc) {
return false;
}
}
return true;
}
/**
* asymmetric data fetcher
*
* finds the rows that do not match the headers length
*
* lets assume that we add one more row to our csv file.
* that has only two values. Something like
*
* @access public
* @return array filled with rows that do not match headers
* @see getHeaders(), symmetrize(), isSymmetric(),
* getAsymmetricRows()
*/
public function getAsymmetricRows()
{
$ret_arr = array();
$hc = count($this->headers);
foreach ($this->rows as $row) {
if (count($row) != $hc) {
$ret_arr[] = $row;
}
}
return $ret_arr;
}
/**
* all rows length equalizer
*
* makes the length of all rows and headers the same. If no $value is given
* all unexistent cells will be filled with empty spaces
*
* @param mixed $value the value to fill the unexistent cells
*
* @access public
* @return array
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
*/
public function symmetrize($value = '')
{
$max_length = 0;
$headers_length = count($this->headers);
foreach ($this->rows as $row) {
$row_length = count($row);
if ($max_length < $row_length) {
$max_length = $row_length;
}
}
if ($max_length < $headers_length) {
$max_length = $headers_length;
}
foreach ($this->rows as $key => $row) {
$this->rows[$key] = array_pad($row, $max_length, $value);
}
$this->headers = array_pad($this->headers, $max_length, $value);
}
/**
* grid walker
*
* travels through the whole dataset executing a callback per each
* cell
*
* Note: callback functions get the value of the cell as an
* argument, and whatever that callback returns will be used to
* replace the current value of that cell.
*
* @param string $callback the callback function to be called per
* each cell in the dataset.
*
* @access public
* @return bool
* @see walkColumn(), walkRow(), fillColumn(), fillRow(), fillCell()
*/
public function walkGrid($callback)
{
foreach (array_keys($this->getRows()) as $key) {
if (!$this->walkRow($key, $callback)) {
return false;
}
}
return true;
}
/**
* column fetcher
*
* gets all the data for a specific column identified by $name
*
* Note $name is the same as the items returned by getHeaders()
*
* @param string $name the name of the column to fetch
*
* @access public
* @return array filled with values of a column
* @see getHeaders(), fillColumn(), appendColumn(), getCell(), getRows(),
* getRow(), hasColumn()
*/
public function getColumn($name)
{
if (!in_array($name, $this->headers)) {
return array();
}
$ret_arr = array();
$key = array_search($name, $this->headers, true);
foreach ($this->rows as $data) {
$ret_arr[] = $data[$key];
}
return $ret_arr;
}
/**
* column existance checker
*
* checks if a column exists, columns are identified by their
* header name.
*
* @param string $string an item returned by getHeaders()
*
* @access public
* @return boolean
* @see getHeaders()
*/
public function hasColumn($string)
{
return in_array($string, $this->headers);
}
/**
* column appender
*
* Appends a column and each or all values in it can be
*
* @param string $column an item returned by getHeaders()
* @param mixed $values same as fillColumn()
*
* @access public
* @return boolean
* @see getHeaders(), fillColumn(), fillCell(), createHeaders(),
* setHeaders()
*/
public function appendColumn($column, $values = null)
{
if ($this->hasColumn($column)) {
return false;
}
$this->headers[] = $column;
$length = $this->countHeaders();
$rows = array();
foreach ($this->rows as $row) {
$rows[] = array_pad($row, $length, '');
}
$this->rows = $rows;
if ($values === null) {
$values = '';
}
return $this->fillColumn($column, $values);
}
/**
* collumn data injector
*
* fills alll the data in the given column with $values
*
* @param mixed $column the column identified by a string
* @param mixed $values ither one of the following
* - (Number) will fill the whole column with the value of number
* - (String) will fill the whole column with the value of string
* - (Array) will fill the while column with the values of array
* the array gets ignored if it does not match the length of rows
*
* @access public
* @return bool
*/
public function fillColumn($column, $values = null)
{
if (!$this->hasColumn($column)) {
return false;
}
if ($values === null) {
return false;
}
if (!$this->isSymmetric()) {
return false;
}
$y = array_search($column, $this->headers);
if (is_numeric($values) || is_string($values)) {
foreach (range(0, $this->countRows() -1) as $x) {
$this->fillCell($x, $y, $values);
}
return true;
}
if ($values === array()) {
return false;
}
$length = $this->countRows();
if (is_array($values) && $length == count($values)) {
for ($x = 0; $x < $length; $x++) {
$this->fillCell($x, $y, $values[$x]);
}
return true;
}
return false;
}
/**
* column remover
*
* Completly removes a whole column identified by $name
*
* @param string $name same as the ones returned by getHeaders();
*
* @access public
* @return boolean
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
* isSymmetric(), getAsymmetricRows()
*/
public function removeColumn($name)
{
if (!in_array($name, $this->headers)) {
return false;
}
if (!$this->isSymmetric()) {
return false;
}
$key = array_search($name, $this->headers);
unset($this->headers[$key]);
$this->resetKeys($this->headers);
foreach ($this->rows as $target => $row) {
unset($this->rows[$target][$key]);
$this->resetKeys($this->rows[$target]);
}
return $this->isSymmetric();
}
/**
* column walker
*
* goes through the whole column and executes a callback for each
* one of the cells in it.
*
* Note: callback functions get the value of the cell as an
* argument, and whatever that callback returns will be used to
* replace the current value of that cell.
*
* @param string $name the header name used to identify the column
* @param string $callback the callback function to be called per
* each cell value
*
* @access public
* @return boolean
* @see getHeaders(), fillColumn(), appendColumn()
*/
public function walkColumn($name, $callback)
{
if (!$this->isSymmetric()) {
return false;
}
if (!$this->hasColumn($name)) {
return false;
}
if (!function_exists($callback)) {
return false;
}
$column = $this->getColumn($name);
foreach ($column as $key => $cell) {
$column[$key] = $callback($cell);
}
return $this->fillColumn($name, $column);
}
/**
* cell fetcher
*
* gets the value of a specific cell by given coordinates
*
* @param integer $x the row to fetch
* @param integer $y the column to fetch
*
* @access public
* @return mixed|false the value of the cell or false if the cell does
* not exist
* @see getHeaders(), hasCell(), getRow(), getRows(), getColumn()
*/
public function getCell($x, $y)
{
if ($this->hasCell($x, $y)) {
$row = $this->getRow($x);
return $row[$y];
}
return false;
}
/**
* cell value filler
*
* replaces the value of a specific cell
*
* @param integer $x the row to fetch
* @param integer $y the column to fetch
* @param mixed $value the value to fill the cell with
*
* @access public
* @return boolean
* @see hasCell(), getRow(), getRows(), getColumn()
*/
public function fillCell($x, $y, $value)
{
if (!$this->hasCell($x, $y)) {
return false;
}
$row = $this->getRow($x);
$row[$y] = $value;
$this->rows[$x] = $row;
return true;
}
/**
* checks if a coordinate is valid
*
* @param mixed $x the row to fetch
* @param mixed $y the column to fetch
*
* @access public
* @return bool
*/
public function hasCell($x, $y)
{
$has_x = array_key_exists($x, $this->rows);
$has_y = array_key_exists($y, $this->headers);
return ($has_x && $has_y);
}
/**
* row fetcher
*
* Note: first row is zero
*
* @param integer $number the row number to fetch
*
* @access public
* @return array the row identified by number, if $number does
* not exist an empty array is returned instead
*/
public function getRow($number)
{
$raw = $this->rows;
if (array_key_exists($number, $raw)) {
return $raw[$number];
}
return array();
}
/**
* multiple row fetcher
*
* Extracts a rows in the following fashion
* - all rows if no $range argument is given
* - a range of rows identified by their key
* - if rows in range are not found nothing is retrived instead
* - if no rows were found an empty array is returned
*
* @param array $range a list of rows to retrive
*
* @access public
* @return array
*/
public function getRows($range = array())
{
if (is_array($range) && ($range === array())) {
return $this->rows;
}
if (!is_array($range)) {
return $this->rows;
}
$ret_arr = array();
foreach ($this->rows as $key => $row) {
if (in_array($key, $range)) {
$ret_arr[] = $row;
}
}
return $ret_arr;
}
/**
* row counter
*
* This function will exclude the headers
*
* @access public
* @return integer
*/
public function countRows()
{
return count($this->rows);
}
/**
* row appender
*
* Aggregates one more row to the currently loaded dataset
*
* @param array $values the values to be appended to the row
*
* @access public
* @return boolean
*/
public function appendRow($values)
{
$this->rows[] = array();
$this->symmetrize();
return $this->fillRow($this->countRows() - 1, $values);
}
/**
* fillRow
*
* Replaces the contents of cells in one given row with $values.
*
* @param integer $row the row to fill identified by its key
* @param mixed $values the value to use, if a string or number
* is given the whole row will be replaced with this value.
* if an array is given instead the values will be used to fill
* the row. Only when the currently loaded dataset is symmetric
*
* @access public
* @return boolean
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), fillColumn(),
* fillCell(), appendRow()
*/
public function fillRow($row, $values)
{
if (!$this->hasRow($row)) {
return false;
}
if (is_string($values) || is_numeric($values)) {
foreach ($this->rows[$row] as $key => $cell) {
$this->rows[$row][$key] = $values;
}
return true;
}
$eql_to_headers = ($this->countHeaders() == count($values));
if (is_array($values) && $this->isSymmetric() && $eql_to_headers) {
$this->rows[$row] = $values;
return true;
}
return false;
}
/**
* row existance checker
*
* Scans currently loaded dataset and
* checks if a given row identified by $number exists
*
* @param mixed $number a numeric value that identifies the row
* you are trying to fetch.
*
* @access public
* @return boolean
* @see getRow(), getRows(), appendRow(), fillRow()
*/
public function hasRow($number)
{
return (in_array($number, array_keys($this->rows)));
}
/**
* row remover
*
* removes one row from the current data set.
*
*
* @param mixed $number the key that identifies that row
*
* @access public
* @return boolean
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
* isSymmetric(), getAsymmetricRows()
*/
public function removeRow($number)
{
$cnt = $this->countRows();
$row = $this->getRow($number);
if (is_array($row) && ($row != array())) {
unset($this->rows[$number]);
} else {
return false;
}
$this->resetKeys($this->rows);
return ($cnt == ($this->countRows() + 1));
}
/**
* row walker
*
* goes through one full row of data and executes a callback
* function per each cell in that row.
*
* Note: callback functions get the value of the cell as an
* argument, and whatever that callback returns will be used to
* replace the current value of that cell.
*
* @param string|integer $row anything that is numeric is a valid row
* identificator. As long as it is within the range of the currently
* loaded dataset
*
* @param string $callback the callback function to be executed
* per each cell in a row
*
* @access public
* @return boolean
* - false if callback does not exist
* - false if row does not exits
*/
public function walkRow($row, $callback)
{
if (!function_exists($callback)) {
return false;
}
if ($this->hasRow($row)) {
foreach ($this->getRow($row) as $key => $value) {
$this->rows[$row][$key] = $callback($value);
}
return true;
}
return false;
}
/**
* raw data as array
*
* Gets the data that was retrived from the csv file as an array
*
* Note: that changes and alterations made to rows, columns and
* values will also reflect on what this function retrives.
*
* @access public
* @return array
* @see connect(), getHeaders(), getRows(), isSymmetric(), getAsymmetricRows(),
* symmetrize()
*/
public function getRawArray()
{
$ret_arr = array();
foreach ($this->rows as $key => $row) {
$item = array();
foreach ($this->headers as $col => $value) {
$item[$value] = $this->fixEncoding($row[$col]);
}
array_push($ret_arr, $item);
unset($item);
}
return $ret_arr;
}
// Fixes the encoding to uf8
function fixEncoding($in_str)
{
if (function_exists('mb_detect_encoding') and function_exists('mb_check_encoding')){
$cur_encoding = mb_detect_encoding($in_str) ;
if ( $cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8") ){
return $in_str;
}
else
return mb_convert_encoding( $in_str, 'UTF-8', 'ISO-8859-1' );
}
return $in_str;
} // fixEncoding
/**
* header creator
*
* uses prefix and creates a header for each column suffixed by a
* numeric value
*
* @param string $prefix string to use as prefix for each
* independent header
*
* @access public
* @return boolean fails if data is not symmetric
* @see isSymmetric(), getAsymmetricRows()
*/
public function createHeaders($prefix)
{
if (!$this->isSymmetric()) {
return false;
}
$length = count($this->headers) + 1;
$this->moveHeadersToRows();
$ret_arr = array();
for ($i = 1; $i < $length; $i ++) {
$ret_arr[] = $prefix . "_$i";
}
$this->headers = $ret_arr;
return $this->isSymmetric();
}
/**
* header injector
*
* uses a $list of values which wil be used to replace current
* headers.
*
*
* @param array $list a collection of names to use as headers,
*
* @access public
* @return boolean fails if data is not symmetric
* @see isSymmetric(), getAsymmetricRows(), getHeaders(), createHeaders()
*/
public function setHeaders($list)
{
if (!$this->isSymmetric()) {
return false;
}
if (!is_array($list)) {
return false;
}
if (count($list) != count($this->headers)) {
return false;
}
$this->moveHeadersToRows();
$this->headers = $list;
return true;
}
/**
* csv parser
*
* reads csv data and transforms it into php-data
*
* @access protected
* @return boolean
*/
protected function parse() {
if (!$this->validates()) {
return false;
}
$tmpname = wp_unique_filename($this->targetDir, str_replace("csv", "xml", basename($this->_filename)));
if ("" == $this->xml_path) {
$this->xml_path = $this->targetDir .'/'. wp_all_import_url_title($tmpname);
}
$ignore_special_characters = apply_filters('wp_all_import_csv_to_xml_remove_non_ascii_characters', true);
$this->toXML($ignore_special_characters);
return true;
}
function toXML( $fixBrokenSymbols = false ){
$c = 0;
$d = ( "" != $this->delimiter ) ? $this->delimiter : $this->settings['delimiter'];
$en = $this->settings['enclosure'];
$e = $this->settings['escape'];
$l = $this->settings['length'];
$this->is_csv = $d;
$is_html = false;
$f = @fopen($this->_filename, "rb");
while (!@feof($f)) {
$chunk = @fread($f, 1024);
if (strpos($chunk, "<!DOCTYPE") === 0) $is_html = true;
break;
}
if ($is_html) return;
$res = fopen($this->_filename, 'rb');
$xmlWriter = new XMLWriter();
$xmlWriter->openURI($this->xml_path);
$xmlWriter->setIndent(true);
$xmlWriter->setIndentString("\t");
$xmlWriter->startDocument('1.0', $this->csv_encoding);
$xmlWriter->startElement('data');
$import_id = 0;
if ( ! empty($_GET['id']) ) $import_id = intval($_GET['id']);
if ( ! empty($_GET['import_id']) ) $import_id = intval($_GET['import_id']);
$create_new_headers = false;
$skip_x_rows = apply_filters('wp_all_import_skip_x_csv_rows', false, $import_id);
$headers = array();
while ($keys = fgetcsv($res, $l, $d, $en, $e)) {
if ($skip_x_rows !== false && $skip_x_rows > $c) {
$c++;
continue;
}
if ($skip_x_rows !== false && $skip_x_rows <= $c) {
$skip_x_rows = false;
$c = 0;
}
$empty_columns = 0;
foreach ($keys as $key) {
if (preg_replace("%\s%", "", $key) == '') $empty_columns++;
}
// Skip empty lines.
if ($empty_columns == count($keys)) continue;
if ($c == 0) {
$buf_keys = $keys;
foreach ($keys as $key => $value) {
if (!$create_new_headers and (preg_match('%\W(http:|https:|ftp:)$%i', $value) or is_numeric($value))) {
$create_new_headers = true;
}
$value = trim(strtolower(preg_replace('/[^a-z0-9_]/i', '', $value)));
if (preg_match('/^[0-9]{1}/', $value)) {
$value = 'el_' . trim(strtolower($value));
}
$value = (!empty($value)) ? $value : 'undefined' . $key;
if (empty($headers[$value])) {
$headers[$value] = 1;
}
else {
$headers[$value]++;
}
$keys[$key] = ($headers[$value] === 1) ? $value : $value . '_' . $headers[$value];
}
$this->headers = $keys;
$create_new_headers = apply_filters('wp_all_import_auto_create_csv_headers', $create_new_headers, $import_id);
if ($create_new_headers) {
$this->createHeaders('column');
$keys = $buf_keys;
}
}
if ( $c or $create_new_headers ) {
if (!empty($keys)) {
$chunk = array();
foreach ($this->headers as $key => $header) {
if(isset($keys[$key])) {
$chunk[ $header ] = $this->fixEncoding( $keys[ $key ] );
}
}
if ( ! empty($chunk) ) {
$xmlWriter->startElement('node');
foreach ($chunk as $header => $value) {
$xmlWriter->startElement($header);
$value = preg_replace('/\]\]>/s', '', preg_replace('/<!\[CDATA\[/s', '', $value ));
if ($fixBrokenSymbols) {
// Remove non ASCII symbols and write CDATA.
$xmlWriter->writeCData(preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $value));
}
else {
$xmlWriter->writeCData($value);
}
$xmlWriter->endElement();
}
$xmlWriter->endElement();
}
}
}
$c++;
}
if ($c === 1 && !$create_new_headers) {
$xmlWriter->startElement('node');
$xmlWriter->endElement();
}
fclose($res);
$xmlWriter->endElement();
$xmlWriter->flush(TRUE);
return TRUE;
}
/**
* empty row remover
*
* removes all records that have been defined but have no data.
*
* @access protected
* @return array containing only the rows that have data
*/
protected function removeEmpty() {
$ret_arr = array();
foreach ($this->rows as $row) {
$line = trim(join('', $row));
if (!empty($line)) {
$ret_arr[] = $row;
}
}
$this->rows = $ret_arr;
}
/**
* csv file validator
*
* checks wheather if the given csv file is valid or not
*
* @access protected
* @return boolean
*/
protected function validates(){
// file existance
if (!file_exists($this->_filename)) {
return false;
}
// file readability
if (!is_readable($this->_filename)) {
return false;
}
return true;
}
/**
* header relocator
*
* @access protected
* @return void
*/
protected function moveHeadersToRows() {
$arr = array();
$arr[] = $this->headers;
foreach ($this->rows as $row) {
$arr[] = $row;
}
$this->rows = $arr;
$this->headers = array();
}
/**
* array key reseter
*
* makes sure that an array's keys are setted in a correct numerical order
*
* Note: that this function does not return anything, all changes
* are made to the original array as a reference
*
* @param array &$array any array, if keys are strings they will
* be replaced with numeric values
*
* @access protected
* @return void
*/
protected function resetKeys(&$array)
{
$arr = array();
foreach ($array as $item) {
$arr[] = $item;
}
$array = $arr;
}
/**
* object data flusher
*
* tells this object to forget all data loaded and start from
* scratch
*
* @access protected
* @return void
*/
protected function flush()
{
$this->rows = array();
$this->headers = array();
}
function analyse_file($file, $capture_limit_in_kb = 10) {
// capture starting memory usage
$output['peak_mem']['start'] = memory_get_peak_usage(true);
// log the limit how much of the file was sampled (in Kb)
$output['read_kb'] = $capture_limit_in_kb;
// read in file
$fh = fopen($file, 'r');
$contents = fgets($fh);
fclose($fh);
// specify allowed field delimiters
$delimiters = array(
'comma' => ',',
'semicolon' => ';',
'pipe' => '|',
'tabulation' => "\t"
);
$delimiters = apply_filters('wp_all_import_specified_delimiters', $delimiters);
// specify allowed line endings
$line_endings = array(
'rn' => "\r\n",
'n' => "\n",
'r' => "\r",
'nr' => "\n\r"
);
// loop and count each line ending instance
foreach ($line_endings as $key => $value) {
$line_result[$key] = substr_count($contents, $value);
}
// sort by largest array value
asort($line_result);
// log to output array
$output['line_ending']['results'] = $line_result;
$output['line_ending']['count'] = end($line_result);
$output['line_ending']['key'] = key($line_result);
$output['line_ending']['value'] = $line_endings[$output['line_ending']['key']];
$lines = explode($output['line_ending']['value'], $contents);
// remove last line of array, as this maybe incomplete?
array_pop($lines);
// create a string from the legal lines
$complete_lines = implode(' ', $lines);
// log statistics to output array
$output['lines']['count'] = count($lines);
$output['lines']['length'] = strlen($complete_lines);
// loop and count each delimiter instance
foreach ($delimiters as $delimiter_key => $delimiter) {
$delimiter_result[$delimiter_key] = substr_count($complete_lines, $delimiter);
}
// sort by largest array value
asort($delimiter_result);
// log statistics to output array with largest counts as the value
$output['delimiter']['results'] = $delimiter_result;
$output['delimiter']['count'] = end($delimiter_result);
$output['delimiter']['key'] = key($delimiter_result);
$output['delimiter']['value'] = $delimiters[$output['delimiter']['key']];
// capture ending memory usage
$output['peak_mem']['end'] = memory_get_peak_usage(true);
return $output;
}
}
?>