|
6 | 6 | use Symfony\Component\Console\Input\InputInterface; |
7 | 7 | use Symfony\Component\Console\Output\OutputInterface; |
8 | 8 | use Symfony\Component\Console\Input\InputArgument; |
| 9 | +use Symfony\Component\Console\Input\InputOption; |
9 | 10 |
|
10 | 11 | class VersionRestoreCommand extends Command |
11 | 12 | { |
12 | 13 | protected function configure() |
13 | 14 | { |
14 | 15 | $this->setName('version:restore'); |
15 | 16 | $this->setDescription('Restore a node version'); |
| 17 | + $this->addArgument('absPath', null, InputArgument::REQUIRED, 'Absolute path to node'); |
| 18 | + $this->addArgument('versionName', null, InputArgument::REQUIRED, 'Name of version to retore'); |
| 19 | + $this->addOption('remove-existing', null, InputOption::VALUE_NONE, 'Flag that governs what happens in case of identifier collision'); |
16 | 20 | $this->setHelp(<<<HERE |
| 21 | +Attempt to restore an old version of a node. |
| 22 | +
|
| 23 | +<em>If <info>absPath</info> is given and <info>versionName</info> is a version name:</em> |
| 24 | + Restores the node at <info>absPath</info> to the state defined by the version with |
| 25 | + the specified version name (<info>versionName</info>). |
| 26 | + This method will work regardless of whether the node at absPath is |
| 27 | + checked-in or not. |
| 28 | +
|
| 29 | +
|
| 30 | +<em>If <info>absPath</info> is given and <info>versionName</info> is a VersionInterface instance: |
| 31 | +</em> |
| 32 | + Restores the specified version to <info>absPath</info>. There must be no existing |
| 33 | + node at <info>absPath</info>. If one exists, a VersionException is thrown. |
| 34 | + There must be a parent node to the location at <info>absPath</info>, otherwise a |
| 35 | + PathNotFoundException is thrown. |
| 36 | + If the would-be parent of the location <info>absPath</info> is actually a property, |
| 37 | + or if a node type restriction would be violated, then a |
| 38 | + ConstraintViolationException is thrown. |
| 39 | +
|
| 40 | +
|
| 41 | +<em>If <info>versionName</info> is VersionInterface instance:</em> |
| 42 | + Restores the node in the current workspace that is the versionable node |
| 43 | + of the specified version to the state reflected in that version. |
| 44 | + This method ignores checked-in status. |
| 45 | +
|
| 46 | +
|
| 47 | +<em>If <info>versionName</info> is an array of VersionInterface instances:</em> |
| 48 | + Restores a set of versions at once. Used in cases where a "chicken and |
| 49 | + egg" problem of mutually referring REFERENCE properties would prevent |
| 50 | + the restore in any serial order. |
| 51 | + The following restrictions apply to the set of versions specified: If S |
| 52 | + is the set of versions being restored simultaneously, |
| 53 | + - For every version V in S that corresponds to a missing node, there |
| 54 | + must also be a parent of V in S. |
| 55 | + - S must contain at least one version that corresponds to an existing |
| 56 | + node in the workspace. |
| 57 | + - No V in S can be a root version (jcr:rootVersion). |
| 58 | + If any of these restrictions does not hold, the restore will fail |
| 59 | + because the system will be unable to determine the path locations to |
| 60 | + which one or more versions are to be restored. In this case a |
| 61 | + VersionException is thrown. |
| 62 | + The versionable nodes in the current workspace that correspond to the |
| 63 | + versions being restored define a set of (one or more) subgraphs. |
| 64 | +
|
| 65 | +<em>If the restore succeeds the changes made are dispatched immediately; |
| 66 | +</em> |
| 67 | +there is no need to call save. |
| 68 | +
|
| 69 | +If an array of VersionInterface instances is restored, an identifier |
| 70 | +collision occurs when the current workspace contains a node outside these |
| 71 | +subgraphs that has the same identifier as one of the nodes that would be |
| 72 | +introduced by the restore operation into one of these subgraphs. |
| 73 | +Else, an identifier collision occurs when a node exists outside the |
| 74 | +subgraph rooted at absPath with the same identifier as a node that would |
| 75 | +be introduced by the restore operation into the affected subgraph. |
| 76 | +The result in such a case is governed by the removeExisting flag. If |
| 77 | +<info>removeExisting</info> is true, then the incoming node takes precedence, and the |
| 78 | +existing node (and its subgraph) is removed (if possible; otherwise a |
| 79 | +RepositoryException is thrown). If <info>removeExisting</info> is false, then an |
| 80 | +ItemExistsException is thrown and no changes are made. Note that this |
| 81 | +applies not only to cases where the restored node itself conflicts with |
| 82 | +an existing node but also to cases where a conflict occurs with any node |
| 83 | +that would be introduced into the workspace by the restore operation. In |
| 84 | +particular, conflicts involving subnodes of the restored node that have |
| 85 | +OnParentVersion settings of COPY or VERSION are also governed by the |
| 86 | +<info>removeExisting</info> flag. |
| 87 | +
|
| 88 | +<b>Note:</b> The Java API defines this with multiple differing |
| 89 | +signatures, you need to act accordingly in your implementation. |
17 | 90 | HERE |
18 | 91 | ); |
19 | 92 | } |
20 | 93 |
|
21 | 94 | public function execute(InputInterface $input, OutputInterface $output) |
22 | 95 | { |
23 | | - throw new \Exception('TODO'); |
| 96 | + $absPath = $input->getArgument('absPath'); |
| 97 | + $versionName = $input->getArgument('versionName'); |
| 98 | + $removeExisting = $input->getOption('remove-existing'); |
| 99 | + $session = $this->getHelper('phpcr')->getSession(); |
| 100 | + $workspace = $session->getWorkspace(); |
| 101 | + $versionManager = $workspace->getVersionManager(); |
| 102 | + $versionManager->restore($removeExisting, $versionName, $absPath); |
24 | 103 | } |
25 | 104 | } |
0 commit comments