Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by da²

  1. Hello, EDIT: this original post wasn't clear, code in this post is way more explicit to show the thing I'm talking about. I'm not asking how to manage this problem, but is it a bug? And if not, could you explain why this behavior? To make it short: why is the Page instance given by HooEvent->arguments(0) not the same as the one given by find() function (children() here)? Shouldn't it be cached and the same? My use case: I have a method "foobar" called by several hooks. This method process sibling pages of the one received in parameter (using $page->parent->children()), and save the other pages if modified, but does not save the one received in parameter because it can come from a saveReady hook and so the page is already being saved. The problem comes from a Pages::sorted hook, after calling "foobar" method I save myself the page using the Page instance given by hook event ($event->arguments(0))... And so I'm not saving anything because it's not the same instance that was modified in "foobar" method. I know how to manage this, but that looks like a cache bug, isn't it? When "foobar" is called by a saveReady hook, changes are saved, so instance used internally by PW is same as children() one. But when I save with hook instance ($event->arguments(0)), changes are not saved. Here is a kind of demonstration, we can see Page instance from HookEvent is not the same as get() or find(): wire()->addHookAfter('Pages::sorted(6778)', test(...)); function test($event) { $eventPage = $event->arguments(0); $findPage = wire()->pages->find(6778, ['getFromCache' => true])[0]; $getPage = wire()->pages->get(6778); wire()->log->message('$eventPage === $findPage ' . ($eventPage === $findPage)); // False wire()->log->message('$eventPage === $getPage ' . ($eventPage === $getPage)); // False wire()->log->message('$findPage === $getPage ' . ($findPage === $getPage)); // True foreach ($eventPage->parent->children() as $sibling) { if ($sibling->id == $eventPage->id) { wire()->log->message('$sibling === $eventPage ' . ($sibling === $eventPage)); // False wire()->log->message('$sibling === $findPage ' . ($sibling === $findPage)); // True wire()->log->message('$sibling === $getPage ' . ($sibling === $getPage)); // True } } } In PW admin, drag/drop the page of id 6778 to change its sort order, and check "messages" logs. I force getFromCache just to test but it's already default value. Is it the expected behavior? Why? Am I supposed to modify/save the instance from hook event or from find()? Does it even matter?
  2. @digitalbricks Checking PHP documentation it's necessary to combine 2 flags, both combinations work: $a = ['a','b','C','A']; sort($a, SORT_NATURAL|SORT_FLAG_CASE); // a, A, b, c sort($a, SORT_STRING|SORT_FLAG_CASE); // a, A, b, c EDIT: cross-posted 🙂
  3. Be careful with $page->meta(), I'm using it for another purpose and it throws if page doesn't exist in DB, so at first page save (after giving a title): ProcessPageAdd: WireDataDB sourceID must be greater than 0 It's necessary to check ID before: if ($page->id) $page->meta(....);
  4. @maetmar In site/config.php you can specify your prepend file: // Prepend this file in /site/templates/ to any rendered template files $config->prependTemplateFile = '_init.php';
  5. Hello, Did you try sort flags? I don't know which one it is, maybe SORT_NATURAL: $repeater->sort('title', SORT_NATURAL);
  6. Hello @fox_digitalanimals A solution with a hook and CSS. First, in site/templates/admin.php, define a new CSS to include in admin: /** @var Config $config */ $config->styles->add($config->urls->templates . "styles/test.css"); require($config->paths->core . "admin.php"); // this is already in admin.php, just take care of having it at bottom site/templates/styles/test.css: .foobar .InputfieldRepeaterAddItem { display: none; } And add a hook in site/templates/admin.php to hide "add" button by adding a css class to repeater wrapper div: $this->addHookAfter("ProcessPageEdit::buildFormContent", function (HookEvent $event) { /** @var Page $page */ $page = $event->object->getPage(); if ($page->template->name == 'myTemplate') { // Filter on this template /** @var InputfieldWrapper $wrapper */ $wrapper = $event->return; /** @var InputfieldRepeater $myRepeater */ $myRepeater = $wrapper->get('repeat'); // "repeat" is the field name of my repeater $myRepeater->addClass('wrap:foobar'); } }); You can finally add a condition on $user roles to add the css class: if ($user->hasRole("theRole")){ // add the css... }
  7. If there are results to store, that's a whole question. 🙂 I didn't think about that since OP question is a bit vague and we don't know if he needs that. And I was curious about testing repeaters. 😆 Maybe store the results on the quiz page in a separate field (Profields Table ?), or a custom process module, or your RockGrid module. ^^ Since I bought Profields Table, I would try with it, I know it works with findRaw(). Adding a Table field on quiz template, columns would be "user | questionId | score". I don't see a good way to do this with only core PW, but I don't know everything in PW.
  8. I never used repeaters so my knowledge is poor on this subject. But in my answer the goal is to create a single quiz per page (1000 quiz == 1000 pages with "quiz" template), do you think it's an issue doing that way? And why? I'm interested in gathering informations on this subject, as it may be useful in the future. 🙂
  9. Hello, Don't consider my answer as the good answer, but I made a quick test to check if an idea could work ("reponses" should be named "answer", and "nouveau" => "add new"): So I created this fields: answer: type=Text isGoodAnswer: type=Checkbox quizzAnswer: type=Repeater, content fields=answer, isGoodAnswer question: type=Text quizzEntry: Type=Repeater, content fields=question, quizzAnswer Added the field quizzEntry to a template, and it looks it's working.
  10. Okay, colleague, I'm writing the report for the boss. Let me know if I've summarized it well: Then I asked ChatGPT to improve it in a more funny way:
  11. I think you can do shorter. 🙂 With Twig I would do that: {{ pages.get('/').children.each('title') | join(', ') }} But usually I use html lists so WireArray API is enough: <ul>{{ pages.get('/').children.each('<li>{title}</li>') }}</ul>
  12. Some reporter had the incredible chance to capture a team of developers successfully completing a full WordPress update. A very rare and intense footage: (reading your messages, this is how I imagine WordPress 😆 )
  13. Hello, Recently, while debugging something, I found I had unsolved PHP warnings. Because I'm using Twig, PHP warnings are not displayed at top of page. Not being aware that we have warnings in our code is not acceptable. 👮‍♂️ So I added this code in site/init.php: set_error_handler( function (int $errorNumber, string $message, string $file, int $lineNumber): bool { wire()->log->save('php-warnings', "Fichier \"$file\", ligne $lineNumber => $message"); // Return true so PHP won't process these warnings and display them at top of page. return true; }, E_WARNING); The log: Do you think it should be integrated in PW base installation, like errors and exceptions? If you have another way of managing this warnings, don't hesitate to share. 🙂
  14. I was struggling, trying permissions, searching in PW source code and the web, thought about a bug... and while taking 1 minute of pause I saw this thread in forum activity tab and thought "OK let's give a try with ChatGPT, I have no idea anyway right now". Question: (I already used template access control, but for some reason I thought user access control was managed by permissions (user-view, user-admin...)). Answer (in bold what I was looking for):
  15. Hello, Error message says there's no property "field" on Page class. There are also some more mistakes. This should be better: public function ready() { $this->pages->addHookBefore('saveReady', function($event) { // Replaced saved with saveReady $page = $event->arguments(0); // Replaced [0] with (0) $summaryField = $page->summary; // Removed ->field('name') $bodyField = $page->body; // Removed ->field('name') if (empty($summaryField)) { // Removed ->value $page->summary = strip_tags(substr($bodyField, 0, 192)); // replaced $summaryField->value with $page->summary, $bodyField->value with $bodyField } }); } Note that "save" hook is executed after the page is saved, so it's too late. Documentation : Page and Pages hooks EDIT : Note that you can also do that without creating a module, just by adding the hook ($this->pages->addHookBefore...) in site/templates/admin.php
  16. @joe_g What do you mean by adding roles dynamically? $page->authors->add($john);
  17. Hi @antoine.ctrs, did you read MAMP Pro documentation first? Setting a server environment is not specifically related with ProcessWire. You can test your installation with a simple index.php and a phpinfo() call. When it works, try with ProcessWire (unzip folder in a served directory and go to this URL with your browser).
  18. That's probably the issue. print_r output shows it's a PageArray, so we can't call PageArray->title. Instead of editing the code it's better to edit the PageReference configuration to set it to a single page and choose a single selection mode (a competition has only one winner):
  19. You should try this. 👆 And this: echo("<pre>" . print_r($championship->winner_name, true) . "</pre>"); exit(); And maybe show the configuration of the PageReference field. I have no idea what is going on. 🙂
  20. Reading that I understand you are not using the User template, isn't it? So the property is still "title" and not "name". Could you post 2 screenshots from PW admin? One of the "player" template properties (the green bars), and one of the "player" page with ID 1442.
  21. No, how to store thousands of users on 2 digits ? 🙂
  22. Ohhhhhhhhhhhhhhhhhhhhhhhhhhhhh yeah I understand, we are all forgetting something tiny but quite important: the property to use on User is "name" instead of "title". 😆 $playerChampionships = $pages->find("template=Championship_results, winner_home_club={$page->id}"); foreach($playerChampionships as $championship) { echo "<li><a href='$championship->url'> $championship->title - {$championship->winner_name->name}</a></li>"; } Property "winner_name" should be renamed to "winner" since it's a User instance and not a string. 😉
  23. Hello, I can't reproduce here on PW 3.0.228, what version are you using and are you sure you don't test this page with a superuser (who has access to everything)?
  24. @JerryDi Looks like you missed something when adding "->title". I suppose you wrote: echo "<li><a href='$championship->url'> $championship->title - {$championship->winner_name}->title</a></li>"; instead of: echo "<li><a href='$championship->url'> $championship->title - {$championship->winner_name->title}</a></li>";
  25. I'd like to add a Fieldset Tab on this page where I put fields related to race results. Is it possible to focus this tab (display its content) via API in a hook? EDIT : forget this question, after saving a page it stays on the same tab it was before, so I don't need this finally.
  • Create New...