Jump to content

Jan Romero

Members
  • Posts

    680
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Jan Romero

  1. Not thinking about this too much, one obvious problem is that you’re querying the database for every item in your inner loop. This is problematic for two reasons: It’s going to be a lot of individual queries Each query seems to depend only on $client, but you’re running them in the subscriptions loop. So every client’s subscription fetches the same data redundantly. Might be worthwhile to fetch all actions in one go and then select from those. So something like pages()->find('template=action, selectedClient.parent=1080, action_start>'.$today) or something. Although this might not work if there are many matching actions per client, since you only want the first one. ProcessWire does not support grouping selectors as far as I know, so this is kind of hitting the limits of the selector system. Tbh I would do this entire thing in SQL and be done with it, since you’re not returning ProcessWire objects anyway. You may have to do some output formatting yourself, but only to $action->selectedTrainer->text1, $action->selectedTrainer->text2 and $client->title, and it will be super fast.
  2. Confirmed on PW 3.0.188 and 3.0.191. Also, the HTML5 input for floats seems to be broken? It tells me the nearest valid values are -1 and 0 when trying to input -0.00001253. You should open an issue on GitHub about this. It seems pretty messed up for PW to fudge numbers by a factor of 100,000.
  3. Ah, but it wasn’t fruitless at all! Now you have the error message: “Page name does not contain restore information”. What is $trashedPage->name? It’s supposed to be the page’s ID, a period, the parent’s ID, another period, the sort position, an underscore, then the actual name, e.g. “2048.1999.4_felt-cute-might-trash-later”. ProcessWire needs this info to know how to restore the page. If it’s not there, something must have gone wrong when the page was trashed, but you can probably just add it manually. If everything else is good, the restore button should then appear in the page tree. It would be neat if ProcessWire showed this info to superusers. It could just be where the restore button would otherwise be, or the restore button could be deactivated with the note appearing on mouseover.
  4. I think you may have downloaded the dev branch at an unlucky time. Looks like this issue which has since been fixed. If you’re on that version, try updating.
  5. Can you call $pages->trasher()->getRestoreInfo($the_trashed_page) and dump the results here?
  6. Haha yeah, sorry, I forgot to supply getCommentByID with the $page and $field arguments… Glad you got it working, happy New Year to you too! Regarding comment editing, have you considered just rolling your own comment system with Pages (maybe even custom page classes) or multi fields like Repeaters? That would allow you to use common ProcessWire skills instead of fighting this specific module.
  7. Hey @modifiedcontent. I’m not the best person to answer this because I’ve never used FieldtypeComments, but since there are no other takers, let’s see… First and foremost, do you really need to call that method? It seems to me that it’s mostly intended for internal use by the usual save functionality. You should be able to delete a comment by just removing it from the WireArray and saving the Page or the Field. What you want to do should work like this, I believe: /* Get the field by whatever name you called it. * This will be of type CommentField. */ $field = $page->getField('mycommentsfield'); /* Get the Comment object you want to delete by * its ID. Note how we call getFieldtype() to * get to the Fieldtype itself. That will be * FieldtypeComments. * If you have already loaded the comments (and * the right pagination page) it may be better * to get it from there, as this will go all the * way to the database: */ $deleteMe = $field->getFieldtype()->getCommentById($page, $field, $id); /* Now since you already have your CommentField * you can call deleteComment on that. It’s the * same thing as calling the method of the same * name on FieldtypeComments and putting $field * in the $field argument. */ $field->deleteComment($page, $deleteMe); //don’t need the notes /* Get the field by whatever name you called it. * This will be of type CommentField. */ $field = $page->getField('mycommentsfield'); /* Get the Comment object you want to delete by * its ID. Note how we call getFieldtype() to * get to the Fieldtype itself. That will be * FieldtypeComments. * If you have already loaded the comments (and * the right pagination page) it may be better * to get it from there, as this will go all the * way to the database: */ $deleteMe = $field->getFieldtype()->getCommentById($id); /* Now since you already have your CommentField * you can call deleteComment on that. It’s the * same thing as calling the method of the same * name on FieldtypeComments and putting $field * in the $field argument. */ $field->deleteComment($page, $deleteMe); //don’t need the notes Now if you already had the Comment object, you could get all the information from there. Let’s assume it’s called $deleteMe again: $deleteMe->field->deleteComment($deleteMe->page, $deleteMe); //note how the comment itself contains references to its CommentField and its Page As to why the return type is mixed, if you check out the method’s code you’ll notice that it returns a variable called $result which may either be False, in case an exception happens when talking to the database, or if everything goes well it may be whatever $query->execute() returns. By default, DatabaseQuery->execute() returns an object of type PDOStatement, so it’s impossible to know the return type of deleteComment ahead of time. It might end up being a Boolean or it might end up being a PDOStatement, so it’s mixed. Like I said, I haven’t tested any of this myself, so I may have missed something and the above code may be faulty.
  8. @EyeDentify PageTable has been in the core for years. It was kindly sponsored by a Finnish company. I could have sworn there was a blog post about it, but I can’t seem to find it.
  9. Looks like you’re using @Wanze’s module Pages2Pdf. Unfortunately that module is pretty outdated and not compatible with PHP 8. I recommend switching to @bernhard’s RockPdf: $pdf = $modules->get('RockPdf'); $pdf->settings([ 'mode' => 'utf-8', 'format' => [210, 297], 'margin_top' => 20, 'margin_bottom' => 20, 'margin_left' => 20, 'margin_right' => 20, ]); $pdf->write("<h1>{$page->title}</h1>"); $pdf->write($page->body); $pdf->download($page->name . '.pdf'); It comes with handy output methods:
  10. While I agree that it shouldn’t be slow, I feel like moving pages should be an extremely rare occurrence and if you do it frequently as part of your usual operations, there probably exists a better way. Especially if those pages are publically accessible, because cool urls don’t change. For pages that just hold internal data, maybe one of the Repeater variants could be a better fit. Or a ProFields Table, or a something custom. Maybe instead of moving children around, just have Page References.
  11. Welcome to PHP lol https://www.php.net/manual/function.preg-replace.php https://www.php.net/manual/function.str-ireplace.php https://www.php.net/manual/function.str-replace.php https://www.php.net/manual/function.mb-ereg-replace.php (just use this) https://www.php.net/manual/function.mb-eregi-replace.php (or this) https://www.php.net/manual/function.mb-ereg-replace-callback.php https://www.php.net/manual/function.substr-replace.php https://www.php.net/manual/function.preg-replace-callback.php https://www.php.net/manual/function.preg-replace-callback-array.php
  12. Only if you tell it to: https://curl.se/docs/manpage.html#-L You’ll also have to increase the maximum number: https://curl.se/docs/manpage.html#--max-redirs
  13. Hi. Sorry about the short reply, but does the Permission “profil-edit” not do what you need out of the box?
  14. Oooh, the page name settings could be a select in the installer if there are enough useful and distinct ones. That would be dope. Definitely a super common need in Germany. @ryan shameless plug, since you’re going to be working on the installer, I opened a small PR inspired by a recent thread for your consideration ?
  15. y not function get_zehner($page) { return wire('pages')->count("parent={$page}, template=mitglied, mitglied_kategorie=Zehnerkarte"); } or even function get_zehner() { return wire('pages')->count("parent=/mitglieder/, template=mitglied, mitglied_kategorie=Zehnerkarte"); } I would additionally rename the function to something like anzahlZehnerkarte, because I would probably expect "get_zehner" to return a PageArray.
  16. Please show how you call get_zehner(). It looks like you’re passing in a Page object $page, but Page has no method count() that takes a selector. You can only call it without any arguments and it will give you the number of children of that page: https://processwire.com/api/ref/page/count/. Perhaps you want to use pages()->count($selector)? Also, this line is outside of <?php ?> tags and will not be executed: $mitglied->mitglied_kategorie = $_POST['Kategorie']; Also, please indent and use the forum’s code feature.
  17. Hi! If you want to accept any numeric value, you can just use Fieldtype Integer, Float or Decimal. As long as you don’t choose the HTML5 input, it will accept spaces and strip them when saving the page. If you still need further regex validation, it may be interesting to add regex validation to the numeric field instead of using a text field and dealing with the spaces. If you want to use Fieldtype Text, your idea of hooking ProcessInput seems good. Perhaps also look into hooking Fieldtype::sanitizeValue instead. Or maybe Fieldtype::sleepValue. All of these options will remove the spaces once when saving and then never display them again. If you want to show the spaces to editors for readability, consider horst’s idea or (assuming they’re deterministic like thousands separators) put them back in somehow. Fieldtype::wakeupValue will work, I imagine. Fieldtype::formatValue wouldn’t be the right choice here, because, as you noted, it only formats for output on the page, not for input fields in the page editor.
  18. I think the easiest and arguably cleanest way to detect this would be wire('page'). In the Admin it will give you the system page with the ProcessPageEdit process, ID 10. When it’s your API it should be whatever page you set up as the endpoint. Or you could look at input()->url or something.
  19. Indeed… Like I said, the code is the best documentation. So I guess it’s $page->setAndSave( [ 'title' => "($id) $template_label | $address, $ort" , 'name' => "$id $template_label $address $ort" ] , null , [ 'noHooks' => true ]);
  20. No, because unfortunately the docs don’t show an example with multiple fields and the options array. I may be wrong and it’s a little difficult to see on mobile, but I would say it needs to be two separate arrays, like this:
  21. Come on, man, you can do this ? That’s the same error message from before. Also, like I said, I’m pretty sure you just had to move the one ] to a different place. The number of brackets was correct. I haven’t been on the computer much today. I can look at the language stuff tomorrow, if you want. Btw a good “trick” is to just skim the actual source code of PW methods. I often find the docs a little lacking, unfortunately. Ryan’s code is quite readable, and usually one is only interested in what happens to the arguments, where best to hook etc. Somewhat superficial stuff like that, if you will, so it’s not too bad. For example, it seems your code is mixing up the fielname/value array and the options array when calling setAndSave(). PW functions often takes multiple different types in multiple different places, which can be a blessing and a curse.
  22. Hi, have you achieved your desired results yet? Just a quick note: if you change multiple fields on one page it’s probably more efficient to just change them individually and then call $page->save() once, instead of using $page->setAndSave() multiple times. Read the docs for more info. Also be aware you’re changing the page’s name every time (well, kind of) Address or Ort change. That can be desirable, but if the page is accessible at its default URL, that URL won’t be stable, and as everybody knows, cool URLs don’t change. I’m not sure I completely understand your requirements, but it looks like it should kinda work? Obviously when you generate the page name in Pages:added and save it, the Pages::saved hook will be triggered and override that change, so you might want to run the first one with ['noHooks' => true] or just get rid of it.
  23. Just to add to the reports, I have coincidentally encountered this issue just minutes ago and thankfully remembered this thread. Bernhard’s/Robin S’s fix worked for my image. It was EXIF orientation 6 (confirmed this to be in line with the specs. 90° CW to make it upright), shot on some old-ish Samsung phone and uploaded without client side resizing. The original showed up fine, but the generated variations were upside-down. Thanks!
  24. Umm yeah I mean did you run that code? From the looks of it I would say it should rain errors, but if it works for you, that’s great! Allow me to step through and critique it anyway: $this->addHookAfter("ProcessPageAdd::buildForm", function(HookEvent $event) { //get the result of the hooked method, which is a form (class InputfieldForm). //it’s also the only form we care about here, so calling it $form is fine. $form = $event->return; //this gets the parent page, so we can stop doing anything unless we are //at the correct position in the page tree. good. //note the indent I added, though ;) $parentField = $form->getChildByName('parent_id'); $parent = pages()->get($parentField->value); if (!$parent->matches('template=dashboard_customer')) return; /*this is going to error, because $page does not exist here. you CAN *call the current page by writing any of this instead of $page (you *don’t WANT to do that here, though. read on before you change this): * - page() (if you have functions API enabled in config.php) * - wire('page') * - $wire->page * - $this->page * - $this->wire('page') *see https://processwire.com/docs/start/api-access/ *since this is confusing and for all other reasons stated in that link *i would recommend simply always using page() etc. */ $pageid = $page->id; /*this is just weird and unnecessary unless your template labels contain *slashes and end in .php, which in itself seems weird and unnecessary? *if you want a template’s name (usually the same as the template file *without the extension), just use $template->name. * ===> importantly, none of this makes sense because when this code runs, you <=== * ===> cannot know the page’s id nor its template!!! <=== * ===> you want to give the page ITS OWN id for a name. this is impossible to <=== * ===> know at this time, as the page has not been created yet. the template, <=== * ===> likewise, has not been chosen by the user. this code BUILDS the drop <=== * ===> down field that lets the user choose a template! <=== */ $template = basename($page->template->label,'.php'); //this was my suggestion to get the page name field from the form, however, //as we see below, you have discovered a better way, which is great! $nameField = $form->getChildByName('_pw_page_name'); //this was my suggestion to make the field invisible. as you’ve discovered, //you could also use $nameField->collapsed = Inputfield::collapsedHidden. //there is a difference, though! AFAIK, Inputfield::collapsedHidden will //completely REMOVE the field from the form output, so you can’t change it //with javascript. that was my main reason to use the class instead, //because you may actually want to do that. $nameField->wrapClass = 'InputfieldHidden'; //this shouldn’t work because of the $page business above. I guess it will //result in "() " because neither $pageid nor $template can have any //reasonable values. //moreover, you can’t use parentheses or spaces in page names, so they will //get stripped or converted to - anyway. remember this is the page name, not //the title. $nameField->value = "($pageid) $template"; //this is unnecessary because we have already put $event->return into the //variable $form. $titleField = $event->return; //this is great, but you should remove the above line and use $form instead. if(!$titleField->has('title')) return; //this is a great way to get the title field from the form! also a great way //to get rid of it. it will still allow you to put a value inside at this point. $titleField->title->collapsed = Inputfield::collapsedHidden; }); Now to do what you really want, you need to hide the fields you want to hide in this ProcessPageAdd::buildForm hook and use an additional hook to set the values. That second hook will have to run at some point when all the things you need to generate those values are known. Since you want to use the page id (there is no real reason to have the page id in the name that I can think of!), that point has to be AFTER the page has been saved. That’s fine, but if you contented yourself with just the template name + a number generated by PW, you could use the Javascript option I suggested above and obviate the second hook. It’s no biggie either way, so whatever. You could hook Pages::added, making your entire code look like this: $this->addHookAfter("ProcessPageAdd::buildForm", function(HookEvent $event) { $form = $event->return; $parentField = $form->getChildByName('parent_id'); $parent = pages()->get($parentField->value); if (!$parent->matches('template=idee')) return; //using the neater way to edit the field! $form->_pw_page_name->collapsed = Inputfield::collapsedHidden; $form->_pw_page_name->value = 'this is a temporary name nobody should ever see, just leave it'; $form->title->collapsed = Inputfield::collapsedHidden; //no default value for the title }); $this->addHookAfter('Pages::added', function(HookEvent $event) { //this time, we can get the page that has just been created! $page = $event->arguments(0); //same as above: only run under certain parents if (!$page->matches('parent.template=idee')) return; $page->setAndSave('name', "{$page->id}_{$page->template->name}"); });
×
×
  • Create New...