From fa13ea38dc9f3b88e0a2cf8fbfca2e27a60a47da Mon Sep 17 00:00:00 2001 From: dantleech Date: Thu, 15 May 2014 09:14:31 +0200 Subject: [PATCH 1/3] Added ability to import a file into the repository --- features/fixtures/files/phpcrlogos.png | Bin 0 -> 19576 bytes features/phpcr_node_file_import.feature | 17 ++++++ .../Console/Application/ShellApplication.php | 1 + .../Command/Phpcr/NodeFileImportCommand.php | 56 ++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 features/fixtures/files/phpcrlogos.png create mode 100644 features/phpcr_node_file_import.feature create mode 100644 src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php diff --git a/features/fixtures/files/phpcrlogos.png b/features/fixtures/files/phpcrlogos.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6facc0d8145edaca8bbc256d06a6885d05900c GIT binary patch literal 19576 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 literal 0 HcmV?d00001 diff --git a/features/phpcr_node_file_import.feature b/features/phpcr_node_file_import.feature new file mode 100644 index 00000000..481d2174 --- /dev/null +++ b/features/phpcr_node_file_import.feature @@ -0,0 +1,17 @@ +Feature: Import an external file as to a node + In order to import an external file into the system + As a user that is logged into the shell + I should be able to run a command which does that + + Background: + Given that I am logged in as "testuser" + And the "cms.xml" fixtures are loaded + + Scenario: Import a file + Given the file "phpcr.png" contains the contents of "files/phpcrlogos.png" + Given the current node is "/" + And I execute the "node:file:import . phpcr.png" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a node at "/phpcr.png" diff --git a/src/PHPCR/Shell/Console/Application/ShellApplication.php b/src/PHPCR/Shell/Console/Application/ShellApplication.php index 3f7ffd6d..0febc116 100644 --- a/src/PHPCR/Shell/Console/Application/ShellApplication.php +++ b/src/PHPCR/Shell/Console/Application/ShellApplication.php @@ -189,6 +189,7 @@ private function registerCommands() $this->add(new CommandPhpcr\NodeCreateCommand()); $this->add(new CommandPhpcr\NodeCorrespondingCommand()); $this->add(new CommandPhpcr\NodeDefinitionCommand()); + $this->add(new CommandPhpcr\NodeFileImportCommand()); $this->add(new CommandPhpcr\NodePropertySetCommand()); $this->add(new CommandPhpcr\NodeSetPrimaryTypeCommand()); $this->add(new CommandPhpcr\NodeRenameCommand()); diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php new file mode 100644 index 00000000..9e3e4c0f --- /dev/null +++ b/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php @@ -0,0 +1,56 @@ +setName('node:file:import'); + $this->setDescription('Import a file at the given path'); + $this->addArgument('path', InputArgument::REQUIRED, 'Path to import file to'); + $this->addArgument('file', InputArgument::REQUIRED, 'Path to file to import'); + $this->setHelp(<<nt:file. The new +node will be named after the file. + +The mime-type will be inferred automatically.. +HERE + ); + } + + public function execute(InputInterface $input, OutputInterface $output) + { + $session = $this->getHelper('phpcr')->getSession(); + + $file = $input->getArgument('file'); + $path = $session->getAbsPath($input->getArgument('path')); + + $parentNode = $session->getNode($path); + + if (!file_exists($file)) { + throw new \InvalidArgumentException(sprintf( + 'File "%s" does not exist.', + $file + )); + } + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $file); + + $filename = basename($file); + $fileNode = $parentNode->addNode($filename, 'nt:file'); + $contentNode = $fileNode->addNode('jcr:content', 'nt:unstructured'); + $content = file_get_contents($file); + $contentNode->setProperty('jcr:data', $content, PropertyType::BINARY); + $contentNode->setProperty('jcr:mimeType', $mimeType); + } +} From 84814b2571cf9ddf5ac20ac460bac083968561dc Mon Sep 17 00:00:00 2001 From: dantleech Date: Fri, 6 Jun 2014 17:20:03 +0200 Subject: [PATCH 2/3] Updated command --- features/bootstrap/FeatureContext.php | 9 ++ features/phpcr_file_import.feature | 68 ++++++++++++ features/phpcr_node_file_import.feature | 17 --- .../Command/Phpcr/NodeFileImportCommand.php | 100 +++++++++++++++--- 4 files changed, 162 insertions(+), 32 deletions(-) create mode 100644 features/phpcr_file_import.feature delete mode 100644 features/phpcr_node_file_import.feature diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d5b859d1..b84942a1 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -471,6 +471,15 @@ public function thereExistsAPropertyAt($arg1) $session->getProperty($arg1); } + /** + * @Given /^there should exist a property at "([^"]*)"$/ + */ + public function thereShouldExistAPropertyAt($arg1) + { + $session = $this->getSession(); + $session->getProperty($arg1); + } + /** * @Given /^there should not exist a property at "([^"]*)"$/ */ diff --git a/features/phpcr_file_import.feature b/features/phpcr_file_import.feature new file mode 100644 index 00000000..f07062d7 --- /dev/null +++ b/features/phpcr_file_import.feature @@ -0,0 +1,68 @@ +Feature: Import an external file as to a node + In order to import an external file into the system + As a user that is logged into the shell + I should be able to run a command which does that + + Background: + Given that I am logged in as "testuser" + And the "cms.xml" fixtures are loaded + And the file "phpcr.png" contains the contents of "files/phpcrlogos.png" + And the current node is "/" + + Scenario: Import a file + Given I execute the "file:import . phpcr.png" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a node at "/phpcr.png" + And the node at "/phpcr.png/jcr:content" should have the property "jcr:mimeType" with value "image/png" + + Scenario: Import a file onto existing file, no overwrite specified + Given I execute the "file:import . phpcr.png" command + And I execute the "file:import . phpcr.png" command + Then the command should fail + + Scenario: Import a file onto existing file, force not specified + Given I execute the "file:import . phpcr.png --no-interaction" command + And I execute the "file:import . phpcr.png" command + Then the command should fail + + Scenario: Import a file onto existing file, force specified + Given I execute the "file:import . phpcr.png" command + And I execute the "file:import . phpcr.png --force" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a node at "/phpcr.png" + And the node at "/phpcr.png/jcr:content" should have the property "jcr:mimeType" with value "image/png" + + Scenario: Import a file, override mime type + Given I execute the "file:import . phpcr.png --mime-type=application/data" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a node at "/phpcr.png" + And the node at "/phpcr.png/jcr:content" should have the property "jcr:mimeType" with value "application/data" + + Scenario: Import a file, specify a name + Given I execute the "file:import ./foobar.png phpcr.png --mime-type=application/data" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a node at "/foobar.png" + + Scenario: Import a file to a specified property + Given I execute the "file:import ./ phpcr.png --no-container" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a property at "/phpcr.png" + + Scenario: Import overwrite a specified property + Given I execute the "file:import ./ phpcr.png --no-container" command + And I save the session + And I execute the "file:import ./ phpcr.png --no-container" command + Then the command should not fail + And I save the session + Then the command should not fail + And there should exist a property at "/phpcr.png" diff --git a/features/phpcr_node_file_import.feature b/features/phpcr_node_file_import.feature deleted file mode 100644 index 481d2174..00000000 --- a/features/phpcr_node_file_import.feature +++ /dev/null @@ -1,17 +0,0 @@ -Feature: Import an external file as to a node - In order to import an external file into the system - As a user that is logged into the shell - I should be able to run a command which does that - - Background: - Given that I am logged in as "testuser" - And the "cms.xml" fixtures are loaded - - Scenario: Import a file - Given the file "phpcr.png" contains the contents of "files/phpcrlogos.png" - Given the current node is "/" - And I execute the "node:file:import . phpcr.png" command - Then the command should not fail - And I save the session - Then the command should not fail - And there should exist a node at "/phpcr.png" diff --git a/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php b/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php index 9e3e4c0f..36f28988 100644 --- a/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php +++ b/src/PHPCR/Shell/Console/Command/Phpcr/NodeFileImportCommand.php @@ -7,50 +7,120 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputArgument; use PHPCR\PropertyType; +use Symfony\Component\Console\Input\InputOption; +use PHPCR\PathNotFoundException; class NodeFileImportCommand extends Command { + /** + * @var PHPCR\SessionInterface + */ + protected $session; + protected function configure() { - $this->setName('node:file:import'); + $this->setName('file:import'); $this->setDescription('Import a file at the given path'); $this->addArgument('path', InputArgument::REQUIRED, 'Path to import file to'); $this->addArgument('file', InputArgument::REQUIRED, 'Path to file to import'); + $this->addOption('mime-type', null, InputOption::VALUE_REQUIRED, 'Mime type (optional, auto-detected)'); + $this->addOption('force', null, InputOption::VALUE_NONE, 'Force overwriting any existing node'); + $this->addOption('no-container', null, InputOption::VALUE_NONE, 'Do not wrap in a JCR nt:file, but write directly to the specified property'); $this->setHelp(<<nt:file. The new -node will be named after the file. +The file will be imported as a node of built-in type nt:file. + +If a Node is specified as path then the filename of the imported file will be used +as the new node, otherwise, if the target path does not exist, then it is assumed +that the path is the target path for the new file, including the filename. + + PHPCRSH> file:import ./ foobar.png + PHPCRSH> file:import ./barfoo.png foobar.png + +In the first example above will create /foobar.png, whereas the second will create +./barfoo.png. + +By default the file will be imported in a container, i.e. a node with type nt:file. In +addition to the file data, the node will contain metadata. -The mime-type will be inferred automatically.. +Alternatively you can specify the --no-container option to import directly to a single property. + +The mime-type of the file (in the case where a container is used) will be automatically determined unless +specified with --mime-type. HERE ); } public function execute(InputInterface $input, OutputInterface $output) { - $session = $this->getHelper('phpcr')->getSession(); + $this->session = $this->getHelper('phpcr')->getSession(); - $file = $input->getArgument('file'); - $path = $session->getAbsPath($input->getArgument('path')); + $filePath = $input->getArgument('file'); + $force = $input->getOption('force'); + $noContainer = $input->getOption('no-container'); - $parentNode = $session->getNode($path); + $path = $this->session->getAbsPath($input->getArgument('path')); + $mimeType = $input->getOption('mime-type'); + $filename = basename($filePath); - if (!file_exists($file)) { + if (!file_exists($filePath)) { throw new \InvalidArgumentException(sprintf( 'File "%s" does not exist.', - $file + $filePath )); } - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mimeType = finfo_file($finfo, $file); + try { + // first assume the user specified the path to the parent node + $parentNode = $this->session->getNode($path); + } catch (PathNotFoundException $e) { + // if the given path does not exist, assume that the basename is the target + // filename and the dirname the path to the parent node + $parentPath = dirname($path); + $parentNode = $this->session->getNode($parentPath); + $filename = basename($path); + } + + $fhandle = fopen($filePath, 'r'); + + if ($noContainer) { + $this->importToProperty($fhandle, $filePath, $filename, $parentNode, $force); + } else { + $this->importToContainer($fhandle, $mimeType, $filePath, $filename, $parentNode, $force); + } + } + + private function importToProperty($fhandle, $filePath, $filename, $parentNode, $force) + { + $parentNode->setProperty($filename, $fhandle, PropertyType::BINARY); + } + + private function importToContainer($fhandle, $mimeType, $file, $filename, $parentNode, $force) + { + // if no mime-type specified, guess it. + if (!$mimeType) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $file); + } + + // handle existing node + if ($parentNode->hasNode($filename)) { + if (true === $force) { + $fileNode = $parentNode->getNode($filename); + $this->session->removeItem($fileNode->getPath()); + } else { + throw new \InvalidArgumentException(sprintf( + 'Node "%s" already has child "%s". Use --force to overwrite.', + $parentNode->getPath(), + $filename + )); + } + } - $filename = basename($file); $fileNode = $parentNode->addNode($filename, 'nt:file'); $contentNode = $fileNode->addNode('jcr:content', 'nt:unstructured'); - $content = file_get_contents($file); - $contentNode->setProperty('jcr:data', $content, PropertyType::BINARY); + $contentNode->setProperty('jcr:data', $fhandle, PropertyType::BINARY); $contentNode->setProperty('jcr:mimeType', $mimeType); } } From f787b82ac047552efce1ec45267994ee3c4e530f Mon Sep 17 00:00:00 2001 From: dantleech Date: Fri, 6 Jun 2014 18:00:48 +0200 Subject: [PATCH 3/3] Updated changelog --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92f99486..9c449747 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ # alpha2 / dev-master -- Added `--pretty` option to `session:export:view` command to output formatted XML -- Ask confirmation before overwriting file in `session:export:view` +## Features + +- New command: `file:import`: - import files into the repository. + +## Improvements + +- `session:export:view`: Added `--pretty` option to `session:export:view` command to output formatted XML. +- `session:export:view`: Ask confirmation before overwriting file.