Jump to content

teppo

PW-Moderators
  • Posts

    3,208
  • Joined

  • Last visited

  • Days Won

    107

Posts posted by teppo

  1. If I'm reading this correctly, the confusion is all about what "age of cache" means, right?

    Currently "age of cache" refers to the expiration time of the cache, not to the time it was stored. Meanwhile you expected it to mean the time the cache was stored. I've always assumed age to refer to the expiration time, but you are correct — it is not unreasonable at all to expect age to refer to the time of storage 🙂

    In terms of documentation, something along the lines of "Optionally specify expiration time" and "If cache exists but has expired, then blank is returned" would perhaps be more in line with actual behaviour, but generally speaking the rule of thumb is that in this context "age" is about "expiration time" rather than "storage time".

    To be clear I'm quite certain that the way the function works and the way it calculates expiration is exactly how it was meant to work — and even if it wasn't, changing it at this point would be a major breaking change in terms of behaviour for existing setups.

    • Like 5
  2. On 5/22/2023 at 6:57 PM, BrendonKoz said:

    Beyond that, it still uses ProcessWire's own search functionality; it doesn't expand upon it. ProcessWire can do some pretty significant things in search, but overall it still relies on MySQL's fulltext search to handle everything. MySQL can offer some level of relevancy (depending on the PW selector search you choose), but it can't, as far as I know, order by number of matches found.

    This is true, with a couple of small twists:

    • SearchEngine supports "pinning" specific template(s) to the top of the list, or alternatively grouping results by template. These require making slight modifications (adding extra rules) to the query (DatabaseQuerySelect object) generated by ProcessWire.
    • In the dev branch of the module there is a work in progress "sort by relevance" feature, which also modifies the query. This is based on MySQL natural language full-text search, so it's still up to the database to decide how relevant each result really is.

    Sorting results by number of matches, giving some fields more "weight" than others, etc. are not currently something that this module does, though I have occasionally considered if they should be. The main issue here is that it would require different storage and search mechanisms, so it's a lot of work, and additionally it would raise a few rather complicated issues (e.g. handling permissions, which is something that we currently get "for free" by relying on selectors.)

    Not sure how sensible that would be, all things considered. It might make more sense to use SE to feed data to a separate search tool, or ditch SE altogether for that sort of use case 🙂

    • Like 3
  3. Just wanted to say that this is indeed a very nice update!

    For an ongoing project I'm relying heavily on WireCache for caching due to the nature of the site: most users are logged in and there is a ton of traffic at very specific times. Keen to implement any performance enhancements, and Redis has been on the top of my list. Definitely interested in using (or developing, if need be) a Redis WireCache module.

    Sure, we have CacheRedis already, but a drop-in solution would be even better.

    (... not to mention that core support for drop-in caching modules is one instance where WP has been ahead of PW. Not that it matters all that much, but still happy to be able to tick that box 🙂)

    • Like 7
  4. On 5/5/2023 at 4:14 PM, gebeer said:

    Now if you can tell me how I can throw a 404 without getting an Exception in my autoload module, that would be awesome 🙂

    That's going to be a problem. ProcessPageView::execute is responsible for calling ProcessPageView::renderPage or ProcessPageView::renderNoPage, which are the two methods responsible for catching and handling 404 exception. In this case you're preventing the core from doing what it would normally do.

    Instead of looking for workarounds (which may not exist), it's easier to just handle segments in templates, or define allowed segments (as discussed above). If you need to serve a page from an URL below home page that doesn't match an actual page, and this needs to happen in a module, it's better to leave URL segments out of the equation (just keep them disabled) and instead use URL hooks or hook to ProcessPageView::pageNotFound.

    • Like 4
  5. Depending on how you're handling unrecognized URLs, this could be a feature (sort of). If you enable all URL segments and don't throw 404 with the Wire404Exception::codeFunction code (or via wire404() function), no further hooks will (or should) be executed.

    See wire404() function docs (and/or function definition) for more details.

    ... though if you're already handling them as described above, then it's likely a bug 😄

    • Like 3
  6. Hey @RIC Developer

    Thanks for the suggestion, makes sense to me. Latest version (1.10.0) of the module has a specific setting for allowing/disabling removal of rows. Additionally settings (all of them) can be defined in site config, in which case they are no longer editable in module config:

    $config->ProcessLoginHistory = [
        'allow_remove' => 0,
    ];

    Note that there was already a separate (optional) login-history-remove permission: if this permission exists, it is required in order to remove rows. This was undocumented, but I've added a separate permissions section to the README.

    • Thanks 1
  7. On 4/11/2023 at 1:31 AM, wbmnfktr said:

    #1: Clients look into the modules section, see a huge list of modules, yet they were assured NO 3rd party modules were used. 😲

    I know I'm cutting corners here, but in my opinion that distinction already exists: "site" and "core". This should be easy enough for a client to grasp, though of course you may need to explain it (at least) once first 🙂

    ProcessWire is by design a modular system, even at the core level, and hiding that would mean that you are hiding a defining architectural design decision and — arguably — advantage over some other systems. If you need to go to such specifics (I haven't, and in fact I have never granted client access to modules at all, though that's of course more about business model; if the client hosts and maintains the site, they will need full access) I would argue that it's better to explain how and why this is actually a good thing, not an issue 🙂

    Meanwhile (again in my opinion) "site" modules are third party modules, regardless of who developed them, though of course it's not a huge stretch to argue that those built by Ryan are 1st party. If you want to signal that Ryan's modules are from the project architect/lead, I guess that could make sense. Still sounds like an oddly specific requirement from the client, though, and I would again explain why some "official Pro-modules" are used 🤷‍♂️

    • Like 4
  8. 12 hours ago, MarkE said:

    This might be achieved via an “allocation” field (float or decimal) in the order and the payment.

    Perhaps obvious, but do not use float for money. It will result in rounding errors.

    Also, regarding allocations (if you go this way), consider early if you need more than one per payment. E.g. if you need to allocate payment per invoice/order row, or allocate overpayment separately, etc. And also give some thought to how you'll handle returns/rebates etc.

    (In my experience two-way sync is rarely necessary, since PW makes querying data easy anyway. But you will likely need some hooks to keep things like order payment status in line with payments.)

    I recently built a system that handles event registrations and product sales, and my approach was basically "approach 3".

    One question is if you need to also handle accounting reports, and at what level. Honestly this is all relatively simple until debit/credit entries, cost centres, accounts, etc. get into the picture. In my case I do need to handle that, so each order/allocation logs a separate accounting row, which I later use to produce a sensible report. Including actual time of each event, which is super important here.

    • Like 3
  9. Template Access Log is a straightforward module that logs changes made to template level access settings: the useRoles option, or applicable roles and/or role-specific permissions. This module is primarily intended for use cases where an audit log is needed, and (at least for now) it just logs data to a log file template_access_log.txt and provides no admin view (apart from what can be found from the logs section in admin).

    Data is logged as JSON:

    2023-03-18 18:42:05     admin       https://example.com/processwire/setup/template/save   {"template":"basic-page","template_id":29,"use_roles":1,"permissions":{"view":[37,1061,1062,1125],"edit":[1062],"add":[1061,1062],"create":[]},"permissions_changed":{"edit":[-1061]}}

    This is something that I needed for some projects, so thought I'd share it here in case someone else has use for it as well. I may add more features later, but at the moment it's already doing pretty much everything it needs to for my use case(s) 🙂

    • Like 8
  10. On 3/15/2023 at 7:21 PM, Ivan Gretsky said:

    This controller should not be connected to any PW template and should have some independent name. How can I do it? Please help!

    Personally I would consider an alternative approach, having this auth form as a separate page that you pass the original page to. This way you could have it as a separate entity, but still have access to anything that the original page contains.

    In this scenario you could have the original page fetch and then render the authorization form page, and return rendered content from there, instead of content of its own. Though of course I may be missing plenty of nuance in your use case 🙂

    In case it makes more sense, it is also possible to set/override the controller for a page (by calling $page->setController('TemplateName')) just like it is possible to set/override layout or view. Technically this might mean that while rendering a page you detect this situation and then re-render the same page with different controller. Feels a little odd, and I'm not entirely certain that it'll work, but I can't see why it wouldn't either.

    • Like 1
  11. On 3/9/2023 at 2:52 PM, MoritzLost said:

    @eydun Yeah, but it's a bit involved. ProcessWire expects its core files in the webroot and won't work properly if they're inside the vendor folder. What you can do is use Composer scripts to hook into the Composer installation and put all of ProcessWire's files in place.

    We're using a similar approach: install ProcessWire via Composer and then use post-install-cmd and post-update-cmd to copy the wire folder from vendor to web root. It would be preferable not to have to do the whole post-[install/update]-cmd step (or have entire wire directory in public directory for that matter) but to be honest this works quite well.

    Some files in wire need to be web accessible, so I'm not aware of any clean way around this.

    To be clear this is about installing and/or updating ProcessWire on a site that has already been set up. As for setting up a complete, new ProcessWire setup via Composer... I've no experience about that. Technically you could install ProcessWire via Composer and then copy everything from vendor/processwire/processwire/ to your web root, but for my use cases that has never really made sense 🙂

    • Like 2
  12. Technically speaking best approach would be to block the IP as early as possible: preferably via firewall (on local machine or before it), but if that's not possible then Apache config, and if that's not possible either then .htaccess.

    Blocking access early means that more unwanted traffic gets blocked out, and it is also better for performance 🙂

    That being said, I just updated https://processwire.com/modules/page-render-iprestriction/ to support a list of blocked IP addresses. This module can block access to your site, but note that it won't attempt to protect your static files, so again other alternatives are generally speaking preferable.

     

    • Like 3
  13. Just to be clear, which version of ProcessWire are you using? The implementation for populating pages_parents has changed a few times even in recent versions.

    Anyway, my understanding is that pages_parents should contain every page that has children — but again, the implementation has changed a few times, and earlier versions (before 3.0.165?) were not entirely reliable. Meanwhile the very latest dev version has another approach that fixes scalability issues that were introduced around 3.0.165, but this version is considered experimental 🙂

    • Like 1
  14. @adrian, I've got one more request (kind of). Earlier you added composer.json, but didn't yet push the project to packagist.org. Would be nice if you could add the module there as well, otherwise it can only be installed by adding the GitHub repository directly.

    Thanks in advance! 🙂

    • Like 1
  15. 12 minutes ago, adrian said:

    At the moment, all my modules still rely on the file compiler. I guess I just haven't seen the need to break any 2.x installs because it seems to work just fine and once it's compiled the first time, I don't think there is any significant (if any) overhead. Are you aware of any?

    Not really.

    I've had some issues in the past, mostly related to disk cache getting out of sync or somehow the module compilation itself messing up the code (but such cases have been super rare). Mostly it just feels unnecessary and a bit "off" to have a separate copy of the code and then have the system abstract that layer away.

    If I could, I would likely disable module compilation entirely from my/our projects (just like template compilation), but there are indeed still some modules that depend on it, so for now it's a no-go 🙂

  16. One more thing: I'm wondering if there's some use case where current way of getting properties via eval is necessary?

    I don't see anything technically wrong with that, but would feel better not using eval at all, and it tends to get flagged by security audits etc. This seems to achieve largely similar results, at least in latest PW version:

    $replacement = $p->get(implode('.', $properties));

    Again my use case for this module is very limited for now, so may be missing something important.

    • Like 2
  17. Hey @adrian!

    Might be a strange use case (considering that it doesn't seem to be supported yet), but I'd like to use this module for a field that's locked (non-editable). Looks like hooking into Inputfield::render won't work in this case, while Inputfield::renderReadyHook does work. To be honest I'm not sure what else that might change/break 🙂

    I've made that change locally since this is indeed something I need, and so far it seems to work (though not much testing done yet).

    Also... have you considered updating the module to PW3? I mean adding the namespace, mainly, so that module compile wouldn't be needed. And it would be great to have this module installable via Composer. Food for thought 🙏😄

    • Like 2
  18. 36 minutes ago, Robin S said:

    Could it maybe be loaded via a CDN? https://cdnjs.com/libraries/ace

    As someone who does a lot of local development, sometimes with no Internet access or extremely slow one (e.g. while travelling), this would not be preferable. Having everything available locally guarantees that things work as expected. Also it guarantees that the version I have can't be compromised by malicious actors. Assuming, of course, that it was safe in the first place 🙂

    Personally I don't have an issue with Ace, but if Monaco (or something else) does similar things with less overhead then why not 👌

    • Like 2
  19. So, I'm currently having a conversation with ChatGPT about a new module 🙂

    Feels weird to be honest: it's quick to answer, especially at first seemed absolutely certain that every answer was the correct one, and kept making obvious mistakes. But that being said: I could've taken the initial code, made a few changes here and there, and it would've been a functional module. Now, after some iterations, it's looking almost perfect.

    One problem I'm having is that the bot keeps stopping halfway through the answer. When I tried to confront if it about that, this is how it responded:

    image.png.1faa258caebc25c54a23bf76c797bed1.png

    Not sure we're quite on the same page here 🤔

    Anyway, it looks like I might be able to take the code provided by the bot, polish it a bit, and put it in use. Sure it required us a dozen tries or so to get here, I had to patiently keep pointing out mistakes and suggest actual hookable methods instead of the non-existing ones that it pulled out of thin air, but that is very impressive nevertheless.

    I can definitely see how this would be useful for something a little simpler 🙂

    • Like 1
    • Thanks 1
×
×
  • Create New...