Jump to content

psy

Members
  • Posts

    718
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by psy

  1. Hi Brandy and welcome to ProcessWire There are many ways to achieve what you want. Hardest part is deciding which method works best for you and you client, eg: On your home page template you could have a Page reference field that allows your client to choose the featured projects and make the first the "main" project. For output, loop through the chosen page references and ensure the main project (page reference Project #1), gets different, more prominent styling. Use Tags on Project pages, eg "Home page featured" & "Home page other". Then in your home page template, use a selector to get the featured projects and loop through as above Based on info you supplied, I'd go with option 1 Hope this helps
  2. Just tested and it works a treat ? When a frontend user enters their event date, in _init.php: <?php if (!empty($input->post->availability)) { $availability = $sanitizer->date($input->post->availability, 'Y-m-d'); $sameDayBookings = $pages->find("template=booking, booking_date=$availability, booking_status!=pending|cancelled",['loadOptions'=>['autojoin' => true, 'joinFields' => ['booking_items']]]); $cache->save('sameDayBookings', $sameDayBookings); } This query takes no time at all. Next, in my custom module: <?php /** * @param Page $item - product page * @return int|void * @throws WireException */ public function itemAvailability(Page $item) { if ($item instanceof NullPage) return; $itemBookingCount = 0; $otherBookings = $this->wire('cache')->get('sameDayBookings'); if ($otherBookings->count > 0) { // there are other booking on the same event date foreach ($otherBookings as $otherBooking) { foreach ($otherBooking->booking_items as $otherBookingItem) { if ($otherBookingItem->booking_item->id == $item->id) { $itemBookingCount = (int)$itemBookingCount + (int)$otherBookingItem->booking_qty; } } } } $itemsAvailable = (int)$item->qty - (int)$itemBookingCount; return $itemsAvailable; } Query times for this function went from an average of 3.5sec to under 0.01 seconds per item and under 1sec to render the page listing multiple items with their availability. Happy dance time! Thank you all!
  3. Grateful for all your suggestions and you gave me an idea. Didn't get a chance to test today but will try tomorrow. It's a conglomeration of your suggestions. in _init.php prepended to all pages (or maybe refined to only the pages on which it's needed ?), collect all bookings for the day, regardless of individual item ids and cache it. Historical bookings won't change and without the repeater stuff, will be quick; instead of going back to the db for all calls, run the individual item queries on the cached page array - at most 20 items Will report back ?
  4. @dragan No question you ask is ever dumb! I should have made it clearer. Each item is a page, a product page. The qty is an integer field and refers to how many units of that product are owned by the client. The $limit is set to that number. The query searches through other bookings for that item on the nominated day, and on each match, subtracts the booking_qty from the item qty, to return how many are left for hire on that date. When all are booked out, the front-end customer cannot add it to their cart to prevent over-booking. A count wont do it as other bookings may have booked 2 or more units of the same item on that day.
  5. @BillH Thanks, I tried RockFinder3 a while ago. It's certainly a great module however I couldn't figure out how to get it working with Repeater fields. It's perfect with direct relation fields, eg PageReference but Repeaters are different beasts. Not sure if RF3 handles '.' separated fields in the selector, eg "booking_items.booking_item.id" either?
  6. I have a $pages selector that works great in giving me the requested info. However it's incredibly slow. Added to this, the request may be called up to 15 times on a particular page for 15 different listed items. <?php // in my custom module... // retrieves qty of items already hired on a particular day to determine availability for new bookings // booking_items is a repeater field and booking_item are repeater pages // I already have the $item and the $eventDate // Query is searching through 5K+ bookings and at least 3x that many booking_item repeater pages $limit = $item->qty; $selector = "template=booking, booking_items.booking_item.id=$item, booking_date=$eventDate, booking_status!=pending|cancelled, limit=$limit"; $pp = $this->wire()->pages; $otherBookings = $pp->find($selector); Each item query can take between 2 to 8 seconds ? What can I do to speed up this query? TIA psy
  7. Had an extreme example to deal with recently. Multiple field replacements for various fieldtypes. May not be the best approach but worked for me. Private function is in a custom module function. <?php /** * Takes a page field, eg 'body' as a template and replaces tags eg {age} with the same field value * from the supplied data page * @param $tplPage * @param $tplField * @param $dataPage * @param string $startTag * @param string $endTag * @param array $other * @return string|string[] * @throws WireException * @throws WirePermissionException */ private function _compileFieldTags ($tplPage, $tplField, $dataPage, $startTag = '{', $endTag = '}', $formatDate = false, $other = []) { $allowedFieldtypes = [ 'FieldtypeText', 'FieldtypeTextarea', 'FieldtypeInteger', 'FieldtypeFloat', 'FieldtypeDatetime', 'FieldtypeToggle', 'FieldtypeCheckbox', 'FieldtypePage' ]; $replacementNames = []; $replacementValues = []; // Sort out what to do with each inputfield type foreach ($dataPage->fieldgroup as $replacement) { if (!in_array($replacement->type, $allowedFieldtypes)) continue; switch ($replacement->type) { case 'FieldtypeDatetime': $fldData = $formatDate == false ? $dataPage->$replacement : $dataPage->getFormatted($replacement); break; case 'FieldtypePage': $fldData = $dataPage->$replacement->title; break; case 'FieldtypeCheckbox': $fldData = $dataPage->$replacement == true ? "Yes" : "No"; break; default: $fldData = $dataPage->$replacement; break; } $replacementNames[] = $replacement->name; $replacementValues[] = $fldData; } // Prepare replacement arrays foreach ($dataPage as $k => $v) { $replacementNames[] = $startTag . $k . $endTag; $replacementValues[] = $v; } $replacementNames['url'] = $startTag . 'url' . $endTag; $replacementValues[] = $dataPage->httpUrl; $result = str_ireplace($replacementNames, $replacementValues, $tplPage->$tplField); return $result; }
  8. Trying to upgrade TD to the latest version and I get this: Fatal Error: Uncaught WireException: No download URL specified in wire/modules/Process/ProcessModule/ProcessModule.module:1072 Happens both on the Modules->New and Settings->Upgrades with the upgrade module. I could upload the zip but that's not the issue. Reason for upgrade was another error message: Fatal error: Uncaught Exception: Serialization of 'Closure' is not allowed in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0 which auto-magically began appearing. I'm not serializing any data and the error disappears when I turn off TD. Any ideas on what's happening here?
  9. @Knubbi that's a question for Ryan in the ProDrafts forum ?
  10. If it's only content, there's also https://modules.processwire.com/modules/version-control/
  11. @MoritzLost True, however (unless I missed something), ProDrafts doesn't work for Repeater Matrix whereas my suggestion will work for template development. As I understand it, ProDrafts is more for checking/comparing content before committing changes. I guess it's what @Knubbi is trying to do
  12. You could use site/config .php settings, eg: <?php if ($user->hasRole('dev') { // or whatever role you assign // development templates directory $config->urls->templates = $config->urls->site . 'templates-dev/'; $config->paths->templates = $config->paths->site . 'templates-dev/'; $config->urls->fieldTemplates = $config->urls->templates . 'fields/'; $config->paths->fieldTemplates = $config->paths->templates . 'fields/'; } // other users, including the public, will see the default $config->templates & $config->paths (same for fields)
  13. Some things to try as results can vary depending on the PHP version: Be more explicit in your if statement, and turning off outputting formatting: <?php if(!empty($page->myfield_text_a) && !empty($page->myfield_text_b) && !empty($page->myfield_options) && !empty($page->myfield_date)) { $page->of(false); //.... }
  14. Some things to check which tripped me up when taking over from a previous developer: In site/config.php ensure that the template url & path are pointing to YOUR templates url & path. The default is 'template' however is customisable In Set Up ->Templates -> [your template] -> Files tab, that your template file name is not being overridden in the Alternate File Name field by something the original dev entered HTH
  15. Had the same issue as @LAPS, ie $vars not accessible in the rendered template. Fixed by including an empty array for $options, ie: <?php $vars = [ 'items' => $items, 'homepage' => pages(1), 'category' => $category ]; echo $files->render('inc/item-detail',$vars,[]);
  16. OK @AndZyk get it after the explanation but a bit confusing without that knowledge. The cursor changing to a text selector on edit threw me. Maybe turn off pointer events to let the user know it's just a display thing?
  17. @AndZyk great work. ? Only other feedback I have is that the buttons "What do I see?", "What do I hear" & "How does the hustle & bustle affect me?" don't go anywhere/show anything. My cursor changed from normal arrow to an 'edit' icon, not pointer on hover. Is this supposed to happen? I'm using Chrome on an iMac
  18. Check the id's of each form & its submit button If they're the same for both and depending on your embed method, both will submit when either form is submitted. Had a similar issue a while ago and changing the form ID's to be unique helped. See
  19. Thanks @SIERRA Oops! Just re-read my code and noticed a mistake. Should be: <?php if (!empty($input->get->id) { // PW way of accessing $_GET $id = $sanitizer->int($input->get->id); // Clean it up to ensure it's an integer $alertspage = $pages->get($id); // You can also do $pages->get("id=$id") if (!$alertspage instance of NullPage) { // ensure the page exists echo $alertspage->title; } else { echo "There was a problem retrieving the page with ID $id"; } } Missed the curly braces surrounding the first and last lines
  20. Think the issue may be in this line - no $ in front of id. Try: <?php if (!empty($input->get->id) // PW way of accessing $_GET $id = $sanitizer->int($input->get->id); // Clean it up to ensure it's an integer $alertspage = $pages->get($id); // You can also do $pages->get("id=$id") if (!$alertspage instance of NullPage) { // ensure the page exists echo $alertspage->title; } else { echo "There was a problem retrieving the page with ID $id"; }
  21. @Robin S Brilliant! Not quite what I needed but a great starting point. My scenario was: Didn't know the repeater item id Did know the id of a particular (page) field inside the repeater page And wanted any repeater item with that field id to be locked for editing by all, including super users. Here's what worked for me: <?php $wire->addHookAfter('Field::getInputfield', function(HookEvent $event) { $page = $event->arguments(0); if (!$page instanceof RepeaterPage) return; $inputfield = $event->return; // Only for a particular Repeater page field (fieldtype page) ID if($page->my-page-field->id !== 4486) return; // Set collapsed to Inputfield::collapsedNoLocked or Inputfield::collapsedHidden as suits $inputfield->collapsed = Inputfield::collapsedNoLocked; });
  22. Hi @SIERRA Using pure PW, you can go to Pages ->Find (in the dropdown), select your repeater template then add any other filters, eg Title - Contains Text...
  23. I know that headless cms has been a hot topic for a while. I've experimented with several frontend frameworks (Angular, React, Vue, etc) and I just don't get it. Maybe for huge corporations with multiple dev teams and big budgets, OK. For 95+% of use cases however, I find headless cms/js frontend to be a major pain with no discernible benefits. From a frontend web UX, they're often slower than a well built PW site with caching (eg ProCache). For native apps, something like api calls to/from PW/Dart via json would do the job. Am I missing something other than a desire for JS devs to earn extra $$$?
  24. @jploch Does this help? On the Template -> Edit -> Files tab, you could nominate an alternative template/path for your PageTable template.
  25. Not sure if related to your issue, but shouldn't that be a double = after $template?
×
×
  • Create New...