diff --git a/composer.json b/composer.json index 2c2cacea..7fe4c937 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,15 @@ "jackalope/jackalope": "~1.1", "phpcr/phpcr": "~2.1", "phpcr/phpcr-utils": "~1.2", - "symfony/finder": "~2.3" + "symfony/finder": "~2.3", + "kukulich/fshl": "dev-symfony-console-formatter" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/dantleech/fshl" + } + ], "minimum-stability": "dev", "require-dev": { "mockery/mockery": "0.9", diff --git a/features/phpcr_node_show.feature b/features/phpcr_node_show.feature new file mode 100644 index 00000000..e283c7aa --- /dev/null +++ b/features/phpcr_node_show.feature @@ -0,0 +1,25 @@ +Feature: Show the current nodes shared set + In order to show the shared set to which the current node belongs + As a user that is logged into the shell + I need to be able to do that + + Background: + Given that I am logged in as "testuser" + And the "cms.xml" fixtures are loaded + + Scenario: Show the current node + Given the current node is "/foobar" + And I execute the "node:show ." command + Then the command should not fail + And I should see the following: + """ + <?xml version="1.0" encoding="UTF-8"?> + <sv:node xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:ns="http://namespace.com/ns" xmlns:test="http://liip.to/jackalope" xmlns:phpcr="http://www.doctrine-project.org/projects/phpcr_odm" xmlns:dcms="http://dcms.com/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:slinp="asd" xmlns:fn_old="http://www.w3.org/2004/10/xpath-functions" xmlns:crx="http://www.day.com/crx/1.0" xmlns:lx="http://flux-cms.org/2.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:dtl="http://www.dantleech.com" xmlns:vlt="http://www.day.com/jcr/vault/1.0" xmlns:my_prefix="http://a_new_namespace" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:rep="internal" sv:name="jcr:root"> + <sv:property sv:name="jcr:primaryType" sv:type="Name"> + <sv:value>rep:root</sv:value> + </sv:property> + <sv:property sv:name="jcr:mixinTypes" sv:type="Name" sv:multiple="true"> + <sv:value>rep:AccessControllable</sv:value> + </sv:property> + </sv:node> + """ diff --git a/spec/PHPCR/Shell/Console/Helper/ResultFormatterHelperSpec.php b/spec/PHPCR/Shell/Console/Helper/ResultFormatterHelperSpec.php index 30619d47..667d1c0f 100644 --- a/spec/PHPCR/Shell/Console/Helper/ResultFormatterHelperSpec.php +++ b/spec/PHPCR/Shell/Console/Helper/ResultFormatterHelperSpec.php @@ -11,4 +11,23 @@ function it_is_initializable() { $this->shouldHaveType('PHPCR\Shell\Console\Helper\ResultFormatterHelper'); } + + function it_should_indent_a_given_xml_string() + { + $xmlString = <<<EOT +<xml><thisis><foobar></foobar></thisis></xml> +EOT + ; + + $this->formatXml($xmlString)->shouldReturn(<<<EOT +<?xml version="1.0"?> +<xml> + <thisis> + <foobar/> + </thisis> +</xml> + +EOT + ); + } } diff --git a/src/PHPCR/Shell/Console/Application/ShellApplication.php b/src/PHPCR/Shell/Console/Application/ShellApplication.php index 978a5e22..1007ad35 100644 --- a/src/PHPCR/Shell/Console/Application/ShellApplication.php +++ b/src/PHPCR/Shell/Console/Application/ShellApplication.php @@ -31,6 +31,7 @@ use PHPCR\Shell\Transport\TransportRegistry; use PHPCR\Shell\Config\ProfileLoader; use PHPCR\Shell\Console\Helper\TableHelper; +use PHPCR\Shell\Console\Helper\SyntaxHighlighterHelper; /** * Main application for PHPCRSH @@ -132,6 +133,7 @@ private function registerHelpers() new ResultFormatterHelper(), new TextHelper(), new TableHelper(), + new SyntaxHighlighterHelper(), $phpcrHelper ); @@ -173,6 +175,7 @@ private function registerCommands() $this->add(new CommandPhpcr\WorkspaceListCommand()); $this->add(new CommandPhpcr\NodeCloneCommand()); $this->add(new CommandPhpcr\NodeCopyCommand()); + $this->add(new CommandPhpcr\NodeShowCommand()); $this->add(new CommandPhpcr\WorkspaceNamespaceListCommand()); $this->add(new CommandPhpcr\WorkspaceNamespaceRegisterCommand()); $this->add(new CommandPhpcr\WorkspaceNamespaceUnregisterCommand()); @@ -272,6 +275,18 @@ private function configureFormatter(OutputFormatter $formatter) $style = new OutputFormatterStyle(null, 'red', array()); $formatter->setStyle('exception', $style); + + // syntax highlighting + $colors = array( + 'html-tag' => 'magenta', + 'html-tagin' => 'yellow', + 'html-quote' => null, + ); + + foreach ($colors as $tag => $color) { + $style = new OutputFormatterStyle($color, null, array()); + $formatter->setStyle($tag, $style); + } } /** diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/NodeShowCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/NodeShowCommand.php new file mode 100644 index 00000000..23bcfa9d --- /dev/null +++ b/src/PHPCR/Shell/Console/Command/Phpcr/NodeShowCommand.php @@ -0,0 +1,40 @@ +<?php + +namespace PHPCR\Shell\Console\Command\Phpcr; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputArgument; + +class NodeShowCommand extends Command +{ + protected function configure() + { + $this->setName('node:show'); + $this->setDescription('Show a node'); + $this->addArgument('path', InputArgument::REQUIRED, 'Path to source node'); + $this->setHelp(<<<HERE +HERE + ); + } + + public function execute(InputInterface $input, OutputInterface $output) + { + $session = $this->getHelper('phpcr')->getSession(); + $absPath = $session->getAbsPath($input->getArgument('path')); + $formatter = $this->getHelper('result_formatter'); + $highlighter = $this->getHelper('syntax_highlighter'); + + $skipBinary = true; + $noRecurse = true; + + ob_start(); + $stream = fopen('php://output', 'w+', false); + $session->exportSystemView($absPath, $stream, $skipBinary, $noRecurse); + $out = ob_get_clean(); + fclose($stream); + + $output->writeln($highlighter->highlightXml($formatter->formatXml($out))); + } +} diff --git a/src/PHPCR/Shell/Console/Helper/ResultFormatterHelper.php b/src/PHPCR/Shell/Console/Helper/ResultFormatterHelper.php index 2d16eca6..daac7559 100644 --- a/src/PHPCR/Shell/Console/Helper/ResultFormatterHelper.php +++ b/src/PHPCR/Shell/Console/Helper/ResultFormatterHelper.php @@ -25,7 +25,6 @@ public function getName() return 'result_formatter'; } - /** * Return the name of a property from its enumeration (i.e. * the value of its CONSTANT) @@ -171,4 +170,16 @@ public function formatException(\Exception $e) return sprintf('[%s] %s', get_class($e), $e->getMessage()); } + + public function formatXml($xmlString) + { + // format output + $dom = new \DOMDocument('1.0'); + $dom->loadXml($xmlString); + $dom->preserveWhitespace = true; + $dom->formatOutput = true; + $out = $dom->saveXml(); + + return $out; + } } diff --git a/src/PHPCR/Shell/Console/Helper/SyntaxHighlighterHelper.php b/src/PHPCR/Shell/Console/Helper/SyntaxHighlighterHelper.php new file mode 100644 index 00000000..6d6450df --- /dev/null +++ b/src/PHPCR/Shell/Console/Helper/SyntaxHighlighterHelper.php @@ -0,0 +1,20 @@ +<?php + +namespace PHPCR\Shell\Console\Helper; + +use Symfony\Component\Console\Helper\Helper; + +class SyntaxHighlighterHelper extends Helper +{ + public function getName() + { + return 'syntax_highlighter'; + } + + public function highlightXml($string) + { + $highlighter = new \FSHL\Highlighter(new \FSHL\Output\SymfonyConsole()); + $highlighter->setLexer(new \FSHL\Lexer\Html()); + return $highlighter->highlight($string); + } +}