theoretic Posted September 3 Share Posted September 3 Hi friends! And thanks for ProcessWire! Content managers I work with like to create new pages by cloning the old ones. No bad in general, but they frequently forget to check and clean up all the content they copy, especially the multilanguage fields. So I decided to make a hook which should wipe all data fields of a recently created clone immediately after it has been created. Hooking such event is a piece of cake (thanks Processwire!) but cleaning all data fields appears to be a tricky business. Of course I've read this topic but it appears to be irrelevant in my case. My hook is basically like this: $wire->addHookAfter("Pages::cloned", function($event) { $clonePage = $event->arguments(1); $clonePage->of(false); //$clonePage->fields = $clonePage->fields->makeNew(); //fails // ...some more tricks including iterating through all data fields... $clonePage->of(true); $clonePage->save(); } Will be grateful for any possible advice ) Link to comment Share on other sites More sharing options...
Jim Bailie Posted September 4 Share Posted September 4 I'm interested in any input on this from more experienced PW devs, but I do wonder if this post helps at all: Link to comment Share on other sites More sharing options...
poljpocket Posted September 4 Share Posted September 4 Reading this, I am asking myself: A clone followed by a data wipe is nothing more than creating an empty new page with the same template, right? Why don't you disallow clone for these templates (possibly for your client's role only) and instruct your users to use "new" instead? 2 Link to comment Share on other sites More sharing options...
Jim Bailie Posted September 4 Share Posted September 4 Ha! I could tell my users to do that, but unfortunately they would not respond positively. The reason I'm interested in this thread is that I will soon need to: Clone a page (same template) Retain some field values Remove remaining values Populate 2 field values based on certain conditions Position the clone in the page tree based on said conditions I think just somehow iterating through the KNOWN field names/values and doing the work is the way to go, but it's always good to hear about any efficiencies that others my be aware of. Link to comment Share on other sites More sharing options...
theoretic Posted September 5 Author Share Posted September 5 Thanks for your interest friends! After some attempts I decided to this the hard way. Here's my working code: $wire->addHookAfter("Pages::cloned", function($event) { $clonePage = $event->arguments(1); $clonePage->of(false); $languages = \ProcessWire\wire('languages'); $emptyLanguageValues = []; foreach($languages as $language) $emptyLanguageValues[$language->name] = ''; foreach( $clonePage->fields as $field ){ switch(true){ case $field->type instanceof \ProcessWire\FieldtypePageTitleLanguage: case $field->type instanceof \ProcessWire\FieldtypeTextLanguage: case $field->type instanceof \ProcessWire\FieldtypeTextareaLanguage: $clonePage->{$field->name}->setLanguageValues($emptyLanguageValues); break; case $field->type instanceof \ProcessWire\FieldtypeInteger: case $field->type instanceof \ProcessWire\FieldtypeFloat: $clonePage->{$field->name} = NULL; break; case $field->type instanceof \ProcessWire\FieldtypeFile: case $field->type instanceof \ProcessWire\FieldtypeImage: $clonePage->$field->deleteAll(); break; case $field->type instanceof \ProcessWire\FieldtypePage: $clonePage->{$field->name}->removeAll(); break; } } $clonePage->save(); $clonePage->of(true); }); This example covers the most used types of data fields. It was enough for me, and it can be extended to include more data fields. By the way, I suppose that it could be a good idea to have a possibility to turn data copy on/off while cloning. But it's in PW core so I don't dare to change this. Link to comment Share on other sites More sharing options...
bernhard Posted September 5 Share Posted September 5 16 hours ago, poljpocket said: A clone followed by a data wipe is nothing more than creating an empty new page with the same template, right? Why don't you disallow clone for these templates (possibly for your client's role only) and instruct your users to use "new" instead? Good point. I think you could hook BEFORE Pages::clone and do exactly that instead of instructing the users to so manually. Note that you need the $event->replace = true; flag so that the original clone process does not kick in after your new page has been created. Something like this (untested): <?php $wire->addHookBefore('Pages::clone', function($event) { $page = $event->arguments('page'); if($page->template != 'your-template') return; $p = new Page(); $p->template = $page->template; $p->parent = $page->parent; $p->title = $page->title; $p->save(); $event->replace = true; // should not be necessary but just to be sure wire()->session->redirect($p->editUrl()); }); Of course that would mean that any clone would wipe all data. But you could add a checkbox to that page that disables the hook and therefore would work as a normal clone. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now