1
0
Fork 0

Extracting JsonFile additions for prettifying JSON

pull/214/head
Justin Rainbow 2012-01-16 16:42:30 -07:00
parent f273b436cc
commit 447230d77a
2 changed files with 92 additions and 6 deletions

View File

@ -15,11 +15,6 @@ namespace Composer\Json;
use Composer\Repository\RepositoryManager; use Composer\Repository\RepositoryManager;
use Composer\Composer; use Composer\Composer;
// defined as of PHP 5.4
if (!defined('JSON_PRETTY_PRINT')) {
define('JSON_PRETTY_PRINT', 128);
}
/** /**
* Reads/writes json files. * Reads/writes json files.
* *
@ -96,7 +91,81 @@ class JsonFile
); );
} }
} }
file_put_contents($this->path, json_encode($hash, JSON_PRETTY_PRINT)); file_put_contents($this->path, $this->encode($hash));
}
/**
* Indents a flat JSON string to make it more human-readable
*
* Original code for this function can be found at:
* http://recursive-design.com/blog/2008/03/11/format-json-with-php/
*
* @param array $hash Data to encode into a formatted JSON string
* @return string Indented version of the original JSON string
*/
public function encode(array $hash)
{
if (defined('JSON_PRETTY_PRINT')) {
return json_encode($hash, JSON_PRETTY_PRINT);
}
$json = json_encode($hash);
$result = '';
$pos = 0;
$strLen = strlen($json);
$indentStr = ' ';
$newLine = "\n";
$prevChar = '';
$outOfQuotes = true;
for ($i = 0; $i <= $strLen; $i++) {
// Grab the next character in the string
$char = substr($json, $i, 1);
// Are we inside a quoted string?
if ('"' === $char && '\\' !== $prevChar) {
$outOfQuotes = !$outOfQuotes;
} else if (':' === $char && $outOfQuotes) {
// Add a space after the : character
$char .= ' ';
} else if (('}' === $char || ']' === $char) && $outOfQuotes) {
$pos--;
if ('{' !== $prevChar && '[' !== $prevChar) {
// If this character is the end of an element,
// output a new line and indent the next line
$result .= $newLine;
for ($j = 0; $j < $pos; $j++) {
$result .= $indentStr;
}
} else {
// Collapse empty {} and []
$result = rtrim($result);
}
}
// Add the character to the result string
$result .= $char;
// If the last character was the beginning of an element,
// output a new line and indent the next line
if ((',' === $char || '{' === $char || '[' === $char) && $outOfQuotes) {
$result .= $newLine;
if ('{' === $char || '[' === $char) {
$pos++;
}
for ($j = 0; $j < $pos; $j++) {
$result .= $indentStr;
}
}
$prevChar = $char;
}
return $result;
} }
/** /**

View File

@ -84,6 +84,15 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
$this->expectParseException('missing comma on line 2, char 21', $json); $this->expectParseException('missing comma on line 2, char 21', $json);
} }
public function testSimpleJsonString()
{
$data = array('name' => 'composer/composer');
$json = '{
"name": "composer\/composer"
}';
$this->assertJsonFormat($json, $data);
}
private function expectParseException($text, $json) private function expectParseException($text, $json)
{ {
try { try {
@ -93,4 +102,12 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
$this->assertContains($text, $e->getMessage()); $this->assertContains($text, $e->getMessage());
} }
} }
private function assertJsonFormat($json, $data)
{
$file = new JsonFile('composer.json');
$this->assertEquals($json, $file->encode($data));
}
} }