104 if (!$this->stderr) {
105 $this->stderr =
fopen(
'php://stderr',
'w');
107 if (!$this->stdout) {
108 $this->stdout =
fopen(
'php://stdout',
'w');
111 $this->stdin =
fopen(
'php://stdin',
'r');
158 $this->format = $value;
167 if (version_compare(PHP_VERSION,
'5.4.0') >= 0) {
168 $this->pretty =
true;
172 $this->forgiving =
true;
180 $this->inputFormat =
'json';
192 $this->inputFormat =
'mimedir';
207 if (count($positional) === 0) {
212 if (count($positional) === 1) {
216 if (count($positional) > 3) {
220 if (!in_array($positional[0], [
'validate',
'repair',
'convert',
'color'])) {
226 $this->
log(
'Error: ' . $e->getMessage(),
'red');
230 $command = $positional[0];
232 $this->inputPath = $positional[1];
233 $this->outputPath = isset($positional[2]) ? $positional[2] :
'-';
235 if ($this->outputPath !==
'-') {
236 $this->stdout =
fopen($this->outputPath,
'w');
239 if (!$this->inputFormat) {
240 if (substr($this->inputPath, -5) ===
'.json') {
241 $this->inputFormat =
'json';
243 $this->inputFormat =
'mimedir';
246 if (!$this->format) {
247 if (substr($this->outputPath, -5) ===
'.json') {
248 $this->format =
'json';
250 $this->format =
'mimedir';
261 $returnCode = $this->$command(
$input);
262 if ($returnCode !== 0) $realCode = $returnCode;
269 $this->
log(
'Error: ' . $e->getMessage(),
'red');
284 $this->
log(
'Usage:',
'yellow');
285 $this->
log(
" vobject [options] command [arguments]");
287 $this->
log(
'Options:',
'yellow');
288 $this->
log($this->
colorize(
'green',
' -q ') .
"Don't output anything.");
289 $this->
log($this->
colorize(
'green',
' -help -h ') .
"Display this help message.");
290 $this->
log($this->
colorize(
'green',
' --format ') .
"Convert to a specific format. Must be one of: vcard, vcard21,");
291 $this->
log($this->
colorize(
'green',
' --forgiving ') .
"Makes the parser less strict.");
292 $this->
log(
" vcard30, vcard40, icalendar20, jcal, jcard, json, mimedir.");
293 $this->
log($this->
colorize(
'green',
' --inputformat ') .
"If the input format cannot be guessed from the extension, it");
294 $this->
log(
" must be specified here.");
296 if (version_compare(PHP_VERSION,
'5.4.0') >= 0) {
297 $this->
log($this->
colorize(
'green',
' --pretty ') .
"json pretty-print.");
300 $this->
log(
'Commands:',
'yellow');
301 $this->
log($this->
colorize(
'green',
' validate') .
' source_file Validates a file for correctness.');
302 $this->
log($this->
colorize(
'green',
' repair') .
' source_file [output_file] Repairs a file.');
303 $this->
log($this->
colorize(
'green',
' convert') .
' source_file [output_file] Converts a file.');
304 $this->
log($this->
colorize(
'green',
' color') .
' source_file Colorize a file, useful for debbugging.');
308 If source_file
is set as
'-', STDIN will be used.
309 If output_file
is omitted, STDOUT will be used.
310 All other output
is sent to STDERR.
315 $this->
log(
'Examples:',
'yellow');
316 $this->
log(
' vobject convert contact.vcf contact.json');
317 $this->
log(
' vobject convert --format=vcard40 old.vcf new.vcf');
318 $this->
log(
' vobject convert --inputformat=json --format=mimedir - -');
319 $this->
log(
' vobject color calendar.ics');
321 $this->
log(
'https://github.com/fruux/sabre-vobject',
'purple');
336 switch ($vObj->name) {
338 $this->
log(
"iCalendar: " . (
string)$vObj->VERSION);
341 $this->
log(
"vCard: " . (
string)$vObj->VERSION);
347 $this->
log(
" No warnings!");
359 if ($warn[
'node'] instanceof
Property) {
360 $extra =
' (property: "' . $warn[
'node']->name .
'")';
362 $this->
log(
" [" . $levels[$warn[
'level']] .
'] ' . $warn[
'message'] . $extra);
383 switch ($vObj->name) {
385 $this->
log(
"iCalendar: " . (
string)$vObj->VERSION);
388 $this->
log(
"vCard: " . (
string)$vObj->VERSION);
394 $this->
log(
" No warnings!");
406 if ($warn[
'node'] instanceof
Property) {
407 $extra =
' (property: "' . $warn[
'node']->name .
'")';
409 $this->
log(
" [" . $levels[$warn[
'level']] .
'] ' . $warn[
'message'] . $extra);
414 fwrite($this->stdout, $vObj->
serialize());
430 $convertVersion = null;
433 switch ($this->format) {
436 if ($vObj->name ===
'VCARD') {
442 $forceInput =
'VCARD';
447 $forceInput =
'VCALENDAR';
466 if ($forceInput && $vObj->name !== $forceInput) {
467 throw new \Exception(
'You cannot convert a ' . strtolower($vObj->name) .
' to ' . $this->format);
469 if ($convertVersion) {
470 $vObj = $vObj->convert($convertVersion);
475 $jsonOptions = JSON_PRETTY_PRINT;
477 fwrite($this->stdout, json_encode($vObj->jsonSerialize(), $jsonOptions));
479 fwrite($this->stdout, $vObj->serialize());
506 protected function colorize($color, $str, $resetTo =
'default') {
517 return "\033[" . $colors[$color] .
'm' . $str .
"\033[" . $colors[$resetTo] .
"m";
529 protected function cWrite($color, $str) {
531 fwrite($this->stdout, $this->
colorize($color, $str));
537 $this->
cWrite(
'cyan',
'BEGIN');
538 $this->
cWrite(
'red',
':');
539 $this->
cWrite(
'yellow', $vObj->name .
"\n");
556 $sortScore =
function(
$key, $array) {
562 if ($array[
$key]->name ===
'VTIMEZONE') {
564 return $score +
$key;
567 return $score +
$key;
573 if ($array[
$key]->name ===
'VERSION') {
575 return $score +
$key;
579 return $score +
$key;
590 function($a, $b) use ($sortScore, $tmp) {
592 $sA = $sortScore($a, $tmp);
593 $sB = $sortScore($b, $tmp);
600 foreach ($children as $child) {
608 $this->
cWrite(
'cyan',
'END');
609 $this->
cWrite(
'red',
':');
610 $this->
cWrite(
'yellow', $vObj->name .
"\n");
623 if ($property->group) {
624 $this->
cWrite(
'default', $property->group);
625 $this->
cWrite(
'red',
'.');
628 $this->
cWrite(
'yellow', $property->name);
632 $this->
cWrite(
'red',
';');
633 $this->
cWrite(
'blue', $param->serialize());
636 $this->
cWrite(
'red',
':');
640 $this->
cWrite(
'default',
'embedded binary stripped. (' . strlen($property->
getValue()) .
' bytes)');
647 foreach ($parts as $part) {
651 $this->
cWrite(
'red', $property->delimiter);
655 foreach ((array)$part as $subPart) {
660 $this->
cWrite(
'red',
',');
666 '\\' => $this->
colorize(
'purple',
'\\\\',
'green'),
667 ';' => $this->
colorize(
'purple',
'\;',
'green'),
668 ',' => $this->
colorize(
'purple',
'\,',
'green'),
669 "\n" => $this->
colorize(
'purple',
"\\n\n\t",
'green'),
674 $this->
cWrite(
'green', $subPart);
679 $this->
cWrite(
"default",
"\n");
695 for (
$ii = 0;
$ii < count($argv);
$ii++) {
698 if (
$ii === 0)
continue;
702 if (substr($v, 0, 2) ===
'--') {
704 $optionName = substr($v, 2);
706 if (strpos($optionName,
'=')) {
707 list($optionName, $optionValue) = explode(
'=', $optionName);
709 $options[$optionName] = $optionValue;
710 } elseif (substr($v, 0, 1) ===
'-' && strlen($v) > 1) {
712 foreach (str_split(substr($v, 1)) as $option) {
737 if (!$this->parser) {
738 if ($this->inputPath !==
'-') {
739 $this->stdin =
fopen($this->inputPath,
'r');
742 if ($this->inputFormat ===
'mimedir') {
749 return $this->parser->parse();
760 protected function log($msg, $color =
'default') {
763 if ($color !==
'default') {
764 $msg = $this->
colorize($color, $msg);
766 fwrite($this->stderr, $msg .
"\n");
validate(Component $vObj)
Validates a VObject file.
main(array $argv)
Main function.
colorize($color, $str, $resetTo='default')
Returns an ansi color string for a color name.
readInput()
Reads the input file.
const VERSION
Full version number.
parseArguments(array $argv)
Parses the list of arguments.
cWrite($color, $str)
Writes out a string in specific color.
convert($vObj)
Converts a vObject file to a new format.
serializeComponent(Component $vObj)
log($msg, $color='default')
Sends a message to STDERR.
repair(Component $vObj)
Repairs a VObject file.
getParts()
Returns a multi-valued property.
This is the CLI interface for sabre-vobject.
serializeProperty(Property $property)
Colorizes a property.
serialize()
Turns the object back into a serialized blob.
const OPTION_FORGIVING
If this option is passed to the reader, it will be less strict about the validity of the lines...
parameters()
Returns an iterable list of children.
const REPAIR
The following constants are used by the validate() method.
color($vObj)
Colorizes a file.
getValue()
Returns the current value.
showHelp()
Shows the help message.
Exception thrown by parser when the end of the stream has been reached, before this was expected...
children()
Returns a flat list of all the properties and components in this component.
validate($options=0)
Validates the node for correctness.