-
Posts
1,306 -
Joined
-
Last visited
-
Days Won
13
Everything posted by Juergen
-
Hook to check if pagetable item should be deleted before save possible?
Juergen replied to Juergen's topic in General Support
Thanks, I have solved this problem now with another way, where I dont need hooking into the pagetable field, but I will take a look at Inputfield::processInput. -
Hello @ all, I have a pagetable field on a page and I want to know if it is possible to check if an item of the pagetable was selected for deletion. As you can see I have clicked the basket icon to delete one item in the pagetable field. What I want to achive is to check fe via a hook before saving the page if an item was activated for deletion, so I can use fe an if/else statement with different code lines. Has anyone done something similar and has an idea how to achive this? Best regards
-
You are right: Combining was the solution - now it works
-
As you can see the children were created with an addHookBefore "saveReady" hook //creation of children $pages->addHookBefore('saveReady', function($event) { $page = $event->arguments[0]; ....some code logic foreach ($periods as $key => $item) { // create new page $k = new Page(); $k->template = 'single-event'; // set template // Copy page fields from parent page to newly created child pages $k->title = $page->title; $k->eventtype = $page->eventtype; $k->eventstatus = $page->eventstatus; $k->participantmaxnumber = $page->participantmaxnumber; $k->eventmaxstatus = $page->eventmaxstatus; $k->notifiable = $page->notifiable; ...... $k->save(); } }); This code works! I have shortened the code because at the beginning there were only some date calculations for recurring events. Then in the ready.php I have tried to store the number of the children in the subdatesnumber field. // Add number of subevents to the subeventnumber field $pages->addHookBefore("saved", function($event) { $page = $event->arguments[0]; if ($page->template == 'events') { if (($page->numChildren) > 0) { $page->subdatesnumber = $page->numChildren; } } });
-
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.
-
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
-
Great. The fix works!
-
I can confirm this error too.
-
Is it possible to show a page table only if there are items in it?
Juergen replied to Juergen's topic in General Support
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. -
Is it possible to show a page table only if there are items in it?
Juergen replied to Juergen's topic in General Support
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. -
Is it possible to show a page table only if there are items in it?
Juergen replied to Juergen's topic in General Support
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; } }); -
Inputfield dependencies and visibility of fields
Juergen replied to Juergen's topic in General Support
Thanks for the answere. I have solved the problem with jquery in my adminscript.js to hide the parent and use the setting "open". -
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
-
Works great! Thanks
-
Thanks for sharing your module with us. I use it to mark events which are booked up.
- 28 replies
-
- 3
-
- icon
- fontawesome
-
(and 2 more)
Tagged with:
-
OK sorry! How can I miss that? Thanks
-
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.
-
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
-
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.
-
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)
-
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'
-
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!!!!!!!
-
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)"