| 1 |
organisation des fichiers : |
|---|
| 2 |
|
|---|
| 3 |
- spyc.php : |
|---|
| 4 |
�lacer dans jelix/lib/spyc/spyc.php |
|---|
| 5 |
- populatedb.cmd.php : |
|---|
| 6 |
�lacer dans jelix/lib/jelix-scripts/commands/populatedb.cmd.php |
|---|
| 7 |
- data.yml : fichier example |
|---|
| 8 |
|
|---|
| 9 |
-------------------------------------------------------------------------------- |
|---|
| 10 |
|
|---|
| 11 |
<?php |
|---|
| 12 |
/** |
|---|
| 13 |
* Spyc -- A Simple PHP YAML Class |
|---|
| 14 |
* @version 0.2 -- 2006-01-07 |
|---|
| 15 |
* @author Chris Wanstrath <chris@ozmm.org> |
|---|
| 16 |
* @link http://spyc.sourceforge.net/ |
|---|
| 17 |
* @copyright Copyright 2005-2006 Chris Wanstrath |
|---|
| 18 |
* @license http://www.opensource.org/licenses/mit-license.php MIT License |
|---|
| 19 |
* @package Spyc |
|---|
| 20 |
*/ |
|---|
| 21 |
|
|---|
| 22 |
/** |
|---|
| 23 |
* A node, used by Spyc for parsing YAML. |
|---|
| 24 |
* @package Spyc |
|---|
| 25 |
*/ |
|---|
| 26 |
class YAMLNode { |
|---|
| 27 |
/**#@+ |
|---|
| 28 |
* @access public |
|---|
| 29 |
* @var string |
|---|
| 30 |
*/ |
|---|
| 31 |
var $parent; |
|---|
| 32 |
var $id; |
|---|
| 33 |
/**#@+*/ |
|---|
| 34 |
/** |
|---|
| 35 |
* @access public |
|---|
| 36 |
* @var mixed |
|---|
| 37 |
*/ |
|---|
| 38 |
var $data; |
|---|
| 39 |
/** |
|---|
| 40 |
* @access public |
|---|
| 41 |
* @var int |
|---|
| 42 |
*/ |
|---|
| 43 |
var $indent; |
|---|
| 44 |
/** |
|---|
| 45 |
* @access public |
|---|
| 46 |
* @var bool |
|---|
| 47 |
*/ |
|---|
| 48 |
var $children = false; |
|---|
| 49 |
|
|---|
| 50 |
/** |
|---|
| 51 |
* The constructor assigns the node a unique ID. |
|---|
| 52 |
* @access public |
|---|
| 53 |
* @return void |
|---|
| 54 |
*/ |
|---|
| 55 |
function YAMLNode() { |
|---|
| 56 |
$this->id = uniqid(''); |
|---|
| 57 |
} |
|---|
| 58 |
} |
|---|
| 59 |
|
|---|
| 60 |
/** |
|---|
| 61 |
* The Simple PHP YAML Class. |
|---|
| 62 |
* |
|---|
| 63 |
* This class can be used to read a YAML file and convert its contents |
|---|
| 64 |
* into a PHP array. It currently supports a very limited subsection of |
|---|
| 65 |
* the YAML spec. |
|---|
| 66 |
* |
|---|
| 67 |
* Usage: |
|---|
| 68 |
* <code> |
|---|
| 69 |
* $parser = new Spyc; |
|---|
| 70 |
* $array = $parser->load($file); |
|---|
| 71 |
* </code> |
|---|
| 72 |
* @package Spyc |
|---|
| 73 |
*/ |
|---|
| 74 |
class Spyc { |
|---|
| 75 |
|
|---|
| 76 |
/** |
|---|
| 77 |
* Load YAML into a PHP array statically |
|---|
| 78 |
* |
|---|
| 79 |
* The load method, when supplied with a YAML stream (string or file), |
|---|
| 80 |
* will do its best to convert YAML in a file into a PHP array. Pretty |
|---|
| 81 |
* simple. |
|---|
| 82 |
* Usage: |
|---|
| 83 |
* <code> |
|---|
| 84 |
* $array = Spyc::YAMLLoad('lucky.yml'); |
|---|
| 85 |
* print_r($array); |
|---|
| 86 |
* </code> |
|---|
| 87 |
* @access public |
|---|
| 88 |
* @return array |
|---|
| 89 |
* @param string $input Path of YAML file or string containing YAML |
|---|
| 90 |
*/ |
|---|
| 91 |
function YAMLLoad($input) { |
|---|
| 92 |
$spyc = new Spyc; |
|---|
| 93 |
return $spyc->load($input); |
|---|
| 94 |
} |
|---|
| 95 |
|
|---|
| 96 |
/** |
|---|
| 97 |
* Dump YAML from PHP array statically |
|---|
| 98 |
* |
|---|
| 99 |
* The dump method, when supplied with an array, will do its best |
|---|
| 100 |
* to convert the array into friendly YAML. Pretty simple. Feel free to |
|---|
| 101 |
* save the returned string as nothing.yml and pass it around. |
|---|
| 102 |
* |
|---|
| 103 |
* Oh, and you can decide how big the indent is and what the wordwrap |
|---|
| 104 |
* for folding is. Pretty cool -- just pass in 'false' for either if |
|---|
| 105 |
* you want to use the default. |
|---|
| 106 |
* |
|---|
| 107 |
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And |
|---|
| 108 |
* you can turn off wordwrap by passing in 0. |
|---|
| 109 |
* |
|---|
| 110 |
* @access public |
|---|
| 111 |
* @return string |
|---|
| 112 |
* @param array $array PHP array |
|---|
| 113 |
* @param int $indent Pass in false to use the default, which is 2 |
|---|
| 114 |
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) |
|---|
| 115 |
*/ |
|---|
| 116 |
function YAMLDump($array,$indent = false,$wordwrap = false) { |
|---|
| 117 |
$spyc = new Spyc; |
|---|
| 118 |
return $spyc->dump($array,$indent,$wordwrap); |
|---|
| 119 |
} |
|---|
| 120 |
|
|---|
| 121 |
/** |
|---|
| 122 |
* Load YAML into a PHP array from an instantiated object |
|---|
| 123 |
* |
|---|
| 124 |
* The load method, when supplied with a YAML stream (string or file path), |
|---|
| 125 |
* will do its best to convert the YAML into a PHP array. Pretty simple. |
|---|
| 126 |
* Usage: |
|---|
| 127 |
* <code> |
|---|
| 128 |
* $parser = new Spyc; |
|---|
| 129 |
* $array = $parser->load('lucky.yml'); |
|---|
| 130 |
* print_r($array); |
|---|
| 131 |
* </code> |
|---|
| 132 |
* @access public |
|---|
| 133 |
* @return array |
|---|
| 134 |
* @param string $input Path of YAML file or string containing YAML |
|---|
| 135 |
*/ |
|---|
| 136 |
function load($input) { |
|---|
| 137 |
// See what type of input we're talking about |
|---|
| 138 |
// If it's not a file, assume it's a string |
|---|
| 139 |
if (!empty($input) && file_exists($input)) { |
|---|
| 140 |
$yaml = file($input); |
|---|
| 141 |
} else { |
|---|
| 142 |
$yaml = explode("\n",$input); |
|---|
| 143 |
} |
|---|
| 144 |
// Initiate some objects and values |
|---|
| 145 |
$base = new YAMLNode; |
|---|
| 146 |
$base->indent = 0; |
|---|
| 147 |
$this->_lastIndent = 0; |
|---|
| 148 |
$this->_lastNode = $base->id; |
|---|
| 149 |
$this->_inBlock = false; |
|---|
| 150 |
$this->_isInline = false; |
|---|
| 151 |
|
|---|
| 152 |
foreach ($yaml as $line) { |
|---|
| 153 |
// If the line starts with a # its a comment |
|---|
| 154 |
$ifchk = trim($line); |
|---|
| 155 |
|
|---|
| 156 |
if ($this->_inBlock === false && empty($ifchk)) { |
|---|
| 157 |
continue; |
|---|
| 158 |
} elseif ($this->_inBlock == true && empty($ifchk)) { |
|---|
| 159 |
$last =& $this->_allNodes[$this->_lastNode]; |
|---|
| 160 |
$last->data[key($last->data)] .= "\n"; |
|---|
| 161 |
} elseif ($ifchk{0} != '#' && substr($ifchk,0,3) != '---') { |
|---|
| 162 |
// Create a new node and get its indent |
|---|
| 163 |
$node = new YAMLNode; |
|---|
| 164 |
$node->indent = $this->_getIndent($line); |
|---|
| 165 |
|
|---|
| 166 |
// Check where the node lies in the hierarchy |
|---|
| 167 |
if ($this->_lastIndent == $node->indent) { |
|---|
| 168 |
// If we're in a block, add the text to the parent's data |
|---|
| 169 |
if ($this->_inBlock === true) { |
|---|
| 170 |
$parent =& $this->_allNodes[$this->_lastNode]; |
|---|
| 171 |
$parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; |
|---|
| 172 |
} else { |
|---|
| 173 |
// The current node's parent is the same as the previous node's |
|---|
| 174 |
if (isset($this->_allNodes[$this->_lastNode])) { |
|---|
| 175 |
$node->parent = $this->_allNodes[$this->_lastNode]->parent; |
|---|
| 176 |
} |
|---|
| 177 |
} |
|---|
| 178 |
} elseif ($this->_lastIndent < $node->indent) { |
|---|
| 179 |
if ($this->_inBlock === true) { |
|---|
| 180 |
$parent =& $this->_allNodes[$this->_lastNode]; |
|---|
| 181 |
$parent->data[key($parent->data)] .= trim($line).$this->_blockEnd; |
|---|
| 182 |
} elseif ($this->_inBlock === false) { |
|---|
| 183 |
// The current node's parent is the previous node |
|---|
| 184 |
$node->parent = $this->_lastNode; |
|---|
| 185 |
|
|---|
| 186 |
// If the value of the last node's data was > or | we need to |
|---|
| 187 |
// start blocking i.e. taking in all lines as a text value until |
|---|
| 188 |
// we drop our indent. |
|---|
| 189 |
$parent =& $this->_allNodes[$node->parent]; |
|---|
| 190 |
$this->_allNodes[$node->parent]->children = true; |
|---|
| 191 |
if (is_array($parent->data)) { |
|---|
| 192 |
$chk = $parent->data[key($parent->data)]; |
|---|
| 193 |
if ($chk === '>') { |
|---|
| 194 |
$this->_inBlock = true; |
|---|
| 195 |
$this->_blockEnd = ' '; |
|---|
| 196 |
$parent->data[key($parent->data)] = |
|---|
| 197 |
str_replace('>','',$parent->data[key($parent->data)]); |
|---|
| 198 |
$parent->data[key($parent->data)] .= trim($line).' '; |
|---|
| 199 |
$this->_allNodes[$node->parent]->children = false; |
|---|
| 200 |
$this->_lastIndent = $node->indent; |
|---|
| 201 |
} elseif ($chk === '|') { |
|---|
| 202 |
$this->_inBlock = true; |
|---|
| 203 |
$this->_blockEnd = "\n"; |
|---|
| 204 |
$parent->data[key($parent->data)] = |
|---|
| 205 |
str_replace('|','',$parent->data[key($parent->data)]); |
|---|
| 206 |
$parent->data[key($parent->data)] .= trim($line)."\n"; |
|---|
| 207 |
$this->_allNodes[$node->parent]->children = false; |
|---|
| 208 |
$this->_lastIndent = $node->indent; |
|---|
| 209 |
} |
|---|
| 210 |
} |
|---|
| 211 |
} |
|---|
| 212 |
} elseif ($this->_lastIndent > $node->indent) { |
|---|
| 213 |
// Any block we had going is dead now |
|---|
| 214 |
if ($this->_inBlock === true) { |
|---|
| 215 |
$this->_inBlock = false; |
|---|
| 216 |
if ($this->_blockEnd = "\n") { |
|---|
| 217 |
$last =& $this->_allNodes[$this->_lastNode]; |
|---|
| 218 |
$last->data[key($last->data)] = |
|---|
| 219 |
trim($last->data[key($last->data)]); |
|---|
| 220 |
} |
|---|
| 221 |
} |
|---|
| 222 |
|
|---|
| 223 |
// We don't know the parent of the node so we have to find it |
|---|
| 224 |
// foreach ($this->_allNodes as $n) { |
|---|
| 225 |
foreach ($this->_indentSort[$node->indent] as $n) { |
|---|
| 226 |
if ($n->indent == $node->indent) { |
|---|
| 227 |
$node->parent = $n->parent; |
|---|
| 228 |
} |
|---|
| 229 |
} |
|---|
| 230 |
} |
|---|
| 231 |
|
|---|
| 232 |
if ($this->_inBlock === false) { |
|---|
| 233 |
// Set these properties with information from our current node |
|---|
| 234 |
$this->_lastIndent = $node->indent; |
|---|
| 235 |
|
|---|
| 236 |
// Set the last node |
|---|
| 237 |
$this->_lastNode = $node->id; |
|---|
| 238 |
// Parse the YAML line and return its data |
|---|
| 239 |
$node->data = $this->_parseLine($line); |
|---|
| 240 |
// Add the node to the master list |
|---|
| 241 |
$this->_allNodes[$node->id] = $node; |
|---|
| 242 |
// Add a reference to the node in an indent array |
|---|
| 243 |
$this->_indentSort[$node->indent][] =& $this->_allNodes[$node->id]; |
|---|
| 244 |
// Add a reference to the node in a References array if this node |
|---|
| 245 |
// has a YAML reference in it. |
|---|
| 246 |
if ( |
|---|
| 247 |
( (is_array($node->data)) && |
|---|
| 248 |
(!is_array($node->data[key($node->data)])) ) |
|---|
| 249 |
&& |
|---|
| 250 |
( (preg_match('/^&([^ ]+)/',$node->data[key($node->data)])) |
|---|
| 251 |
|| |
|---|
| 252 |
(preg_match('/^\*([^ ]+)/',$node->data[key($node->data)])) ) |
|---|
| 253 |
) { |
|---|
| 254 |
$this->_haveRefs[] =& $this->_allNodes[$node->id]; |
|---|
| 255 |
} elseif ( |
|---|
| 256 |
( (is_array($node->data)) && |
|---|
| 257 |
(is_array($node->data[key($node->data)])) ) |
|---|
| 258 |
) { |
|---|
| 259 |
// Incomplete reference making code. Ugly, needs cleaned up. |
|---|
| 260 |
foreach ($node->data[key($node->data)] as $d) { |
|---|
| 261 |
if ( !is_array($d) && |
|---|
| 262 |
( (preg_match('/^&([^ ]+)/',$d)) |
|---|
| 263 |
|| |
|---|
| 264 |
(preg_match('/^\*([^ ]+)/',$d)) ) |
|---|
| 265 |
) { |
|---|
| 266 |
$this->_haveRefs[] =& $this->_allNodes[$node->id]; |
|---|
| 267 |
} |
|---|
| 268 |
} |
|---|
| 269 |
} |
|---|
| 270 |
} |
|---|
| 271 |
} |
|---|
| 272 |
} |
|---|
| 273 |
unset($node); |
|---|
| 274 |
|
|---|
| 275 |
// Here we travel through node-space and pick out references (& and *) |
|---|
| 276 |
$this->_linkReferences(); |
|---|
| 277 |
|
|---|
| 278 |
// Build the PHP array out of node-space |
|---|
| 279 |
$trunk = $this->_buildArray(); |
|---|
| 280 |
return $trunk; |
|---|
| 281 |
} |
|---|
| 282 |
|
|---|
| 283 |
/** |
|---|
| 284 |
* Dump PHP array to YAML |
|---|
| 285 |
* |
|---|
| 286 |
* The dump method, when supplied with an array, will do its best |
|---|
| 287 |
* to convert the array into friendly YAML. Pretty simple. Feel free to |
|---|
| 288 |
* save the returned string as tasteful.yml and pass it around. |
|---|
| 289 |
* |
|---|
| 290 |
* Oh, and you can decide how big the indent is and what the wordwrap |
|---|
| 291 |
* for folding is. Pretty cool -- just pass in 'false' for either if |
|---|
| 292 |
* you want to use the default. |
|---|
| 293 |
* |
|---|
| 294 |
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And |
|---|
| 295 |
* you can turn off wordwrap by passing in 0. |
|---|
| 296 |
* |
|---|
| 297 |
* @access public |
|---|
| 298 |
* @return string |
|---|
| 299 |
* @param array $array PHP array |
|---|
| 300 |
* @param int $indent Pass in false to use the default, which is 2 |
|---|
| 301 |
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) |
|---|
| 302 |
*/ |
|---|
| 303 |
function dump($array,$indent = false,$wordwrap = false) { |
|---|
| 304 |
// Dumps to some very clean YAML. We'll have to add some more features |
|---|
| 305 |
// and options soon. And better support for folding. |
|---|
| 306 |
|
|---|
| 307 |
// New features and options. |
|---|
| 308 |
if ($indent === false or !is_numeric($indent)) { |
|---|
| 309 |
$this->_dumpIndent = 2; |
|---|
| 310 |
} else { |
|---|
| 311 |
$this->_dumpIndent = $indent; |
|---|
| 312 |
} |
|---|
| 313 |
|
|---|
| 314 |
if ($wordwrap === false or !is_numeric($wordwrap)) { |
|---|
| 315 |
$this->_dumpWordWrap = 40; |
|---|
| 316 |
} else { |
|---|
| 317 |
$this->_dumpWordWrap = $wordwrap; |
|---|
| 318 |
} |
|---|
| 319 |
|
|---|
| 320 |
// New YAML document |
|---|
| 321 |
$string = "---\n"; |
|---|
| 322 |
|
|---|
| 323 |
// Start at the base of the array and move through it. |
|---|
| 324 |
foreach ($array as $key => $value) { |
|---|
| 325 |
$string .= $this->_yamlize($key,$value,0); |
|---|
| 326 |
} |
|---|
| 327 |
return $string; |
|---|
| 328 |
} |
|---|
| 329 |
|
|---|
| 330 |
/**** Private Properties ****/ |
|---|
| 331 |
|
|---|
| 332 |
/**#@+ |
|---|
| 333 |
* @access private |
|---|
| 334 |
* @var mixed |
|---|
| 335 |
*/ |
|---|
| 336 |
var $_haveRefs; |
|---|
| 337 |
var $_allNodes; |
|---|
| 338 |
var $_lastIndent; |
|---|
| 339 |
var $_lastNode; |
|---|
| 340 |
var $_inBlock; |
|---|
| 341 |
var $_isInline; |
|---|
| 342 |
var $_dumpIndent; |
|---|
| 343 |
var $_dumpWordWrap; |
|---|
| 344 |
/**#@+*/ |
|---|
| 345 |
|
|---|
| 346 |
/**** Private Methods ****/ |
|---|
| 347 |
|
|---|
| 348 |
/** |
|---|
| 349 |
* Attempts to convert a key / value array item to YAML |
|---|
| 350 |
* @access private |
|---|
| 351 |
* @return string |
|---|
| 352 |
* @param $key The name of the key |
|---|
| 353 |
* @param $value The value of the item |
|---|
| 354 |
* @param $indent The indent of the current node |
|---|
| 355 |
*/ |
|---|
| 356 |
function _yamlize($key,$value,$indent) { |
|---|
| 357 |
if (is_array($value)) { |
|---|
| 358 |
// It has children. What to do? |
|---|
| 359 |
// Make it the right kind of item |
|---|
| 360 |
$string = $this->_dumpNode($key,NULL,$indent); |
|---|
| 361 |
// Add the indent |
|---|
| 362 |
$indent += $this->_dumpIndent; |
|---|
| 363 |
// Yamlize the array |
|---|
| 364 |
$string .= $this->_yamlizeArray($value,$indent); |
|---|
| 365 |
} elseif (!is_array($value)) { |
|---|
| 366 |
// It doesn't have children. Yip. |
|---|
| 367 |
$string = $this->_dumpNode($key,$value,$indent); |
|---|
| 368 |
} |
|---|
| 369 |
return $string; |
|---|
| 370 |
} |
|---|
| 371 |
|
|---|
| 372 |
/** |
|---|
| 373 |
* Attempts to convert an array to YAML |
|---|
| 374 |
* @access private |
|---|
| 375 |
* @return string |
|---|
| 376 |
* @param $array The array you want to convert |
|---|
| 377 |
* @param $indent The indent of the current level |
|---|
| 378 |
*/ |
|---|
| 379 |
function _yamlizeArray($array,$indent) { |
|---|
| 380 |
if (is_array($array)) { |
|---|
| 381 |
$string = ''; |
|---|
| 382 |
foreach ($array as $key => $value) { |
|---|
| 383 |
$string .= $this->_yamlize($key,$value,$indent); |
|---|
| 384 |
} |
|---|
| 385 |
return $string; |
|---|
| 386 |
} else { |
|---|
| 387 |
return false; |
|---|
| 388 |
} |
|---|
| 389 |
} |
|---|
| 390 |
|
|---|
| 391 |
/** |
|---|
| 392 |
* Returns YAML from a key and a value |
|---|
| 393 |
* @access private |
|---|
| 394 |
* @return string |
|---|
| 395 |
* @param $key The name of the key |
|---|
| 396 |
* @param $value The value of the item |
|---|
| 397 |
* @param $indent The indent of the current node |
|---|
| 398 |
*/ |
|---|
| 399 |
function _dumpNode($key,$value,$indent) { |
|---|
| 400 |
$value = $this->_doFolding($value,$indent); |
|---|
| 401 |
$indent = str_repeat(' ',$indent); |
|---|
| 402 |
if (is_int($key)) { |
|---|
| 403 |
// It's a sequence |
|---|
| 404 |
$string = $indent.'- '.$value."\n"; |
|---|
| 405 |
} else { |
|---|
| 406 |
// It's mapped |
|---|
| 407 |
$string = $indent.$key.': '.$value."\n"; |
|---|
| 408 |
} |
|---|
| 409 |
return $string; |
|---|
| 410 |
} |
|---|
| 411 |
|
|---|
| 412 |
/** |
|---|
| 413 |
* Folds a string of text, if necessary |
|---|
| 414 |
* @access private |
|---|
| 415 |
* @return string |
|---|
| 416 |
* @param $value The string you wish to fold |
|---|
| 417 |
*/ |
|---|
| 418 |
function _doFolding($value,$indent) { |
|---|
| 419 |
// Don't do anything if wordwrap is set to 0 |
|---|
| 420 |
if ($this->_dumpWordWrap === 0) { |
|---|
| 421 |
return $value; |
|---|
| 422 |
} |
|---|
| 423 |
|
|---|
| 424 |
if (strlen($value) > $this->_dumpWordWrap) { |
|---|
| 425 |
$indent += $this->_dumpIndent; |
|---|
| 426 |
$indent = str_repeat(' ',$indent); |
|---|
| 427 |
$wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); |
|---|
| 428 |
$value = ">\n".$indent.$wrapped; |
|---|
| 429 |
} |
|---|
| 430 |
return $value; |
|---|
| 431 |
} |
|---|
| 432 |
|
|---|
| 433 |
/* Methods used in loading */ |
|---|
| 434 |
|
|---|
| 435 |
/** |
|---|
| 436 |
* Finds and returns the indentation of a YAML line |
|---|
| 437 |
* @access private |
|---|
| 438 |
* @return int |
|---|
| 439 |
* @param string $line A line from the YAML file |
|---|
| 440 |
*/ |
|---|
| 441 |
function _getIndent($line) { |
|---|
| 442 |
preg_match('/^\s{1,}/',$line,$match); |
|---|
| 443 |
if (!empty($match[0])) { |
|---|
| 444 |
$indent = substr_count($match[0],' '); |
|---|
| 445 |
} else { |
|---|
| 446 |
$indent = 0; |
|---|
| 447 |
} |
|---|
| 448 |
return $indent; |
|---|
| 449 |
} |
|---|
| 450 |
|
|---|
| 451 |
/** |
|---|
| 452 |
* Parses YAML code and returns an array for a node |
|---|
| 453 |
* @access private |
|---|
| 454 |
* @return array |
|---|
| 455 |
* @param string $line A line from the YAML file |
|---|
| 456 |
*/ |
|---|
| 457 |
function _parseLine($line) { |
|---|
| 458 |
$line = trim($line); |
|---|
| 459 |
|
|---|
| 460 |
if (preg_match('/^-(.*):$/',$line)) { |
|---|
| 461 |
// It's a mapped sequence |
|---|
| 462 |
$key = trim(substr(substr($line,1),0,-1)); |
|---|
| 463 |
$array[$key] = ''; |
|---|
| 464 |
} elseif ($line[0] == '-' && substr($line,0,3) != '---') { |
|---|
| 465 |
// It's a list item but not a new stream |
|---|
| 466 |
if (strlen($line) > 1) { |
|---|
| 467 |
$value = trim(substr($line,1)); |
|---|
| 468 |
// Set the type of the value. Int, string, etc |
|---|
| 469 |
$value = $this->_toType($value); |
|---|
| 470 |
$array[] = $value; |
|---|
| 471 |
} else { |
|---|
| 472 |
$array[] = array(); |
|---|
| 473 |
} |
|---|
| 474 |
} elseif (preg_match('/^(.+):/',$line,$key)) { |
|---|
| 475 |
// It's a key/value pair most likely |
|---|
| 476 |
// If the key is in double quotes pull it out |
|---|
| 477 |
if (preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { |
|---|
| 478 |
$value = trim(str_replace($matches[1],'',$line)); |
|---|
| 479 |
$key = $matches[2]; |
|---|
| 480 |
} else { |
|---|
| 481 |
// Do some guesswork as to the key and the value |
|---|
| 482 |
$explode = explode(':',$line); |
|---|
| 483 |
$key = trim($explode[0]); |
|---|
| 484 |
array_shift($explode); |
|---|
| 485 |
$value = trim(implode(':',$explode)); |
|---|
| 486 |
} |
|---|
| 487 |
|
|---|
| 488 |
// Set the type of the value. Int, string, etc |
|---|
| 489 |
$value = $this->_toType($value); |
|---|
| 490 |
if (empty($key)) { |
|---|
| 491 |
$array[] = $value; |
|---|
| 492 |
} else { |
|---|
| 493 |
$array[$key] = $value; |
|---|
| 494 |
} |
|---|
| 495 |
} |
|---|
| 496 |
return $array; |
|---|
| 497 |
} |
|---|
| 498 |
|
|---|
| 499 |
/** |
|---|
| 500 |
* Finds the type of the passed value, returns the value as the new type. |
|---|
| 501 |
* @access private |
|---|
| 502 |
* @param string $value |
|---|
| 503 |
* @return mixed |
|---|
| 504 |
*/ |
|---|
| 505 |
function _toType($value) { |
|---|
| 506 |
if (preg_match('/^["\'](.*)["\']/U',$value,$matches)) { |
|---|
| 507 |
// Cut out comments |
|---|
| 508 |
$value = (string)$matches[1]; |
|---|
| 509 |
} elseif (preg_match('/^\\[(.+)\\]$/',$value,$matches)) { |
|---|
| 510 |
// Inline Sequence |
|---|
| 511 |
|
|---|
| 512 |
// Take out strings sequences and mappings |
|---|
| 513 |
$explode = $this->_inlineEscape($matches[1]); |
|---|
| 514 |
|
|---|
| 515 |
// Propogate value array |
|---|
| 516 |
$value = array(); |
|---|
| 517 |
foreach ($explode as $v) { |
|---|
| 518 |
$value[] = $this->_toType($v); |
|---|
| 519 |
} |
|---|
| 520 |
} elseif (strpos($value,': ')!==false && !preg_match('/^{(.+)/',$value)) { |
|---|
| 521 |
// It's a map |
|---|
| 522 |
$array = explode(': ',$value); |
|---|
| 523 |
$key = trim($array[0]); |
|---|
| 524 |
array_shift($array); |
|---|
| 525 |
$value = trim(implode(': ',$array)); |
|---|
| 526 |
$value = $this->_toType($value); |
|---|
| 527 |
$value = array($key => $value); |
|---|
| 528 |
} elseif (preg_match("/{(.+)}$/",$value,$matches)) { |
|---|
| 529 |
// Inline Mapping |
|---|
| 530 |
|
|---|
| 531 |
// Take out strings sequences and mappings |
|---|
| 532 |
$explode = $this->_inlineEscape($matches[1]); |
|---|
| 533 |
|
|---|
| 534 |
// Propogate value array |
|---|
| 535 |
$array = array(); |
|---|
| 536 |
foreach ($explode as $v) { |
|---|
| 537 |
$array = $array + $this->_toType($v); |
|---|
| 538 |
} |
|---|
| 539 |
$value = $array; |
|---|
| 540 |
} elseif (strtolower($value) == 'null' or $value == '' or $value == '~') { |
|---|
| 541 |
$value = NULL; |
|---|
| 542 |
} elseif (ctype_digit($value)) { |
|---|
| 543 |
$value = (int)$value; |
|---|
| 544 |
} elseif (strtolower($value) == 'true' or $value == '+') { |
|---|
| 545 |
$value = TRUE; |
|---|
| 546 |
} elseif (strtolower($value) == 'false' or $value == '-') { |
|---|
| 547 |
$value = FALSE; |
|---|
| 548 |
} elseif (is_numeric($value)) { |
|---|
| 549 |
$value = (float)$value; |
|---|
| 550 |
} else { |
|---|
| 551 |
// Just a normal string, right? |
|---|
| 552 |
$value = trim(preg_replace('/#(.+)$/','',$value)); |
|---|
| 553 |
} |
|---|
| 554 |
|
|---|
| 555 |
return $value; |
|---|
| 556 |
} |
|---|
| 557 |
|
|---|
| 558 |
/** |
|---|
| 559 |
* Used in inlines to check for more inlines or quoted strings |
|---|
| 560 |
* @access private |
|---|
| 561 |
* @return array |
|---|
| 562 |
*/ |
|---|
| 563 |
function _inlineEscape($inline) { |
|---|
| 564 |
// There's gotta be a cleaner way to do this... |
|---|
| 565 |
// While pure sequences seem to be nesting just fine, |
|---|
| 566 |
// pure mappings and mappings with sequences inside can't go very |
|---|
| 567 |
// deep. This needs to be fixed. |
|---|
| 568 |
|
|---|
| 569 |
// Check for strings |
|---|
| 570 |
if (preg_match_all('/"([^"]+)"/',$inline,$strings)) { |
|---|
| 571 |
$strings = $strings[1]; |
|---|
| 572 |
$inline = preg_replace('/"([^"]+)"/','YAMLString',$inline); |
|---|
| 573 |
} |
|---|
| 574 |
|
|---|
| 575 |
// Check for sequences |
|---|
| 576 |
if (preg_match_all('/\[(.+)\]/U',$inline,$seqs)) { |
|---|
| 577 |
$inline = preg_replace('/\[(.+)\]/U','YAMLSeq',$inline); |
|---|
| 578 |
$seqs = $seqs[0]; |
|---|
| 579 |
} |
|---|
| 580 |
|
|---|
| 581 |
// Check for mappings |
|---|
| 582 |
if (preg_match_all('/{(.+)}/U',$inline,$maps)) { |
|---|
| 583 |
$inline = preg_replace('/{(.+)}/U','YAMLMap',$inline); |
|---|
| 584 |
$maps = $maps[0]; |
|---|
| 585 |
} |
|---|
| 586 |
|
|---|
| 587 |
$explode = explode(', ',$inline); |
|---|
| 588 |
|
|---|
| 589 |
// Re-add the strings |
|---|
| 590 |
if (!empty($strings)) { |
|---|
| 591 |
$i = 0; |
|---|
| 592 |
foreach ($explode as $key => $value) { |
|---|
| 593 |
if ($value == 'YAMLString') { |
|---|
| 594 |
$explode[$key] = $strings[$i]; |
|---|
| 595 |
++$i; |
|---|
| 596 |
} |
|---|
| 597 |
} |
|---|
| 598 |
} |
|---|
| 599 |
|
|---|
| 600 |
// Re-add the sequences |
|---|
| 601 |
if (!empty($seqs)) { |
|---|
| 602 |
$i = 0; |
|---|
| 603 |
foreach ($explode as $key => $value) { |
|---|
| 604 |
if (strpos($value,'YAMLSeq') !== false) { |
|---|
| 605 |
$explode[$key] = str_replace('YAMLSeq',$seqs[$i],$value); |
|---|
| 606 |
++$i; |
|---|
| 607 |
} |
|---|
| 608 |
} |
|---|
| 609 |
} |
|---|
| 610 |
|
|---|
| 611 |
// Re-add the mappings |
|---|
| 612 |
if (!empty($maps)) { |
|---|
| 613 |
$i = 0; |
|---|
| 614 |
foreach ($explode as $key => $value) { |
|---|
| 615 |
if (strpos($value,'YAMLMap') !== false) { |
|---|
| 616 |
$explode[$key] = str_replace('YAMLMap',$maps[$i],$value); |
|---|
| 617 |
++$i; |
|---|
| 618 |
} |
|---|
| 619 |
} |
|---|
| 620 |
} |
|---|
| 621 |
|
|---|
| 622 |
return $explode; |
|---|
| 623 |
} |
|---|
| 624 |
|
|---|
| 625 |
/** |
|---|
| 626 |
* Builds the PHP array from all the YAML nodes we've gathered |
|---|
| 627 |
* @access private |
|---|
| 628 |
* @return array |
|---|
| 629 |
*/ |
|---|
| 630 |
function _buildArray() { |
|---|
| 631 |
$trunk = array(); |
|---|
| 632 |
foreach ($this->_indentSort[0] as $n) { |
|---|
| 633 |
if (empty($n->parent)) { |
|---|
| 634 |
$this->_nodeArrayizeData($n); |
|---|
| 635 |
// Check for references and copy the needed data to complete them. |
|---|
| 636 |
$this->_makeReferences($n); |
|---|
| 637 |
// Merge our data with the big array we're building |
|---|
| 638 |
$trunk = array_kmerge($trunk,$n->data); |
|---|
| 639 |
} |
|---|
| 640 |
} |
|---|
| 641 |
|
|---|
| 642 |
return $trunk; |
|---|
| 643 |
} |
|---|
| 644 |
|
|---|
| 645 |
/** |
|---|
| 646 |
* Traverses node-space and sets references (& and *) accordingly |
|---|
| 647 |
* @access private |
|---|
| 648 |
* @return bool |
|---|
| 649 |
*/ |
|---|
| 650 |
function _linkReferences() { |
|---|
| 651 |
if (is_array($this->_haveRefs)) { |
|---|
| 652 |
foreach ($this->_haveRefs as $node) { |
|---|
| 653 |
if (!empty($node->data)) { |
|---|
| 654 |
$key = key($node->data); |
|---|
| 655 |
// If it's an array, don't check. |
|---|
| 656 |
if (is_array($node->data[$key])) { |
|---|
| 657 |
foreach ($node->data[$key] as $k => $v) { |
|---|
| 658 |
$this->_linkRef($node,$key,$k,$v); |
|---|
| 659 |
} |
|---|
| 660 |
} else { |
|---|
| 661 |
$this->_linkRef($node,$key); |
|---|
| 662 |
} |
|---|
| 663 |
} |
|---|
| 664 |
} |
|---|
| 665 |
} |
|---|
| 666 |
return true; |
|---|
| 667 |
} |
|---|
| 668 |
|
|---|
| 669 |
function _linkRef(&$n,$key,$k = NULL,$v = NULL) { |
|---|
| 670 |
if (empty($k) && empty($v)) { |
|---|
| 671 |
// Look for &refs |
|---|
| 672 |
if (preg_match('/^&([^ ]+)/',$n->data[$key],$matches)) { |
|---|
| 673 |
// Flag the node so we know it's a reference |
|---|
| 674 |
$this->_allNodes[$n->id]->ref = substr($matches[0],1); |
|---|
| 675 |
$this->_allNodes[$n->id]->data[$key] = |
|---|
| 676 |
substr($n->data[$key],strlen($matches[0])+1); |
|---|
| 677 |
// Look for *refs |
|---|
| 678 |
} elseif (preg_match('/^\*([^ ]+)/',$n->data[$key],$matches)) { |
|---|
| 679 |
$ref = substr($matches[0],1); |
|---|
| 680 |
// Flag the node as having a reference |
|---|
| 681 |
$this->_allNodes[$n->id]->refKey = $ref; |
|---|
| 682 |
} |
|---|
| 683 |
} elseif (!empty($k) && !empty($v)) { |
|---|
| 684 |
if (preg_match('/^&([^ ]+)/',$v,$matches)) { |
|---|
| 685 |
// Flag the node so we know it's a reference |
|---|
| 686 |
$this->_allNodes[$n->id]->ref = substr($matches[0],1); |
|---|
| 687 |
$this->_allNodes[$n->id]->data[$key][$k] = |
|---|
| 688 |
substr($v,strlen($matches[0])+1); |
|---|
| 689 |
// Look for *refs |
|---|
| 690 |
} elseif (preg_match('/^\*([^ ]+)/',$v,$matches)) { |
|---|
| 691 |
$ref = substr($matches[0],1); |
|---|
| 692 |
// Flag the node as having a reference |
|---|
| 693 |
$this->_allNodes[$n->id]->refKey = $ref; |
|---|
| 694 |
} |
|---|
| 695 |
} |
|---|
| 696 |
} |
|---|
| 697 |
|
|---|
| 698 |
/** |
|---|
| 699 |
* Finds the children of a node and aids in the building of the PHP array |
|---|
| 700 |
* @access private |
|---|
| 701 |
* @param int $nid The id of the node whose children we're gathering |
|---|
| 702 |
* @return array |
|---|
| 703 |
*/ |
|---|
| 704 |
function _gatherChildren($nid) { |
|---|
| 705 |
$return = array(); |
|---|
| 706 |
$node =& $this->_allNodes[$nid]; |
|---|
| 707 |
foreach ($this->_allNodes as $z) { |
|---|
| 708 |
if ($z->parent == $node->id) { |
|---|
| 709 |
// We found a child |
|---|
| 710 |
$this->_nodeArrayizeData($z); |
|---|
| 711 |
// Check for references |
|---|
| 712 |
$this->_makeReferences($z); |
|---|
| 713 |
// Merge with the big array we're returning |
|---|
| 714 |
// The big array being all the data of the children of our parent node |
|---|
| 715 |
$return = array_kmerge($return,$z->data); |
|---|
| 716 |
} |
|---|
| 717 |
} |
|---|
| 718 |
return $return; |
|---|
| 719 |
} |
|---|
| 720 |
|
|---|
| 721 |
/** |
|---|
| 722 |
* Turns a node's data and its children's data into a PHP array |
|---|
| 723 |
* |
|---|
| 724 |
* @access private |
|---|
| 725 |
* @param array $node The node which you want to arrayize |
|---|
| 726 |
* @return boolean |
|---|
| 727 |
*/ |
|---|
| 728 |
function _nodeArrayizeData(&$node) { |
|---|
| 729 |
if (is_array($node->data) && $node->children == true) { |
|---|
| 730 |
// This node has children, so we need to find them |
|---|
| 731 |
$childs = $this->_gatherChildren($node->id); |
|---|
| 732 |
// We've gathered all our children's data and are ready to use it |
|---|
| 733 |
$key = key($node->data); |
|---|
| 734 |
$key = empty($key) ? 0 : $key; |
|---|
| 735 |
// If it's an array, add to it of course |
|---|
| 736 |
if (is_array($node->data[$key])) { |
|---|
| 737 |
$node->data[$key] = array_kmerge($node->data[$key],$childs); |
|---|
| 738 |
} else { |
|---|
| 739 |
$node->data[$key] = $childs; |
|---|
| 740 |
} |
|---|
| 741 |
} elseif (!is_array($node->data) && $node->children == true) { |
|---|
| 742 |
// Same as above, find the children of this node |
|---|
| 743 |
$childs = $this->_gatherChildren($node->id); |
|---|
| 744 |
$node->data = array(); |
|---|
| 745 |
$node->data[] = $childs; |
|---|
| 746 |
} |
|---|
| 747 |
|
|---|
| 748 |
// We edited $node by reference, so just return true |
|---|
| 749 |
return true; |
|---|
| 750 |
} |
|---|
| 751 |
|
|---|
| 752 |
/** |
|---|
| 753 |
* Traverses node-space and copies references to / from this object. |
|---|
| 754 |
* @access private |
|---|
| 755 |
* @param object $z A node whose references we wish to make real |
|---|
| 756 |
* @return bool |
|---|
| 757 |
*/ |
|---|
| 758 |
function _makeReferences(&$z) { |
|---|
| 759 |
// It is a reference |
|---|
| 760 |
if (isset($z->ref)) { |
|---|
| 761 |
$key = key($z->data); |
|---|
| 762 |
// Copy the data to this object for easy retrieval later |
|---|
| 763 |
$this->ref[$z->ref] =& $z->data[$key]; |
|---|
| 764 |
// It has a reference |
|---|
| 765 |
} elseif (isset($z->refKey)) { |
|---|
| 766 |
if (isset($this->ref[$z->refKey])) { |
|---|
| 767 |
$key = key($z->data); |
|---|
| 768 |
// Copy the data from this object to make the node a real reference |
|---|
| 769 |
$z->data[$key] =& $this->ref[$z->refKey]; |
|---|
| 770 |
} |
|---|
| 771 |
} |
|---|
| 772 |
return true; |
|---|
| 773 |
} |
|---|
| 774 |
|
|---|
| 775 |
} |
|---|
| 776 |
|
|---|
| 777 |
|
|---|
| 778 |
// |
|---|
| 779 |
// An ever-so-slightly modified version of the array_kmerge() function posted |
|---|
| 780 |
// to php.net by mail at nospam dot iaindooley dot com on 2004-04-08. |
|---|
| 781 |
// http://us3.php.net/manual/en/function.array-merge.php#41394 |
|---|
| 782 |
// |
|---|
| 783 |
function array_kmerge($arr1,$arr2) { |
|---|
| 784 |
if(!is_array($arr1)) |
|---|
| 785 |
$arr1 = array(); |
|---|
| 786 |
|
|---|
| 787 |
if(!is_array($arr2)) |
|---|
| 788 |
$arr2 = array(); |
|---|
| 789 |
|
|---|
| 790 |
$keys1 = array_keys($arr1); |
|---|
| 791 |
$keys2 = array_keys($arr2); |
|---|
| 792 |
$keys = array_merge($keys1,$keys2); |
|---|
| 793 |
$vals1 = array_values($arr1); |
|---|
| 794 |
$vals2 = array_values($arr2); |
|---|
| 795 |
$vals = array_merge($vals1,$vals2); |
|---|
| 796 |
$ret = array(); |
|---|
| 797 |
|
|---|
| 798 |
foreach($keys as $key) { |
|---|
| 799 |
list($unused,$val) = each($vals); |
|---|
| 800 |
// This is the good part! If a key already exists, but it's part of a |
|---|
| 801 |
// sequence (an int), just keep addin' numbers until we find a fresh one. |
|---|
| 802 |
if (isset($ret[$key]) and is_int($key)) { |
|---|
| 803 |
while (array_key_exists($key, $ret)) { |
|---|
| 804 |
$key++; |
|---|
| 805 |
} |
|---|
| 806 |
} |
|---|
| 807 |
$ret[$key] = $val; |
|---|
| 808 |
} |
|---|
| 809 |
|
|---|
| 810 |
return $ret; |
|---|
| 811 |
} |
|---|
| 812 |
?> |
|---|
| 813 |
|
|---|
| 814 |
________________________________________________________________________________ |
|---|
| 815 |
|
|---|
| 816 |
|
|---|
| 817 |
<?php |
|---|
| 818 |
/** |
|---|
| 819 |
* @package jelix-scripts |
|---|
| 820 |
* @version $Id$ |
|---|
| 821 |
* @author Loic Mathaud |
|---|
| 822 |
* @contributor |
|---|
| 823 |
* @copyright 2005-2006 Jouanneau laurent |
|---|
| 824 |
* @link http://www.jelix.org |
|---|
| 825 |
* @licence GNU General Public Licence see LICENCE file or http://www.gnu.org/licenses/gpl.html |
|---|
| 826 |
*/ |
|---|
| 827 |
|
|---|
| 828 |
|
|---|
| 829 |
|
|---|
| 830 |
class populatedbCommand extends JelixScriptCommand { |
|---|
| 831 |
|
|---|
| 832 |
public $name = 'populatedb'; |
|---|
| 833 |
public $allowed_options=array('-profil'=>true); |
|---|
| 834 |
public $allowed_parameters=array('module'=>true); |
|---|
| 835 |
|
|---|
| 836 |
public $syntaxhelp = "[-profil nom] MODULE"; |
|---|
| 837 |
public $help =" |
|---|
| 838 |
Ins� un jeu de donn� de test dans une table |
|---|
| 839 |
|
|---|
| 840 |
-profil (facultatif) : indique le profil �tiliser pour se connecter � la base de donn� |
|---|
| 841 |
|
|---|
| 842 |
MODULE : le nom du module concern� DAO : nom du dao �tiliser. |
|---|
| 843 |
|
|---|
| 844 |
|
|---|
| 845 |
Vous devez cr� un fichier au format YAML nomm�ata.yml |
|---|
| 846 |
Ce fichier est �lacer dans un r�rtoire data/ (�r�) dans le module souhait� Structure du fichier : |
|---|
| 847 |
|
|---|
| 848 |
nom_dao_1: |
|---|
| 849 |
- |
|---|
| 850 |
champ_1: valeur |
|---|
| 851 |
champ_2: valeur |
|---|
| 852 |
- |
|---|
| 853 |
champ_1: valeur |
|---|
| 854 |
... |
|---|
| 855 |
|
|---|
| 856 |
nom_dao_2: |
|---|
| 857 |
- |
|---|
| 858 |
champ_1: valeur |
|---|
| 859 |
champ_2: valeur |
|---|
| 860 |
..."; |
|---|
| 861 |
|
|---|
| 862 |
|
|---|
| 863 |
public function run(){ |
|---|
| 864 |
jxs_init_jelix_env(); |
|---|
| 865 |
|
|---|
| 866 |
$path = $this->getModulePath($this->_parameters['module']); |
|---|
| 867 |
$filename = $path.'/data/data.yml'; |
|---|
| 868 |
|
|---|
| 869 |
if (!file_exists($filename)) { |
|---|
| 870 |
die("Error: ". $filename ." doesn't exist\n"); |
|---|
| 871 |
} |
|---|
| 872 |
|
|---|
| 873 |
// include spyc class |
|---|
| 874 |
include(JELIXS_APPS_BASEPATH .'/lib/spyc/spyc.php'); |
|---|
| 875 |
|
|---|
| 876 |
$recordset = Spyc::YAMLLoad($filename); |
|---|
| 877 |
|
|---|
| 878 |
$module = $this->_parameters['module']; |
|---|
| 879 |
|
|---|
| 880 |
foreach ($recordset as $name => $records) { |
|---|
| 881 |
$selector = $module .'~'. $name; |
|---|
| 882 |
|
|---|
| 883 |
$dao = jDAO::get($selector); |
|---|
| 884 |
$rec = jDAO::createRecord($selector); |
|---|
| 885 |
|
|---|
| 886 |
foreach ($records as $record) { |
|---|
| 887 |
foreach ($record as $field => $value) { |
|---|
| 888 |
$rec->$field = $value; |
|---|
| 889 |
} |
|---|
| 890 |
$dao->insert($rec); |
|---|
| 891 |
} |
|---|
| 892 |
} |
|---|
| 893 |
} |
|---|
| 894 |
} |
|---|
| 895 |
|
|---|
| 896 |
|
|---|
| 897 |
?> |
|---|
| 898 |
|
|---|
| 899 |
-------------------------------------------------------------------------------- |
|---|
| 900 |
|
|---|
| 901 |
post: |
|---|
| 902 |
- |
|---|
| 903 |
id:1 |
|---|
| 904 |
title: My first post ! |
|---|
| 905 |
body: Here is my first post with Jelix :) Enjoy ! |
|---|
| 906 |
date: "NOW()" |
|---|
| 907 |
- |
|---|
| 908 |
id:2 |
|---|
| 909 |
title: Hello guys ! |
|---|
| 910 |
body: Wouah Jelix rox :) ! |
|---|
| 911 |
date: "NOW()" |
|---|
| 912 |
- |
|---|
| 913 |
id:3 |
|---|
| 914 |
title : Test of title |
|---|
| 915 |
body: yeah, nice test of blogging :) |
|---|
| 916 |
date: "NOW()" |
|---|
| 917 |
|
|---|
| 918 |
- |
|---|
| 919 |
id:4 |
|---|
| 920 |
title: Another post in Jelix |
|---|
| 921 |
body: this app rox !! |
|---|
| 922 |
date: "NOW()" |
|---|
| 923 |
|
|---|
| 924 |
comment: |
|---|
| 925 |
- |
|---|
| 926 |
id: |
|---|
| 927 |
post_id:1 |
|---|
| 928 |
body: �roxe ici ! |
|---|
| 929 |
- |
|---|
| 930 |
id: |
|---|
| 931 |
post_id:1 |
|---|
| 932 |
body: vraiment cool ce Jelix, on s'amuse bien avec :) |
|---|
| 933 |
|
|---|
| 934 |
- |
|---|
| 935 |
id: |
|---|
| 936 |
post_id:2 |
|---|
| 937 |
body: kewl ton blog, v1 laCH t coms sur le m1 !! |
|---|
| 938 |
|
|---|