Skip to content
Extraits de code Groupes Projets
Valider a85c1058 rédigé par Matthieu Napoli's avatar Matthieu Napoli
Parcourir les fichiers

Moved the ini component to a separate repository

parent 120cba65
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -45,8 +45,9 @@
"piwik/device-detector": "~2.0",
"piwik/decompress": "~0.1.1",
"piwik/network": "~0.1.0",
"mnapoli/php-di": "5.0.x-dev",
"piwik/cache": "~0.2",
"piwik/ini": "~1.0",
"mnapoli/php-di": "5.0.x-dev",
"doctrine/cache": "dev-filecache-race-condition-fix as 1.3.1",
"psr/log": "~1.0",
"monolog/monolog": "~1.11",
......
......@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "eaa7dcd4b0c89c35cff039cd259a38c3",
"hash": "09ced245f00415f5fe13703565767884",
"packages": [
{
"name": "container-interop/container-interop",
......@@ -629,6 +629,38 @@
],
"time": "2015-01-01 16:13:46"
},
{
"name": "piwik/ini",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/piwik/component-ini.git",
"reference": "6c95b8886871bec86e7d648e913b4dc88b4166a6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/piwik/component-ini/zipball/6c95b8886871bec86e7d648e913b4dc88b4166a6",
"reference": "6c95b8886871bec86e7d648e913b4dc88b4166a6",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Piwik\\Ini\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"time": "2015-01-07 22:10:24"
},
{
"name": "piwik/network",
"version": "0.1.0",
......@@ -701,17 +733,17 @@
},
{
"name": "symfony/console",
"version": "v2.6.1",
"version": "v2.6.3",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8"
"reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8",
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8",
"url": "https://api.github.com/repos/symfony/Console/zipball/6ac6491ff60c0e5a941db3ccdc75a07adbb61476",
"reference": "6ac6491ff60c0e5a941db3ccdc75a07adbb61476",
"shasum": ""
},
"require": {
......@@ -754,21 +786,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-06 17:50:02"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.6.1",
"version": "v2.6.3",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216"
"reference": "40ff70cadea3785d83cac1c8309514b36113064e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216",
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/40ff70cadea3785d83cac1c8309514b36113064e",
"reference": "40ff70cadea3785d83cac1c8309514b36113064e",
"shasum": ""
},
"require": {
......@@ -776,10 +808,10 @@
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0",
"symfony/config": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/stopwatch": "~2.2"
"symfony/stopwatch": "~2.3"
},
"suggest": {
"symfony/dependency-injection": "",
......@@ -812,21 +844,21 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-05 14:28:40"
},
{
"name": "symfony/monolog-bridge",
"version": "v2.6.1",
"version": "v2.6.3",
"target-dir": "Symfony/Bridge/Monolog",
"source": {
"type": "git",
"url": "https://github.com/symfony/MonologBridge.git",
"reference": "98a8debb952b8a7e0fff31fbce0f5e965dc1f499"
"reference": "83a451b5a2e16a14ffd07a42746c4b9db1a48c1d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/MonologBridge/zipball/98a8debb952b8a7e0fff31fbce0f5e965dc1f499",
"reference": "98a8debb952b8a7e0fff31fbce0f5e965dc1f499",
"url": "https://api.github.com/repos/symfony/MonologBridge/zipball/83a451b5a2e16a14ffd07a42746c4b9db1a48c1d",
"reference": "83a451b5a2e16a14ffd07a42746c4b9db1a48c1d",
"shasum": ""
},
"require": {
......@@ -834,9 +866,9 @@
"php": ">=5.3.3"
},
"require-dev": {
"symfony/console": "~2.3",
"symfony/console": "~2.4",
"symfony/event-dispatcher": "~2.2",
"symfony/http-kernel": "~2.2"
"symfony/http-kernel": "~2.4"
},
"suggest": {
"symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings. You need version ~2.3 of the console for it.",
......@@ -870,7 +902,7 @@
],
"description": "Symfony Monolog Bridge",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-03 08:01:59"
},
{
"name": "tedivm/jshrink",
......@@ -2004,17 +2036,17 @@
},
{
"name": "symfony/var-dumper",
"version": "v2.6.1",
"version": "v2.6.3",
"target-dir": "Symfony/Component/VarDumper",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "8f3ee04faeca3b8418229b2efbfc8b2b8625b8aa"
"reference": "36af986811340fd4c1bc39cf848da388bbdd8473"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/8f3ee04faeca3b8418229b2efbfc8b2b8625b8aa",
"reference": "8f3ee04faeca3b8418229b2efbfc8b2b8625b8aa",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/36af986811340fd4c1bc39cf848da388bbdd8473",
"reference": "36af986811340fd4c1bc39cf848da388bbdd8473",
"shasum": ""
},
"require": {
......@@ -2053,21 +2085,21 @@
"debug",
"dump"
],
"time": "2014-11-18 10:08:24"
"time": "2015-01-01 13:28:01"
},
{
"name": "symfony/yaml",
"version": "v2.6.1",
"version": "v2.6.3",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20"
"reference": "82462a90848a52c2533aa6b598b107d68076b018"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20",
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018",
"reference": "82462a90848a52c2533aa6b598b107d68076b018",
"shasum": ""
},
"require": {
......@@ -2100,7 +2132,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
"time": "2014-12-02 20:19:20"
"time": "2015-01-03 15:33:07"
}
],
"aliases": [
......
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Ini;
/**
* Reads INI configuration.
*/
class IniReader
{
/**
* Reads a INI configuration file and returns it as an array.
*
* The array returned is multidimensional, indexed by section names:
*
* ```
* array(
* 'Section 1' => array(
* 'value1' => 'hello',
* 'value2' => 'world',
* ),
* 'Section 2' => array(
* 'value3' => 'foo',
* )
* );
* ```
*
* @param string $filename The file to read.
* @throws IniReadingException
* @return array
*/
public function readFile($filename)
{
if (!file_exists($filename) || !is_readable($filename)) {
throw new IniReadingException(sprintf("The file %s doesn't exist or is not readable", $filename));
}
$ini = $this->getFileContent($filename);
if ($ini === false) {
throw new IniReadingException(sprintf('Impossible to read the file %s', $filename));
}
return $this->readString($ini);
}
/**
* Reads a INI configuration string and returns it as an array.
*
* The array returned is multidimensional, indexed by section names:
*
* ```
* array(
* 'Section 1' => array(
* 'value1' => 'hello',
* 'value2' => 'world',
* ),
* 'Section 2' => array(
* 'value3' => 'foo',
* )
* );
* ```
*
* @param string $ini String containing INI configuration.
* @throws IniReadingException
* @return array
*/
public function readString($ini)
{
if (!function_exists('parse_ini_file')) {
return $this->readIni($ini, true);
}
$array = @parse_ini_string($ini, true, INI_SCANNER_RAW);
if ($array === false) {
$e = error_get_last();
throw new IniReadingException('Syntax error in INI configuration: ' . $e['message']);
}
$array = $this->decodeValues($array);
return $array;
}
/**
* Reimplementation in case `parse_ini_file()` is disabled.
*
* @author Andrew Sohn <asohn (at) aircanopy (dot) net>
* @author anthon (dot) pang (at) gmail (dot) com
*
* @param string $ini
* @param bool $processSections
* @return array
*/
private function readIni($ini, $processSections)
{
if (is_string($ini)) {
$ini = explode("\n", str_replace("\r", "\n", $ini));
}
if (count($ini) == 0) {
return array();
}
$sections = array();
$values = array();
$result = array();
$globals = array();
$i = 0;
foreach ($ini as $line) {
$line = trim($line);
$line = str_replace("\t", " ", $line);
// Comments
if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {
continue;
}
// Sections
if ($line{0} == '[') {
$tmp = explode(']', $line);
$sections[] = trim(substr($tmp[0], 1));
$i++;
continue;
}
// Key-value pair
list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
if (strstr($value, ";")) {
$tmp = explode(';', $value);
if (count($tmp) == 2) {
if ((($value{0} != '"') && ($value{0} != "'")) ||
preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) ||
preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value)
) {
$value = $tmp[0];
}
} else {
if ($value{0} == '"') {
$value = preg_replace('/^"(.*)".*/', '$1', $value);
} elseif ($value{0} == "'") {
$value = preg_replace("/^'(.*)'.*/", '$1', $value);
} else {
$value = $tmp[0];
}
}
}
$value = trim($value);
$value = trim($value, "'\"");
if ($i == 0) {
if (substr($key, -2) == '[]') {
$globals[substr($key, 0, -2)][] = $value;
} else {
$globals[$key] = $value;
}
} else {
if (substr($key, -2) == '[]') {
$values[$i - 1][substr($key, 0, -2)][] = $value;
} else {
$values[$i - 1][$key] = $value;
}
}
}
for ($j = 0; $j < $i; $j++) {
if (isset($values[$j])) {
if ($processSections === true) {
$result[$sections[$j]] = $values[$j];
} else {
$result[] = $values[$j];
}
} else {
if ($processSections === true) {
$result[$sections[$j]] = array();
}
}
}
return $result + $globals;
}
/**
* @param string $filename
* @return bool|string Returns false if failure.
*/
private function getFileContent($filename)
{
if (function_exists('file_get_contents')) {
return file_get_contents($filename);
} elseif (function_exists('file')) {
$ini = file($filename);
if ($ini !== false) {
return implode("\n", $ini);
}
} elseif (function_exists('fopen') && function_exists('fread')) {
$handle = fopen($filename, 'r');
if (!$handle) {
return false;
}
$ini = fread($handle, filesize($filename));
fclose($handle);
return $ini;
}
return false;
}
private function decodeValues($config)
{
foreach ($config as &$section) {
foreach ($section as $option => $value) {
$section[$option] = $this->decodeValue($value);
}
}
return $config;
}
/**
* We have to decode values manually because parse_ini_file() has a poor implementation.
*
* @param mixed $value
* @return mixed
*/
private function decodeValue($value)
{
if (is_array($value)) {
foreach ($value as &$subValue) {
$subValue = $this->decodeValue($subValue);
}
return $value;
}
if (is_numeric($value)) {
return $value + 0;
}
switch (strtolower($value)) {
case '':
case 'null' :
return null;
case 'true' :
case 'yes' :
case 'on' :
return true;
case 'false':
case 'no':
case 'off':
return false;
}
return $value;
}
}
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Ini;
/**
* Exception when reading a INI configuration.
*/
class IniReadingException extends \Exception
{
}
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Ini;
/**
* Writes INI configuration.
*/
class IniWriter
{
/**
* Writes an array configuration to a INI file.
*
* The array provided must be multidimensional, indexed by section names:
*
* ```
* array(
* 'Section 1' => array(
* 'value1' => 'hello',
* 'value2' => 'world',
* ),
* 'Section 2' => array(
* 'value3' => 'foo',
* )
* );
* ```
*
* @param string $filename
* @param array $config
* @param string $header Optional header to insert at the top of the file.
* @throws IniWritingException
*/
public function writeToFile($filename, array $config, $header = '')
{
$ini = $this->writeToString($config, $header);
if (!file_put_contents($filename, $ini)) {
throw new IniWritingException(sprintf('Impossible to write to file %s', $filename));
}
}
/**
* Writes an array configuration to a INI string and returns it.
*
* The array provided must be multidimensional, indexed by section names:
*
* ```
* array(
* 'Section 1' => array(
* 'value1' => 'hello',
* 'value2' => 'world',
* ),
* 'Section 2' => array(
* 'value3' => 'foo',
* )
* );
* ```
*
* @param array $config
* @param string $header Optional header to insert at the top of the file.
* @return string
* @throws IniWritingException
*/
public function writeToString(array $config, $header = '')
{
$ini = $header;
$sectionNames = array_keys($config);
foreach ($sectionNames as $sectionName) {
$section = $config[$sectionName];
// no point in writing empty sections
if (empty($section)) {
continue;
}
if (! is_array($section)) {
throw new IniWritingException(sprintf("Section \"%s\" doesn't contain an array of values", $sectionName));
}
$ini .= "[$sectionName]\n";
foreach ($section as $option => $value) {
if (is_numeric($option)) {
$option = $sectionName;
$value = array($value);
}
if (is_array($value)) {
foreach ($value as $currentValue) {
$ini .= $option . '[] = ' . $this->encodeValue($currentValue) . "\n";
}
} else {
$ini .= $option . ' = ' . $this->encodeValue($value) . "\n";
}
}
$ini .= "\n";
}
return $ini;
}
private function encodeValue($value)
{
if (is_bool($value)) {
return (int) $value;
}
if (is_string($value)) {
return "\"$value\"";
}
return $value;
}
}
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Ini;
/**
* Exception when writing a INI configuration.
*/
class IniWritingException extends \Exception
{
}
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Tests\Unit\Ini;
use Piwik\Ini\IniReader;
class IniReaderTest extends \PHPUnit_Framework_TestCase
{
public function test_readString()
{
$ini = <<<INI
[Section 1]
foo = "bar"
bool_true_1 = 1
bool_false_1 = 0
bool_true_2 = true
bool_false_2 = false
bool_true_3 = yes
bool_false_3 = no
bool_true_4 = on
bool_false_4 = off
empty =
explicit_null = null
int = 10
float = 10.3
array[] = "string"
array[] = 10.3
array[] = 1
array[] = 0
array[] = true
array[] = false
[Section 2]
foo = "bar"
INI;
$expected = array(
'Section 1' => array(
'foo' => 'bar',
'bool_true_1' => 1,
'bool_false_1' => 0,
'bool_true_2' => true,
'bool_false_2' => false,
'bool_true_3' => true,
'bool_false_3' => false,
'bool_true_4' => true,
'bool_false_4' => false,
'empty' => null,
'explicit_null' => null,
'int' => 10,
'float' => 10.3,
'array' => array(
'string',
10.3,
1,
0,
true,
false,
),
),
'Section 2' => array(
'foo' => 'bar',
),
);
$reader = new IniReader();
$this->assertSame($expected, $reader->readString($ini));
}
public function test_readString_withEmptyString()
{
$reader = new IniReader();
$this->assertSame(array(), $reader->readString(''));
}
/**
* @expectedException \Piwik\Ini\IniReadingException
* @expectedExceptionMessage Syntax error in INI configuration
*/
public function test_readString_shouldThrowException_ifInvalidIni()
{
$reader = new IniReader();
$reader->readString('[ test = foo');
}
public function test_readString_shouldIgnoreComments()
{
$expected = array(
'Section 1' => array(
'foo' => 'bar',
),
);
$ini = <<<INI
; <?php exit; ?> DO NOT REMOVE THIS LINE
[Section 1]
foo = "bar"
INI;
$reader = new IniReader();
$this->assertSame($expected, $reader->readString($ini));
}
}
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Tests\Unit\Ini;
use Piwik\Ini\IniWriter;
class IniWriterTest extends \PHPUnit_Framework_TestCase
{
public function test_writeToString()
{
$config = array(
'Section 1' => array(
'foo' => 'bar',
'bool_true' => true,
'bool_false' => false,
'int' => 10,
'float' => 10.3,
'array' => array(
'string',
10.3,
true,
false,
),
),
'Section 2' => array(
'foo' => 'bar',
),
);
$expected = <<<INI
[Section 1]
foo = "bar"
bool_true = 1
bool_false = 0
int = 10
float = 10.3
array[] = "string"
array[] = 10.3
array[] = 1
array[] = 0
[Section 2]
foo = "bar"
INI;
$writer = new IniWriter();
$this->assertEquals($expected, $writer->writeToString($config));
}
public function test_writeToString_withEmptyConfig()
{
$writer = new IniWriter();
$this->assertEquals('', $writer->writeToString(array()));
}
/**
* @expectedException \Piwik\Ini\IniWritingException
* @expectedExceptionMessage Section "Section 1" doesn't contain an array of values
*/
public function test_writeToString_shouldThrowException_withInvalidConfig()
{
$writer = new IniWriter();
$writer->writeToString(array('Section 1' => 123));
}
public function test_writeToString_shouldAddHeader()
{
$header = "; <?php exit; ?> DO NOT REMOVE THIS LINE\n";
$config = array(
'Section 1' => array(
'foo' => 'bar',
),
);
$expected = <<<INI
; <?php exit; ?> DO NOT REMOVE THIS LINE
[Section 1]
foo = "bar"
INI;
$writer = new IniWriter();
$this->assertEquals($expected, $writer->writeToString($config, $header));
}
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter