Jump to content

Juergen

Members
  • Posts

    1,427
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Juergen

  1. AddHookbefore doesnt work because the number of the children will not be stored. I guess that the children were not created at the time of the Hook, so numChildren doesnt work.
  2. Hello @ all, I need to store the number of children in an integer field in the parent page after the children were created. I use the ready.php for the code: $pages->addHookAfter("saved", function($event) { $page = $event->arguments[0]; if ($page->template == 'events') { if (($page->numChildren) > 0) { $page->subdatesnumber = $page->numChildren; $page->save(); } } }); I always get a blank page after save with this piece of code. I have tried several variations but without success. events = template name of the parent page subdatesnumber = integer field in the parent page where the number of children should be stored (fe 4) Workflow: After saving of the parent page some child pages will be created. After they were created the number of children should be stored in the field "subdatesnumber" which is in the parent page. Does anyone know what could be wrong with the code? Best regards
  3. Great. The fix works!
  4. I can confirm this error too.
  5. Mmhh! Your version seems not to work: $itemnumber = $event->object->getPage()->NAMEOFYOURPAGETABLEFIELD->count(); $this->message("Number of items:{$itemnumber}"); Returns always 0 in the message in my case.
  6. Ok, thanks for the hint. In my case I have only direct children in the page table field, but I have changed it to your snippet.
  7. If you use the init.php introduced in PW 2.6.7 you can add this piece of code to the init. php: // show pagetable field only if there are items in it $pages->addHookAfter("ProcessPageEdit::buildFormContent", function($event) { $wrapper = $event->return; if($wrapper->has('NAMEOFYOURPAGETABLEFIELD')){ if ($event->object->getPage()->numChildren > 0) return; $wrapper->NAMEOFYOURPAGETABLEFIELD->collapsed = Inputfield::collapsedHidden; } });
  8. Thanks for the answere. I have solved the problem with jquery in my adminscript.js to hide the parent and use the setting "open".
  9. Hello @all I have discovered an issue with inputfield dependencies depending on the visibility settings of the field where the dependency takes care of. The picture below shows the setting of the "parent" field. If the "parent" field has presentation "not editable" or "hidden", the inputfield dependency for the other field which takes care of this field wouldnt work. If I change the presentation fe to "open" everything work as expected. Is this a normal behaviour? In my case I show or hide a field depending on the settings of this "parent" field. If the "parent" field has one of the two settings written above, the "child" field is always invisible. Best regards
  10. Works great! Thanks
  11. Thanks for sharing your module with us. I use it to mark events which are booked up.
  12. OK sorry! How can I miss that? Thanks
  13. Forget the drag and drop idea , a link, fe next to the page title, that opens the template editor in a modal window to show all the fields of the template, would fit the requirements.
  14. Hello @tpr here is an idea, what can also be useful for admins: It would be great if there will be a drag and drop possibility in the forms to change the position of a field in the form itself. You have added a great function to edit a field directly from the form. So changing the position of the field in the form directly would also be a great addon (but maybe difficult to implement?!?) I hope you understand what I mean. At the moment you have to open the template directory and change the position of the fields there. With roles permission you can make this only accessable for superusers. Its only an idea. Best regards Jürgen
  15. Uahh! It was a heavy birth, but now it is working as expected. As @kongondo pointed out, the deletion of the old pages have to take place after creation and saving of the new child pages. But this is only possible if each of the child pages has an unique path name. Otherwise the saving of the new children is not possible (duplication of the path names). Solution: I have added the current time stamp to the path name. Now the path names of my children look like "name-of-the event-23-12-2016-1482482098". Now every child page has a unique path name. Now I was able to put the code for deleting the old children after the saving of the new created children. .... .... //check for other languages and create UNIQUE path names foreach ($this->languages as $lang) { $lname = $lang->isDefault() ? '' : $lang->id; $default = $this->languages->get("default"); if ($page->title->getLanguageValue($lang)) { $k->set("name$lname", $page->title->getLanguageValue($lang) . '-' . $eventstartmultiple . '-' . time()); } else { $k->set("name$lname", $page->title->getLanguageValue($default) . '-' . $eventstartmultiple . '-' . time()); } $k->set("status$lang", 1); } $k->save(); } //delete old children $pages = $this->wire('pages'); $repeaterID = $this->wire('fields')->get('eventpricerepeater')->id; // this is the 'repeater_field_name' page $repeaterPage = $pages->get("parent.name=repeaters, name=for-field-$repeaterID"); foreach ($page->children as $child) { if (in_array($child->id, $oldchildrenids, true)) { $id = $child->id; $child->delete(); $this->message("{$child->id} wurde gefunden und gelöscht"); $childRepeaterPage = $repeaterPage->child("name=for-page-$id"); // will also delete the repeat item pages, e.g. the '1234567890' if ($childRepeaterPage->id) $pages->delete($childRepeaterPage, true); } } The deletion code is now after the saving of the new children. Each child gets an unique path name by adding the time stamp via "time()" at the end. Every time i create new children, they will be created properly (and the corresponding repeaters too). All old children and repeaters will be deleted properly. Special Thanks to @kongondo and to @adrian for their patience and help getting this to work.
  16. I have tried to grab the ids of the "old children" and put it into an array with this piece of code before the children start beeing created: //grab the old children and make array of their ids. $oldchildrenids = array(); foreach ($page->children('include=all') as $child) { $oldchildrenids[] = $child->id; } This works so far. To delete the "old children" and their repeaters I have used this piece of code: //delete old children $pages = $this->wire('pages'); $repeaterID = $this->wire('fields')->get('eventpricerepeater')->id; // this is the 'repeater_field_name' page $repeaterPage = $pages->get("parent.name=repeaters, name=for-field-$repeaterID"); foreach($page->children as $child){ if (in_array($child->id, $oldchildrenids, true)) { //grab only the old children $id = $child->id; $child->delete(); //delete all old children $this->message("{$child->id} was deleted"); //delete all old repeater pages and their children $childRepeaterPage = $repeaterPage->child("name=for-page-$id"); // will also delete the repeat item pages, e.g. the '1234567890' if($childRepeaterPage->id) $pages->delete($childRepeaterPage, true); } } Problem: I cannot put the last code snippet after the save() function because then the new children will not be created. Maybe thats a reason because I manipulate the path of the pages with the date as suffix (eventname-21-12-2016). As a result the page itself could not be saved because of the same path. I need to put it before the save function. The repeater pages were also not created (Duplicate entry error as always)
  17. But if I place the delete function after the creation function of the new children, all new children will be deleted or do you mean children of the repeater items?
  18. One problem resists. This only works on the first creation of the children. If you create the children again - all the repeater pages of the children will be deleted via $child->delete(); and will not be created new. So $k->eventpricerepeater->import($page->eventpricerepeater); will not be working once more. So it seems that $child->delete is responsible for this behavior. To clearify: The default children of the event (frontend pages) will be created, but not the repeater children. Here I get the duplicate entry error message again. After first creation of children: After creating the children once more: Duplicate entry error message appears and prevents creating of children repeater pages once more. But there are no children pages there - so where is the duplicate entry message coming from. Error saving field "eventpricerepeater" - SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1482406846-2793-1-0' for key 'name_parent_id'
  19. Hello @adrian and @kongondo the following piece of code still works: $k->eventpricerepeater->import($page->eventpricerepeater); What was the problem? The problem was that I had to delete the parent page after made changes in the hook module. My mistake was that I havent done this, so the repeaters pages were not beeing created properly. After deleting the parent page and creating a new parent page (event) everything works fine. I dont get any error message and the repeaters will be copied to the children. The new parent page ist called "ABC Termin" (= ABC event). All repeaters were created properly and all values are inside the repeaters. Thanks for your help!!!!!!!
  20. Yes this will be saved to the parent page. Its only a checkbox that should be checked if the child pages should be created, no need to put it before a page save, because it will be saved from the hook function. Thanks for your help!!!!!!!!
  21. This is the hook code: public function init() { $this->pages->addHookBefore('saveReady', $this, 'createEvents'); } public function createEvents($event) { $page = $event->arguments[0]; //create multiple recurring events - daily,weekly,monthly,yearly if (($page->template == "events") AND ($page->repeattype >= "2")) { //check for multiple events $pages = $this->wire('pages'); $repeaterID = $this->wire('fields')->get('eventpricerepeater')->id; // this is the 'repeater_field_name' page $repeaterPage = $pages->get("parent.name=repeaters, name=for-field-$repeaterID"); // check if recurring is checked on the page beeing saved. if ($page->recurring == 1) { foreach ($page->children('include=all') as $child) { $id = $child->id; // first delete the child page $child->delete(); // this is the 'name_of_page_with_repeater' $childRepeaterPage = $repeaterPage->child("name=for-page-$id"); // will also delete the repeate item pages, e.g. the '1234567890' $this->message("ID: {$childRepeaterPage->id} erstellt."); if($childRepeaterPage->id) $pages->delete($childRepeaterPage, true); } //START RECURRING DATE $eventstartunformatted = $page->getUnformatted('date_start'); $eventstarttime = date("H:i", $eventstartunformatted); function timeToSeconds($time) { $timeExploded = explode(':', $time); if (isset($timeExploded[2])) { return $timeExploded[0] * 3600 + $timeExploded[1] * 60 + $timeExploded[2]; } return $timeExploded[0] * 3600 + $timeExploded[1] * 60; } $eventstartseconds = timeToSeconds($eventstarttime); //END RECURRING DATE $eventendunformatted = $page->getUnformatted('date_end'); $eventendtime = date("H:i", $eventendunformatted); $diff = $eventendunformatted - $eventstartunformatted; //$minterval = $page->repeattype->value; if ($page->repeattype->value == "D") { $page->of(false); $page->weekdaysevent = '1|2|3|4|5|6|7'; //set the wire array } else { } $weekdays = $page->weekdaysevent; //interval from db $startdateunformatted = $page->getUnformatted('date_start'); //interval start $startdate = date("Y-m-d H:i", $startdateunformatted); if ($page->intervallimittype == "1") { $enddateunformatted = $page->getUnformatted('recurringdateend'); //interval end $secondstoend = "86340"; $enddate = $enddateunformatted + $secondstoend; } else { $enddate = "7258032000"; //virtual enddate far in the future: 31.12.2199 } $enddate = date("Y-m-d H:i", $enddate); $end = new DateTime($enddate); if ($page->repeattype->value == "D") { $step = "1"; $unit = "W"; } else { $step = $page->steps; //Number for the interval $unit = $page->repeattype->value; } $dow1 = $dow2 = $dow3 = $dow4 = $dow5 = $dow6 = $dow7 = ""; //get all activated days foreach ($weekdays as $number) { ${"dow$number"} = true; } $daysarray = array( "", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" ); for ($i = 1; $i < 8; $i++) { if (${"dow$i"}) { ${"dow$i"} = $daysarray[$i]; //get checked days name ${"start$i"} = new DateTime($startdate); //create start dates for every weekday ${"start$i"}->modify(${"dow$i"}); //get the first occurence of each day ${"interval$i"} = new DateInterval("P{$step}{$unit}"); //create intervals for each weekday ${"period$i"} = new DatePeriod(${"start$i"}, ${"interval$i"}, $end); //create periods for each weekday foreach (${"period$i"} as $date) { $date = $date->format('Y-m-d H:i'); $starttime = strtotime($eventstarttime); //add time in seconds to date $date = (strtotime($date)) + $eventstartseconds; ${"array$i"}[] = $date; } } else { ${"array$i"}[] = ""; } } $periods = array_merge($array1, $array2, $array3, $array4, $array5, $array6, $array7); //merge all arrays into one $periods = (array_filter($periods)); //remove empty array parts sort($periods); //sort array ascending if ($page->intervallimittype == "2") { $periods = array_slice($periods, 0, $page->repeatcount); //set new eventenddate $lastEl = array_pop((array_slice($periods, -1))); $page->recurringdateend = $lastEl; $page->publish_until = $lastEl; } $i = 1; $periodsnumber = count($periods); // Output all days and dates $eventcounter = 1; $bookingtypesp = $page->bookingkind; $parent = wire('pages')->get($page->id); foreach ($periods as $item) { // create new page $k = new Page(); $k->template = 'single-event'; // set template //$k->parent = wire('pages')->get($page->id); // set the parent $k->parent = $parent; // set the parent // Copy page fields from parent page to newly created child pages $k->date_start = $item; $k->eventpricerepeater->import($parent->eventpricerepeater); $k->publish_until = $item + $diff; $k->eventstatus = $page->eventstatus; $k->participantmaxnumber = $page->participantmaxnumber; $k->eventmaxstatus = $page->eventmaxstatus; $k->eventmaxstatus = "1"; //get start date and create path name $eventstartmultiple = date("Y-m-d", $item); //get date for URL $k->title = $page->title; //check for other languages foreach ($this->languages as $lang) { $lname = $lang->isDefault() ? '' : $lang->id; $default = $this->languages->get("default"); if ($page->title->getLanguageValue($lang)) { $k->set("name$lname", $page->title->getLanguageValue($lang) . '-' . $eventstartmultiple); } else { $k->set("name$lname", $page->title->getLanguageValue($default) . '-' . $eventstartmultiple); } $k->set("status$lang", 1); $k->save(); } } $this->message("Es wurden " . ($periodsnumber) . " Kopien der Verantstaltung {$k->title} erstellt"); $page->recurring = 0; //END RECURRING } } The code at the beginning is only for calculating the start dates of the child pages - so dont be confused! The creating of the child pages starts at "foreach($periods as $item)"
  22. Maybe that could be the reason!!! My child pages have the same title because it is always the same event (only the starting date will change). I will try it to add the number at the end (fe. event-1, event-2,...). I have manipulated the path names to add the starting date at the end (event-21-12-1016, event-28-12-1016 and so on). Therefore I never had a problem to store sub events with the same title. I will give it a try
  23. Mmmhh! It works in your case. I run the latest dev version of PW (3.0.45) $page is the parent page. I run a hook to create the child pages. This is how $page is defined inside the hook function: $page = $event->arguments[0]; So $page is always the page that you are working on (the parent page). Only for better explanation: It is a complex children creating function that is running with the hook. It creates children with different start dates depending on the settings. So the start date array is called $periods in my case. It is responsible for creating the children. If fe 5 dates should be created with an interval of 1 week than the period array consists of the five calculated start dates. Here is an example: $periods = array('21.12.2016', '28.12.2016', '04.01.2017', '11.01.2016'); This is why my foreach loop doesnt look like foreach ($children as $title) { Instead of this it looks like foreach ($periods as $item) { Thats the only difference. This is the complete foreach loop which is responsible for creating the child pages and filling their fields with values from the parent page. foreach ($periods as $item) { // create new page $k = new Page(); $k->template = 'single-event'; // set template $k->parent = wire('pages')->get($page->id); // set the parent // Copy page fields from parent page to newly created child pages $k->date_start = $item; $k->eventpricerepeater->import($page->eventpricerepeater); $k->publish_until = $item + $diff; $k->eventstatus = $page->eventstatus; $k->participantmaxnumber = $page->participantmaxnumber; $k->eventmaxstatus = $page->eventmaxstatus; $k->eventmaxstatus = "1"; //get start date and create path name $eventstartmultiple = date("Y-m-d", $item); //get date for URL $k->title = $page->title; //check for other languages foreach ($this->languages as $lang) { $lname = $lang->isDefault() ? '' : $lang->id; $default = $this->languages->get("default"); if ($page->title->getLanguageValue($lang)) { $k->set("name$lname", $page->title->getLanguageValue($lang) . '-' . $eventstartmultiple); } else { $k->set("name$lname", $page->title->getLanguageValue($default) . '-' . $eventstartmultiple); } $k->set("status$lang", 1); //$k->of(false); $k->save(); } } I will try to adapt it to your code and post the result here.
  24. Away from the deletion of the children repeater pages - it seems that there is still a problem by copying the repeater to the children pages $k->eventpricerepeater->import($page->eventpricerepeater); It seems that the repeater page will not be copied (created) to the children pages, because the page name is the same as in the parent (Duplicate-Entry). There exists only one page from the parent page (1482132297-8942-1) and it seems that the same page name will be copied to the children pages and therefore I always get the duplicate entry error. As a result the repater pages will not be created - so the deletion process will not take place. Here is the beginning of the code which creates the children pages foreach ($periods as $item) { // create new page $k = new Page(); $k->template = 'single-event'; // set template $k->parent = wire('pages')->get($page->id); // set the parent $k->setOutputFormatting(false); // Copy page fields from parent page to newly created child pages $k->date_start = $item; $k->eventpricerepeater->import($page->eventpricerepeater); $k->eventstatus = $page->eventstatus; .............. .............. This piece of code works because all fields except the repeater fields will be copied to the children pages.
  25. Mmhh! The $childRepeaterPage->id returns always 0 if I output it via a message. Could this be the problem why its not working?
×
×
  • Create New...