Tom. Posted November 11, 2017 Share Posted November 11, 2017 Solution: $p->save(["uncacheAll" => false]); Edit: Added step by step Hey guys, I'm building an eCommerce for ProcessWire which is coming along nicely. However I've come across a bug which I can't seem to figure out what's going off and why. I've put up a post on GitHub, but I know Ryan is a busy man and I am currently working on this 6-8 hours a day. https://github.com/processwire/processwire-issues/issues/434 Here is a link to the issue. Link to comment Share on other sites More sharing options...
Macrura Posted November 11, 2017 Share Posted November 11, 2017 don't you need to call $new_option->of(false); before saving? 1 Link to comment Share on other sites More sharing options...
Tom. Posted November 11, 2017 Author Share Posted November 11, 2017 3 hours ago, Macrura said: don't you need to call $new_option->of(false); before saving? Tried setting both $page->of(false); and $new_option->of(false); problem still exists. Link to comment Share on other sites More sharing options...
Robin S Posted November 11, 2017 Share Posted November 11, 2017 Your code copied from the GitHub issue: $options = wirecommerce_get_all_variations($page); $variations = $page->wirecommerce_variations; // Detect added $added = 0; foreach($options as $option) { if(!$variations->has("wirecommerce_variation_value='$option'")) { $new_option = $variations->getNewItem(); $new_option->wirecommerce_variation_value = $option; $new_option->save(); $added++; } } if($added > 0) $this->message("$added variations added."); The code example for adding a repeater item from the documentation: $building = $page->buildings->getNew(); $building->title = 'One Atlantic Center'; $building->feet_high = 880; $building->num_floors = 50; $building->year_built = 1997; $building->save(); $page->buildings->add($building); $page->save(); So I think your code should be: $options = wirecommerce_get_all_variations($page); $variations = $page->wirecommerce_variations; // Detect added $added = 0; foreach($options as $option) { if(!$variations->has("wirecommerce_variation_value='$option'")) { $new_option = $variations->getNew(); // Or getNewItem(), they are the same thing $new_option->wirecommerce_variation_value = $option; $new_option->save(); $variations->add($new_option); $added++; } } $page->save(); if($added > 0) $this->message("$added variations added."); 3 Link to comment Share on other sites More sharing options...
Tom. Posted November 11, 2017 Author Share Posted November 11, 2017 1 hour ago, Robin S said: Your code copied from the GitHub issue: $options = wirecommerce_get_all_variations($page); $variations = $page->wirecommerce_variations; // Detect added $added = 0; foreach($options as $option) { if(!$variations->has("wirecommerce_variation_value='$option'")) { $new_option = $variations->getNewItem(); $new_option->wirecommerce_variation_value = $option; $new_option->save(); $added++; } } if($added > 0) $this->message("$added variations added."); The code example for adding a repeater item from the documentation: $building = $page->buildings->getNew(); $building->title = 'One Atlantic Center'; $building->feet_high = 880; $building->num_floors = 50; $building->year_built = 1997; $building->save(); $page->buildings->add($building); $page->save(); So I think your code should be: $options = wirecommerce_get_all_variations($page); $variations = $page->wirecommerce_variations; // Detect added $added = 0; foreach($options as $option) { if(!$variations->has("wirecommerce_variation_value='$option'")) { $new_option = $variations->getNew(); // Or getNewItem(), they are the same thing $new_option->wirecommerce_variation_value = $option; $new_option->save(); $variations->add($new_option); $added++; } } $page->save(); if($added > 0) $this->message("$added variations added."); Thanks for the suggestion, but sadly not the case. Here is a quote from Ryan: "It shouldn't be necessary to do the $page->repeater->add($repeater); as the getNew() method already does that." Link to comment Share on other sites More sharing options...
adrian Posted November 12, 2017 Share Posted November 12, 2017 In a rush, but take a look at this post: https://processwire.com/talk/topic/6435-cant-figure-out-how-to-create-a-repeater-through-the-api/?do=findComment&comment=62987 Can't remember why I say that the docs are wrong, but for some reason I save the new item before adding any subfields - maybe something to that for some reason? Link to comment Share on other sites More sharing options...
Robin S Posted November 12, 2017 Share Posted November 12, 2017 1 minute ago, adrian said: Can't remember why I say that the docs are wrong, but for some reason I save the new item before adding any subfields - maybe something to that for some reason? I think that is because in that example you are adding files to the repeater page. A page has to be saved before you can add files or images to it. 1 Link to comment Share on other sites More sharing options...
Tom. Posted November 12, 2017 Author Share Posted November 12, 2017 Yeah, I'm starting to think this is something to do with mod_security or timeout. The script seems good? That or it's a bug with ProcessWire. It has the appearance of a mod_security issue blocking the fields from saving. But I don't know. Usually when that happens if effects all fields. Edit: Checked, mod security is turned off Link to comment Share on other sites More sharing options...
Tom. Posted November 18, 2017 Author Share Posted November 18, 2017 Added step by step guide: 1. Create a new template called bug. 2. Create two repeaters one called repeater_1 and repeater_2. 3. Create a text field called text and add that to repeater_1 and repeater_2. 4. Add repeater_1 and repeater_2 to the bug template. 5. Add this code to ready.php: $wire->addHookBefore("Pages::save", function($event) { $page = $event->arguments("page"); if($page->template == "bug") { for($i = 0; $i < 3; $i++) { $p = $page->repeater_2->getNew(); $p->text = "Bug"; $p->save(); } } }); 6. Create a bug template page and add content to repeater_1. 7. Click save, you will see that the content for repeater_2 isn't saved, however 3 repeater_2's are added. 8. Remove $p->save(); from the provided code. 9. Add content to repeater_1, you will see that content is added however only 1 repeater is added to repeater_2. $p->save() causes any other repeater to not save, I believe this also applies to Page Reference (see: https://github.com/processwire/processwire-issues/issues/430) Link to comment Share on other sites More sharing options...
adrian Posted November 18, 2017 Share Posted November 18, 2017 I haven't followed closely, but please try: $p->save('text'); Or something like that depending on what field(s) you are trying to save. Sorry, I should probably look at this more thoroughly, but not enough time Saving the entire page in a save hook will always cause problems because of recursion. 1 Link to comment Share on other sites More sharing options...
Tom. Posted November 18, 2017 Author Share Posted November 18, 2017 6 minutes ago, adrian said: I haven't followed closely, but please try: $p->save('text'); Or something like that depending on what field(s) you are trying to save. Sorry, I should probably look at this more thoroughly, but not enough time Saving the entire page in a save hook will always cause problems because of recursion. Thanks, sadly that returns the error "Can't save field from a new page - please save the entire page first". Maybe I will just have to rethink how this is going to work if that's the case, shame I thought it was a really user friendly way of handling product variations. Link to comment Share on other sites More sharing options...
adrian Posted November 18, 2017 Share Posted November 18, 2017 2 minutes ago, Tom. said: Thanks, sadly that returns the error "Can't save field from a new page - please save the entire page first" Makes sense - tricky because you are adding a repeater item. I am sure there is a fix, but really have to go now Have a read of this: https://processwire.com/talk/topic/315-run-code-after-page-save/?do=findComment&comment=2206 - might put you on the right track! Link to comment Share on other sites More sharing options...
Robin S Posted November 18, 2017 Share Posted November 18, 2017 @Tom., there does seem to be something funny going on in this case when hooking before Pages::save. Will do some more testing, but to allow you to move forward with your project the quick solution is just to hook after Pages::save. So in the test case: $wire->addHookAfter("Pages::save", function(HookEvent $event) { $page = $event->arguments('page'); if($page->template == 'bug' && !$page->skip_me) { for($i = 0; $i < 3; $i++) { $p = $page->repeater_2->getNew(); $p->text = 'Bug'; $p->save(); $page->repeater_2->add($p); $page->skip_me = true; // prevent recursion $page->save(); } } }); Edit: did some more testing using a Page Reference field and managed to trace it back to the "uncacheAll" option in PagesEditor::save(). Posted a comment on the other GitHub issue, which is definitely related to your issue. Hopefully Ryan can fix it soon. 3 Link to comment Share on other sites More sharing options...
Tom. Posted November 18, 2017 Author Share Posted November 18, 2017 5 hours ago, Robin S said: @Tom., there does seem to be something funny going on in this case when hooking before Pages::save. Will do some more testing, but to allow you to move forward with your project the quick solution is just to hook after Pages::save. So in the test case: $wire->addHookAfter("Pages::save", function(HookEvent $event) { $page = $event->arguments('page'); if($page->template == 'bug' && !$page->skip_me) { for($i = 0; $i < 3; $i++) { $p = $page->repeater_2->getNew(); $p->text = 'Bug'; $p->save(); $page->repeater_2->add($p); $page->skip_me = true; // prevent recursion $page->save(); } } }); Edit: did some more testing using a Page Reference field and managed to trace it back to the "uncacheAll" option in PagesEditor::save(). Posted a comment on the other GitHub issue, which is definitely related to your issue. Hopefully Ryan can fix it soon. Thank you so much Robin, I really appreciate it! 2 Link to comment Share on other sites More sharing options...
adrian Posted November 18, 2017 Share Posted November 18, 2017 For reference for other who come across this and don't see the github issue: https://github.com/processwire/processwire-issues/issues/434#issuecomment-345437293 Ryan talks about the uncacheAll issue and how to deal with it. 3 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