Completed
Push — master ( f6f521...3540e6 )
by cam
04:25
created

importer_csv.php ➔ inc_importer_csv_dist()   D

Complexity

Conditions 18
Paths 13

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
nc 13
nop 6
dl 0
loc 50
rs 4.8666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2019                                                *
7
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8
 *                                                                         *
9
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11
\***************************************************************************/
12
13
if (!defined('_ECRIRE_INC_VERSION')) {
14
	return;
15
}
16
17
include_spip('inc/charsets');
18
19
/**
20
 * Based on an example by ramdac at ramdac dot org
21
 * Returns a multi-dimensional array from a CSV file optionally using the
22
 * first row as a header to create the underlying data as associative arrays.
23
 *
24
 * @param string $file Filepath including filename
25
 * @param bool $head Use first row as header.
26
 * @param string $delim Specify a delimiter other than a comma.
27
 * @param int $len Line length to be passed to fgetcsv
28
 * @return array or false on failure to retrieve any rows.
29
 */
30
31
/**
32
 * Importer le charset d'une ligne
33
 *
34
 * Importe un texte de CSV dans un charset et le passe dans le charset du site (utf8 probablement)
35
 * Les CSV peuvent sous ms@@@ avoir le charset 'iso-8859-1', mais pasfois aussi 'windows-1252' :/
36
 *
37
 * @param mixed $texte
38
 * @param bool|string $definir_charset_source
39
 *     false : ne fait rien
40
 *     string : utilisera pour les prochains imports le charset indiqué
41
 *     true : remet le charset d'import par défaut de la fonction
42
 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
43
 */
44
function importer_csv_importcharset($texte, $definir_charset_source = false) {
45
	// le plus frequent, en particulier avec les trucs de ms@@@
46
	static $charset_source = 'iso-8859-1';
47
	if ($definir_charset_source) {
48
		if ($definir_charset_source === true) {
49
			$charset_source = 'iso-8859-1';
50
		} else {
51
			$charset_source = $definir_charset_source;
52
		}
53
	}
54
	// mais open-office sait faire mieux, donc mefiance !
55
	if (is_utf8($texte)) {
56
		$charset = 'utf-8';
57
	} else {
58
		$charset = $charset_source;
59
	}
60
	return importer_charset($texte, $charset);
0 ignored issues
show
Bug introduced by
It seems like $charset defined by $charset_source on line 58 can also be of type boolean; however, importer_charset() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
61
}
62
63
/**
64
 * enlever les accents des cles presentes dans le head,
65
 * sinon ca pose des problemes ...
66
 *
67
 * @param string $key
68
 * @return string
69
 */
70
function importer_csv_nettoie_key($key) {
71
	return translitteration($key);
72
}
73
74
/**
75
 * Lit un fichier csv et retourne un tableau
76
 * si $head est true, la premiere ligne est utilisee en header
77
 * pour generer un tableau associatif
78
 *
79
 * @param string $file
80
 * @param bool $head
81
 * @param string $delim
82
 * @param string $enclos
83
 * @param int $len
84
 * @param string $charset_source
85
 *     Permet de définir un charset source du CSV, si différent de utf-8 ou iso-8859-1
86
 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
87
 */
88
function inc_importer_csv_dist($file, $head = false, $delim = ',', $enclos = '"', $len = 10000, $charset_source = '') {
89
	$return = false;
90
	if (@file_exists($file)
91
		and $handle = fopen($file, 'r')) {
92
		if ($charset_source) {
93
			importer_csv_importcharset('', $charset_source);
94
		}
95
		if ($head) {
96
			$header = fgetcsv($handle, $len, $delim, $enclos);
97
			if ($header) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $header of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
98
				$header = array_map('importer_csv_importcharset', $header);
99
				$header = array_map('importer_csv_nettoie_key', $header);
100
				$header_type = array();
101
				foreach ($header as $heading) {
102
					if (!isset($header_type[$heading])) {
103
						$header_type[$heading] = "scalar";
104
					} else {
105
						$header_type[$heading] = "array";
106
					}
107
				}
108
			}
109
		}
110
		while (($data = fgetcsv($handle, $len, $delim, $enclos)) !== false) {
111
			$data = array_map('importer_csv_importcharset', $data);
112
			if ($head and isset($header)) {
113
				$row = array();
114
				foreach ($header as $key => $heading) {
115
					if ($header_type[$heading] == "array") {
0 ignored issues
show
Bug introduced by
The variable $header_type does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
116
						if (!isset($row[$heading])) {
117
							$row[$heading] = array();
118
						}
119
						if (isset($data[$key]) and strlen($data[$key])) {
120
							$row[$heading][] = $data[$key];
121
						}
122
					} else {
123
						$row[$heading] = (isset($data[$key])) ? $data[$key] : '';
124
					}
125
				}
126
				$return[] = $row;
127
			} else {
128
				$return[] = $data;
129
			}
130
		}
131
		if ($charset_source) {
132
			importer_csv_importcharset('', true);
133
		}
134
	}
135
136
	return $return;
137
}
138