Jump to content

cwsoft

Members
  • Posts

    206
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by cwsoft

  1. Have you tried a simple var_dump($int); exit; after your third line of the last code block in your template file? Then I would to a $match = $pages->get('id=' . $int); var_dump($match); exit; to see if your result is a null page or a match. For debugging I would install Tracy Debugger from the PW module repository and then just add some bd($object); calls to get an idea of whats going on.
  2. Hi nice post. Just missing the content somehow. Would be nice to post a link to the PW modules directory with your module or at least to your Github (or similar VCS) repository. But the code examples look great by the way 🙂
  3. After using the new style/theme from the dev branch for about a week now, I switched back to the default theme from the main branch recently. I wasn‘t able to adjust to the light grey background and the reduced colors on input elements or background of notes and messages. However I guess I am not the intended audience to be attracted by the new style/theme either. I only use dark themes when it comes to VS Code Editor, all other Apps stay in light mode. But that was only after finding a dark color scheme, which pleased my eyes, which took about half a year of trial and error. The 15+ last years I used light themes for coding too. Only setting I do at night is to dim the iPad display for reading. Usually I stick with the defaults offered by the OS system or Apps, as I do find this look the awesome my Posh terminal adjustments just a waste of my lifetime. So I would not bother to have a new light style/theme which covers the edge cases for the most popular modules and pro modules out there and see the dark themes more as a yes we have that too, but it might be involving some tweaks of the CSS to get it working with the modules out there. Hope this won‘t lead to a split in the community or the leaving of PW supporters and module authors out there, as it could be seen on other CMS/CMF systems before. So keep up the good work, just setup a list with reported (real) issues - ideally focusing on light themes first and try to keep out personal preferences as good as possible.
  4. Hi, as you moved to another ISP, maybe try to disable fingerprinting temporarily and check if that works for you. $config->sessionFingerprint = false;
  5. Solved the issue myself thanks to Tracy Debugger and the handy bd() method. While inspecting the methods using bd($inputfield) I found a property called "hasInputfield" in the $inputfield storing the Page references. So I added the following lines at the end of the code in my initial post to set the notes on the nested inputfield which stores the Page References. if ($field->name === 'hotel') { $nestedInputfield = $inputfield->hasInputfield; $nestedInputfield->notes("$fieldInfo can't be modified."); } The class however needed to be set to the outer inputfield to disable the inputfield to prevent user actions on it.
  6. Hi, I have a hook, which disables some input fields and shows a note, why the input field is disabled. This seems to work fine just with one exception. When I have a InputfieldSelect with PageReferences as items, I can disable the select field, but the notes don't show up below the input field. It works fine for Select Options or other Inputfields like Datetime, Text etc. So I am a bit puzzled why my notes don't show up for PageReferences only. $wire->addHookBefore('InputfieldSelect::render', function (HookEvent $event) { $inputfield = $event->object; $page = $inputfield->hasPage; $field = $inputfield->hasField; // Limit to certain templates and fields. if (!$page || !$field) return; if (!$page->className === 'MyPageClass' || !in_array($field->name, ['hotel', 'branch'])) return; // Disable inputfield and show a notice to the user. $inputfield->addClass = 'uk-disabled'; $fieldInfo = $field->name === 'hotel' ? 'Hotel' : 'Branch'; $inputfield->notes("$fieldInfo can't be modified."); }); Both select input fields gets disabled, which is what I want, but the notes are only showing for the field branch, which stores Select Options. However no notes are shown for the field hotel, which stores Page References. Both fields are InputfieldSelect fields, but one storing options, the other page references. If I do a bd($inputfield), I can see that for the hotel field (with page references), there exists no parent (InputfieldWrapper), but for the field branch it's there. Output from bd($inputfield): parent: array(3) 'className' => 'InputfieldWrapper' 'name' => '' 'id' => 'InputfieldWrapper31' Does anybody have a glue, whats going on here? As mentioned, the note is shown fine for all Inputfield types (e.g. Text, Datetime, SelectOptions) except for PageReferences. Is there any other way you guys can think of how I could add a note below the inputfield, if the $inputfield->notes() method does not work? By the way. The notes text is shown just fine in the data section (bd) for both. Guess it must be related to the missing parent, which is the InputfieldWrapper. Any hints welcome. P.S.: This behavior is identical for both, the actual master and the actual dev branch and has nothing to do with the redesigned admin theme.
  7. Can confirm, that pages()->getFresh($page) works as well. The $page->get('field', 'sanitizer_method', 'default') was accidentally taken over from an $input->get call. Fixed it in my example code above. Thanks.
  8. @bernhardThanks for your suggestions. Will try the get Fresh call for sure. Fun fact is that my $cachedPage was named this way only in this example code. I used $dbPage and finally $oldPage for my own code. I indeed revert back up to four fields (page select, select option, textfield and datetime) on two different templates split in two separate saveReady hooks via saveReady(template=xy). In addition I overwrite page name and page title to some unique values using parts of some input fields and take care of setting a draft value for the page title when a page is newly created but not yet saved (my page title is an auto field not directly set by the user). So early returns are not always possible in this special case. I usally tend to use short circuit returns instead of nested ifs, whenever possible, which however isn‘t possible in my scenario, as the page name and the final title needs to be set last once all fields which may be part of it where sanitized and maybe reverted back to it‘s previous state.
  9. After playing about two evenings with various kinds of hooks, I just used a plain old Pages::saveReady hook, as this allows me to access all page fields of a certain page/template more easily. So my final code looks like this now. // Ensure first three chars of the required field 'location_place' can't be changed. $wire->addHookAfter('Pages::saveReady(template=location)', function (HookEvent $event) { // Ensure we have a valid page. $page = $event->arguments(0); if (!$page || $page->isTrash) return; // Get actual field values (required) entered by the user. $actualPlace = $page->get('location_place'); // Fetch previous page from database so we can check if 'location_place' has changed. $cachedPage = pages()->getById($page->id, array('cache' => false, 'getFromCache' => false, 'getOne' => true)); if ($cachedPage->id > 0) { $oldPlace = $cachedPage->getUnformatted('location_place'); if ($oldPlace && substr($actualPlace, 0, 3) !== substr($oldPlace, 0, 3)) { // Reset location_place to previous value and show an error on the inputfield. $page->location_place = $oldPlace; $inputfield = $page->getInputfield('location_place'); $inputfield->error('First three characters can not be changed. Input reset to previous value.'); // If you prefer less drama, just show a message instead of the error state on the input field itself. // $event->message('First three characters can not be changed. Input reset to previous value.'); } } }); However I may play with this hook too, just to check it's potential use case: https://processwire.com/api/ref/fieldtype-text/save-field-ready/ Cheers and thanks to @bernhard and @Robin S for your valuable feedback and proposals. Pretty sure they will come handy at some time for me.
  10. As promised some feedback. The easiest thing I came up with was a saveReady Hook, where I fetched the previous page state from the database and compared the fields needed with the actual values. However the code became a bit messy, as I have two templates one with three input fields one with two, ending in a gigantic switch block hard to maintain. What worked too, was the proposal from Robin S. However fetching the actual values from Inputfields of various types (text, datetime, select array, page select) needs some custom tweaks here and there to get the field values. Things can get tricky very fast, when using multiple hooks, which interfere with each other. Here it‘s key to understand what hooks fire first etc. At the end, I managed what I had in mind, but it indeed was a long way with lots of trial and error, reading the tutorial over and over again and inspecting the inputfield classes and with quite a lot of life debugging using Tracy. Without Tracy and the ideas and snippets found in the forum, I wouldn‘t be able to solve what I had in mind. So yes, managing hooks is still on my todo list, even after one year using ProcessWire for two part time projects.
  11. @bernhard @Robin S: Thank you very much for your code suggestions. Looks very promising. Will try both tomorrow and then report back. Giving an additional hint/warning directly to the corresponding inputfield like robin suggested seems a good idea in terms of usability. The idea of a temporary field is also a need trick. Tried with saveReady before, which seems to work, but felt a bit hacky to me, as I needed to fetch the uncached old value to check for potential changes in the text field. Always good to learn something new. Your answers are highly appreciated. Made my day.
  12. Dear all, I am struggling with implementing a before/after hook (tested both, didn't work), which should prevent users from changing the first 3 characters of a string in a specific text_field. Here is what I came up with for the moment in my site/ready.php. The bd() debug calls indicated, that the "new" value is reset to the "old" value inside $event. However when clicking "Save" in the backend, the "new" value will be saved and populated instead. // Prevent user from changing the first three characters of a text_field on a specific page template. $wire->addHookBefore('Page(template=my_template)::changed(text_field)', function (HookEvent $event) { // Ensure we have a valid page to save. $page = $event->object; if ($page->id === 0 || $page->isTrash) return; // Allow changes of the text_field value if the first three characters remain unchanged. $old = $event->arguments(1); $new = $event->arguments(2); if (mb_substr($new, 0, 3) === mb_substr($old, 0, 3)) return; // Revert back user input in case the first three chars differ. bd($event); $event->arguments(2, $old); bd($event); $event->warning('First three chars of text_field can ot be changed. Reset to previous value.'); }); Seems I am missing something here, but I can't figure out what exactly. Could anybody give me a hint why this won't work? Do I need to implement this in the Page:saveReady hook instead? If yes I guess I would need to fetch the old values from the uncached page object to compare old/new values. Thats why I thought the Page:changed hook would make more sense. Any hints or comments are welcome. Cheers
  13. Had similar issues with login on local site a while ago using DDEV. I put a config-dev.php into my local site folder and set the $config->httpHosts to my local site domain.ddev.site. In addition I changed the Session suffix for my localsite so I could open live and local site in the browser the same time. Otherwise the sessions will overwrite each other causing weired issues. With this two changes everything works great even live/local site by site in different browser tabs.
  14. Hi, I first went to the tutorials section, where I first read the different output strategies. After reading the three different main strategies, I decided to go with my first steps using the Delayed Output strategy. https://processwire.com/docs/tutorials/default-site-profile/ https://processwire.com/download/site-profiles/ Choosen: Default profile (standard/intermediate edition) Then I started to add some pages and started to add simple things in the template files using the great Processwire API and some plain PHP. After I created my first prototype and got the go from my customer, I reimplemented the site with some more structure using PageClasses and Latte template engine for the views, while sticking to the delayed output strategy. Some times later I added Markup regions to my sites frontend login template to alter the header and footer region for guest users. My advice is to start simple using the Default profile (standard/intermediate edition) and work on some tutorials and try to alter or add functionality in small steps. Cheers
  15. If it‘s just one language and one or two spots you need to deal with month or weekday names, I tend to use an array with e.g. the month names defined in the Latter template in combination with a PHP date format string like „n“ used as array index pointing to the month name needed (or „N“ for the weekday number).
  16. @YipperI struggled on this topic in my first project too. I used delayed output strategy for the first prototype. Then I did a rewrite over a weekend with all the stuff I‘ve learned in the meantime and restructured code into Page Classes and switched from PHP templates for the view part to Latte template engine where it made sense. Fun fact. To overwrite some template parts (e.g. navigation, footer) until guests logged into the frontend, I used Markup regions on the login page to overwrite the default template parts, which shouldn‘t be visible for guest or spam bots. Lessons learned. It‘s more important to get started then overthinking which strategy to use. You will learn a lot and some of the available strategies may come handy later, once you know, how and where you can make use of it.
  17. Similar here. I init my PW Git repos inside the site folder and to exclude some stuff via .gitignore.
  18. @kongondoCool to know. So far used ddev exclusively from the bash shell, as I worked several years on Unix systems. However, I may check out this VS code Add-in with one of the next projects.
  19. DDEV works great on Ubuntu in WSL2 on Windows 11. Installed VS Code in Windows with an extension to work remote on Linux too. So I do all my Web dev work in Ubuntu. Ubuntu file system shows up in Windows explorer too. This makes it easy to transfer files from Ubuntu to the WWW server using Filezilla on Windows by just using the local path to Ubuntu. Copying files from Windows to Ubuntu can easily be done via cp /mnt/c/Users/user/Downloads/file.ext . too. So WSL2 in comnination with DDEV and VS Code is really fun.
  20. Hi Natalie, welcome to the PW forum. I would start setting up a local development env (like ddev) with a clean PW installation and a blank template. Then I would decide on a output strategy, like delayed output. Next I would create the HTML template using the look of your old site with some basic pages and the nav menu. Once that is done, I would try to implement one dynamic page (e.g. member login area) from your old site and see how for you get. If you hit a wall on your journey, come back in the forum and ask for guidance. The community here is very kind and can help you on your way. Thats how I started with PW. After the first implementation with just the PW API and basic concepts, I did a rewrite using some of the more advanced techniques like implementing the Latte template engine and PageClasses. But my first setup was just procedural PHP code organized in functions stored in helper files and basic PW PHP template files using the great PW API. That get‘s you started quickly, which I think is more important than trying to get the most sophisticated features implemented right from the beginning. I tend to go with release soon and iterate fast approach most of the times. Just my two cents. Cheers cwsoft
  21. https://processwire.com/docs/security/admin/#preventing-dictionary-attacks For sites with simultaneous users coming from the same shared IP address, throttling by IP address may lock out legitimate users. Had this scenario with a project with about 1.000 frontend user accounts, which could sign in for courses. All get an E-Mail with their login credentials at about the same time. We had about 50-100 users from a big company using a shared IP address. Here some (5-10) of those users where blocked. So I allowed some IP ranges to not lock out legitimated users sharing the same IP address, simply to reduce the support request for my clients site operators. If this scenario doesn‘t matter for your sites, I would always turn on throttling by IP address.
  22. Running latest ddev version on Windows 11 under wsl2. No slow down seen yet compared to previous versions.
  23. Hi. Have you tried to add include=all or include=hidden as parameter or via the options array to the get or find API calls? See API overview for details: https://processwire.com/api/ref/pages/find/ From the API doc page: include (string): Optional inclusion mode of 'hidden', 'unpublished' or 'all'. (default=none). Typically you would specify this directly in the selector string, so the option is mainly useful if your first argument is not a string. Cheers cwsoft
  24. @BrendonKozYes that is exactly the issue. The method processInputFile executes on both upload and deletion using the file input field. The processInputAddFile does not allow easy access to the pagefile and the other infos like page object etc. needed to unzip the files to the designated spots. Thought there might be a PW way of preventing trigger to kick in (e.g. by adding data to return value object) or to detect inside processInputFile if this was triggered from processInputDeleteFile etc. The easiest method I came up with is to set a PW session variable inside the delete hook and check for it in processInputFile to skip the extraction of the ZIP file. This works fine, but I doubt that this is the ideal way of doing it.
  25. @BrendonKozThanks for your suggestion. Basically an editor can upload a zip file with PDF participation certificates for courses from a page file field in the backend. Once the ZIP file was uploaded, the PDF files should be extracted to a folder inside site/assets/files/upload, which is protected via .htaccess from direct access. At the end of the year the extracted PDF files will be deleted by the course editor, by deleting the corresponding ZIP archive via pressing the trashcan icon of the page file field. The course attendees can download their PDF certificate after the course is finished from their course page available after frontend login. This is done by clicking a download button, which reads the binary contents of the corresponding PDF file and sends it as PDF file to the browser for download using PHP header functions. So the PDF files are not touched after upload until they get deleted at the end of the year. The PDF files should stay around until the end of the year or a predefined time period before getting deleted. So I do need two hooks. Upload of the ZIP file triggers the unzip task and the deletion of the ZIP archive should trigger the delete extracted PDF files task. Timing won‘t help, as the delete action should not trigger the unzip process again.
×
×
  • Create New...