2121
2222namespace PHPCR \Util \Console \Command ;
2323
24- use Symfony \Component \Console \Command \Command ;
2524use Symfony \Component \Console \Input \InputOption ;
26- use Symfony \Component \Console \Input \InputArgument ;
2725use Symfony \Component \Console \Input \InputInterface ;
2826use Symfony \Component \Console \Output \OutputInterface ;
2927use Symfony \Component \Console \Helper \DialogHelper ;
28+ use PHPCR \Util \Console \Command \BaseCommand ;
3029
3130/**
3231 * Command which can update the properties of nodes found
3332 * using the given JCR query.
3433 *
3534 * @author Daniel Leech <daniel@dantleech.com>
3635 */
37- class WorkspaceNodeUpdateCommand extends Command
36+ class NodesUpdateCommand extends BaseCommand
3837{
3938 /**
4039 * {@inheritDoc}
@@ -43,19 +42,23 @@ protected function configure()
4342 {
4443 parent ::configure ();
4544
46- $ this ->setName ('phpcr:workspace:node:update ' )
47- ->addArgument (
48- 'query ' ,
49- InputArgument::REQUIRED ,
50- 'A query statement to execute ' )
51- ->addOption ('force ' , null ,
52- InputOption::VALUE_NONE ,
53- 'Use to bypass the confirmation dialog '
45+ $ this ->setName ('phpcr:nodes:update ' )
46+ ->addOption (
47+ 'type ' , 't ' ,
48+ InputOption::VALUE_REQUIRED ,
49+ 'Update nodes of given node type, e.g. nt:unstructured '
5450 )
5551 ->addOption (
56- 'language ' , 'l ' ,
52+ 'where ' , 'w ' ,
53+ InputOption::VALUE_OPTIONAL ,
54+ 'Specify the update criteria in SQL, e.g. "foobar = \'foo \' AND barfoo = \'bar \'" '
55+ )
56+ ->addOption (
57+ 'query-language ' , 'l ' ,
5758 InputOption::VALUE_OPTIONAL ,
58- 'The query language (sql, jcr_sql2 ' )
59+ 'The query language (sql, jcr_sql2 ' ,
60+ 'jcr_sql2 '
61+ )
5962
6063 ->addOption ('set-prop ' , 'p ' ,
6164 InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY ,
@@ -73,16 +76,22 @@ protected function configure()
7376 InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY ,
7477 'Remove mixin from the nodes '
7578 )
79+ ->addOption ('force ' , null ,
80+ InputOption::VALUE_NONE ,
81+ 'Use to bypass the confirmation dialog '
82+ )
7683 ->setDescription ('Command to manipulate the nodes in the workspace. ' )
7784 ->setHelp (<<<HERE
78- The <info>workspace:node: update</info> command updates properties of nodes found
79- by the given JCR query .
85+ The <info>nodes: update</info> command updates properties of nodes of type x matching
86+ the given select criteria .
8087
81- php bin/phpcr workspace:node: update "SELECT FROM nt:unstructured" --set-prop=foo=bar
88+ php bin/phpcr nodes: update --type=" nt:unstructured" --where="foo='bar' " --set-prop=foo=bar
8289
8390The options for manipulating nodes are the same as with the
8491<info>node:touch</info> command and
8592can be repeated to update multiple properties.
93+
94+ The <info>--where</info> option corresponds to the "where" part of a standard query.
8695HERE
8796);
8897 }
@@ -92,34 +101,45 @@ protected function configure()
92101 */
93102 protected function execute (InputInterface $ input , OutputInterface $ output )
94103 {
95- $ sql = $ input ->getArgument ('query ' );
96- $ language = strtoupper ($ input ->getOption ('language ' ));
104+ $ type = $ input ->getOption ('type ' );
105+ $ where = $ input ->getOption ('where ' );
106+ $ queryLanguage = strtoupper ($ input ->getOption ('query-language ' ));
97107 $ setProp = $ input ->getOption ('set-prop ' );
98108 $ removeProp = $ input ->getOption ('remove-prop ' );
99109 $ addMixins = $ input ->getOption ('add-mixin ' );
100110 $ removeMixins = $ input ->getOption ('remove-mixin ' );
101- $ force = $ input ->getOption ('force ' );
111+ $ noInteraction = $ input ->getOption ('no-interaction ' );
112+ $ helper = $ this ->getPhpcrCliHelper ();
113+ $ session = $ this ->getPhpcrSession ();
114+ $ this ->dialog = new DialogHelper ();
115+
116+ if (!$ type ) {
117+ throw new \InvalidArgumentException ('You must provide the "type" option, to select all nodes specify the type "nt:base" ' );
118+ }
102119
103- $ helper = $ this ->getHelper ('phpcr ' );
104- $ session = $ helper ->getSession ();
120+ if ($ where ) {
121+ $ sql = sprintf ('SELECT * FROM [%s] WHERE %s ' , $ type , $ where );
122+ } else {
123+ $ sql = sprintf ('SELECT * FROM [%s] ' , $ type );
124+ }
105125
106- $ query = $ helper ->createQuery ($ language , $ sql );
126+ $ output ->writeln ($ sql );
127+ $ query = $ helper ->createQuery ($ queryLanguage , $ sql );
107128
108129 $ start = microtime (true );
109130 $ result = $ query ->execute ();
110131 $ elapsed = microtime (true ) - $ start ;
111132
112- if (!$ force ) {
113- $ dialog = new DialogHelper ();
114- $ force = $ dialog ->askConfirmation ($ output , sprintf (
115- '<question>About to update %d nodes, do you want to continue Y/N ?</question> ' ,
116- count ($ result )
117- ), false );
133+ if (!$ noInteraction ) {
134+ if (false === $ this ->getAction ($ output , $ result )) {
135+ return 0 ;
136+ }
118137 }
119138
120139 foreach ($ result as $ i => $ row ) {
121140 $ output ->writeln (sprintf (
122- "<info>Updating node</info> %s. " ,
141+ "<info>Updating node:</info>[%d] %s. " ,
142+ $ i ,
123143 $ row ->getPath ()
124144 ));
125145
@@ -137,4 +157,30 @@ protected function execute(InputInterface $input, OutputInterface $output)
137157
138158 return 0 ;
139159 }
160+
161+ protected function getAction ($ output , $ result )
162+ {
163+ $ response = strtoupper ($ this ->dialog ->ask ($ output , sprintf (
164+ '<question>About to update %d nodes. Enter "Y" to continue, "N" to cancel or "L" to list.</question> ' ,
165+ count ($ result ->getRows ())
166+ ), false ));
167+
168+ if ($ response == 'L ' ) {
169+ foreach ($ result as $ i => $ row ) {
170+ $ output ->writeln (sprintf (' - [%d] %s ' , $ i , $ row ->getPath ()));
171+ }
172+
173+ return $ this ->getAction ($ output , $ result );
174+ }
175+
176+ if ($ response == 'N ' ) {
177+ return false ;
178+ }
179+
180+ if ($ response == 'Y ' ) {
181+ return true ;
182+ }
183+
184+ return $ this ->getAction ($ output , $ result );
185+ }
140186}
0 commit comments