Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by DrQuincy

  1. I have had a client say that because the dev and live hosts are so similar they get confused between the development and production CMSs. They have asked for a way to make it clearer which environment they're in. Although it says “The site is in debug mode, suitable for sites in development” in yellow when you log in on the dev version I think they are wanting something more obvious. An easy solution would be to add a message at the top of the page in debug mode. After messing around with Inspect element it seems if I could insert custom HTML before div#pw-mastheads that would do the trick. Is there a hook for this? I could do it with custom JS but is there any way to tell from the DOM or an existing JS variable if it's in debug mode? Thanks.
  2. Thanks. ? I'm going to try and implement this when I get the time. I'm thinking use your code running only on Pages::delete with status!=trash added to the selector — and then issuing a warning on Pages::restore if there are any broken references (possibly also setting the page to unpublished). I'll post something once I've had a go.
  3. The above is great @Robin S, thanks. The issue I have though is if Page A references Page B, you can delete Page A. But then when you come to delete Page B it won't let you because it sees a reference between Page A, which is in the trash, and page B. I'm struggling to come up with a solution that will always work in a user-friendly way. If you only run the above just on delete (and not trash) then that fixes my initial problem but what could happen is a page could be restored while the page it references is still in the trash. What do you think would be best practice here? Run your code above on delete only and then do a similar check on restore — only on restore simply issue a warning since at that point the reference is broken. I'm just finding when thinking through all the scenarios it gets complicated and I'm wondering if you run that hook above without adding parent!=7 to the selector (to ignore trashed items) it can get messy and prevent legitimate deletes and trashes. Maybe it's just better to enforce on delete and on the edge cases where page are restored issue a warning. Hope that makes sense and I've understood it correctly!
  4. I have an older site where the client wishes to add a general site search: a single search box that will search everything. I have done this before by adding a hidden text field to each searchable templates and creating a plain text version of the page when it is saved (using hooks). Then when I do a search using ~= for fulltext and if the number of characters if fewer than the minimum character limit for natural language search for that engine I switch to %= and do a LIKE search (although searches must be at least three characters). This site (which uses MyISAM), however, is based in the engineering industry and as well as the usual pages of about, news, etc they have products and manuals that they will want to be made searchable. I am wondering if a user searches Acme 123 will it only search for Acme since 123 is too short for MyISAM — rather give more weight to the specific 123 product? I guess it depends on the selector (see below). I'm wondering how to approach this. With my custom work I tend to write a query that does a MATCH AGAINST with the phrase with no quotes and then again wrapped in double-quotes, given more weight to the latter (you can do this with InnoDB without having to use BOOLEAN MODE) via the relevancy score. The problem is natural language is better for general searches but LIKE is possibly better for searching product names. I'm not sure there's an easy solution other than to add a checkbox “Exact match only (useful for product searches)” — unless there is a way to do it with fulltext selectors. I've noticed that newer versions of ProcessWire offer a wider selection of selectors. Here are the relevant ones: FULLTEXT *= Contains phrase/text Given phrase or word appears in value compared to. ~= Contains all words All given whole words appear in compared value, in any order. ~*= Contains all partial words All whole or partial words appear in value, in any order.* ~~= Contains all words live All whole words and last partial word appear in any order.* ~|= Contains any words Any given whole words appear in value, in any order.* ~|*= Contains any partial words Any given whole or partial words appear in value, in any order.* **= Contains match Any given whole words match against value.* LIKE %= Contains phrase/text like Phrase or word appears in value compared to, using like. ~%= Contain all words like All whole or partial words appear in value using like, in any order.* ~|%= Contains any words like Any given whole or partial words appear in value using like, in any order.* *Available in ProcessWire 3.0.160 or newer. I'm just a bit lost as to which selectors to use. If you use word-based fulltext selectors does it still match phrases as well and give a higher relevancy? If there's a way to search Acme 123 as an exact match first and then just Acme and 123 separately (the latter would be ignored though unless using InnoDB, which is fine) and still return results by relevancy that would be ideal. When using fulltext selectors can you combine them and have results returned by aggregate relevancy? Any advice or experiences would be appreciated. ?
  5. I have created a brochureware template site that I can clone and put sites together more quickly. I have just copied it for the first time and I replaced the $config->userAuthSalt and $config->tableSalt values with a cryptographically secure hex token of the same length. I have the password reset module installed so reset the password and logged in no problem (there is only one user in the template). The site seems to work fine. I just wanted to check this was safe to do. It seems userAuthSalt is a secret salt for hashing the user passwords (in addition to the one built in to bcrypt) hence the need to change the password. Looking at the source it seems tableSalt is never used internally by PW anyway. Am I right in my assumptions? If so, I'm probably okay to change them as I have done — and actually having multiple sites with the same values is also not going to be much of an issue in most cases.
  6. Good to know, thanks. You answered that in record time, by the way. ?
  7. I've noticed that some of my older PW sites are missing /wire/config/install.sql on the remote servers (I think it's down to an old rule I had in my file transfer client that I have since changed). I'm just wondering: is this file ever used again after installation? Thanks.
  8. Ah yes, good idea. I have used them already for some redirects.
  9. Thanks a lot for such a detailed reply, it is most useful. ? I always leave the login as /processwire but then they tend to be brochureware type sites so not exactly highly sensitive. Yes, I think this is exactly what I will do. Like you say, it's easy to do so might as well.
  10. To keep the main site tree clean I have added a collection of JSON templates to /processwire/api/{reference} However, it has occurred to me that this means I need to include that path in my JavaScript to make the API call. Am I at any significant disadvantage if a hacker knows the CMS login path to be /processwire/? I know WP users change /wp-admin/ to something else but it is my understanding ProcessWire is much more secure. Does it really matter? The docs say there is dictionary attack protection built in via throttling. Thanks.
  11. I have this code: $formPage = wire('pages')->get('/forms/contact/'); $formPage->of(false); $formPage->formFields->get('id=1075')->formFieldLabel = '<strong>Test</strong>'; // This works $formPage->formFields->get('id=1075')->formFieldAttributes->get('property=placeholder')->value = 'New placeholder'; // This does work echo $formPage->formFields->get('id=1075')->formFieldAttributes->get('property=placeholder')->value; // Echos old value rather than 'New placeholder' I have forms stored in a template. I want to be able to dynamically override some of the values in the page/ form file but I don't wish to save them. The reason being I pass the \ProcessWire\Page (form) object to a function that creates the HTML for the form. Saving it would alter the form in the database whereas I just want to do it for this request only. In this case formFields is a repeater and formFieldAttributes in a Pro Fields Table field. Is this possible?
  12. I just wanted to check how the new “Prevent direct access to file assets owned by pages using this template?” option works under the template Access tab. The first option works as PW has done historically. If I choose the third option then it seems I only get a 404 if the current user doesn't have view access to the page. So, that's great. It seems to change the folder now so that is satisfies a different .htaccess rule to control access. What I'm unsure of is in the second option where it says: What is meant by “publicly accessible”? Would this be a page that uses the admin template? I just wanted to understand how it works because to me this implies role access — which seems to be the job of the third option. To be honest, if I ever wanted to secure files in this way I think I'd use the third option anyway. One general question: if you chose the third option and wanted to log the number of times a restricted file is accessed, which hook would you use? Thanks.
  13. Thanks for confirming. Another problem solved on this great forum. ?
  14. Thanks. I have found out the issue and it was not permission-related. In file-errors.txt I had this error: allowPath: pathname may not traverse “../” I don't really understand how it works but from looking at the source is seems WireFileTools->allowPath() is blocking it. This fixes the error: public static function createDuplicateImage($src, $dest) { if (file_exists($src) === false) { return false; } // Duplicate the file \ProcessWire\wire('files')->copy($src, $dest); // NOTE new line $dest = realpath($dest); return new \ProcessWire\ImageSizer($dest); } You need to call realpath() after file duplication (since realpath() does not work on non-existent files). This sends the full canonicalised absolute pathname and WireFileTools via ImageSizer deletes the -tmp files. I'm not sure if this is intended behaviour but I hope that helps anyone else who needs to do this. I presume it is a security feature that blocks certain paths from file manipulation.
  15. @horst Thanks, this works great but I am left with some -tmp images. What I needed to do was create thumbnail images outside of PageImage context. So I need to duplicate the file first and then pass it to a new ImageSizer object and resize per your example. My code is like this: public static function createDuplicateImage($src, $dest) { if (file_exists($src) === false) { return false; } // Duplicate the file \ProcessWire\wire('files')->copy($src, $dest); return new \ProcessWire\ImageSizer($dest); } // ... $image = Util::createDuplicateImage('./foo.png', './foo-cropped.png'); $image->resize(250, 250); I get foo-cropped.png sized to 250px x 250px but am left with a duplicate foo-cropped.png-tmp.png. Looking at the ImageSizeEngine class this line is returning false for some reason: $this->wire('files')->unlink($this->tmpFile); Any ideas why? I am just on a local MAMP set up and have never had problems creating and deleting files with PHP before. Thanks. ?
  16. Ah, thanks. The documentation is great but with some many features it's easy to miss things. Here's the relevant page from the docs should anyone need it: https://processwire.com/api/ref/image-sizer/ Thanks to you both. ?
  17. If you want to resize an image that is not a PageImage is there a way to do it? No worries if not as I can just get Intervention Image via composer but didn't want to include a library I didn't need if PW can do it. I can't see anything in $files and it seems functions like size() can only be applied to PageImages. Thanks.
  18. It seems this is part of the ProcessWire core now so if you install 3.0.184 there is a template option: If you look in the latest PW there is a new rule that blocks access to folders in site/assets that start with a hyphen. If you attempt to access the corresponding URL without the hyphen PW will do authentication checks. Direct access to the folder throws a Forbidden error. If access is blocked to the file it 404s irrespective of the What to do when user attempts to view a page and has no access? setting. See
  19. Not sure if this is the best way as it involves adding code to every template file but this seems to work. Add a function in functions.php such as killWithstatusCode() that returns a simple HTML error template. This can check the current HTTP response code and output a message accordingly. Then at the top of each template add: if (http_response_code() != 200) return killWithstatusCode(); Technically, the response code could be between 200 and 299 and be regarded as a success so you could replace http_response_code() with a more concise function that checks if the code starts with a 2. if (!statusCodeSuccess()) return killWithstatusCode(); I did see Ryan say in an old forum post that if you don't wish to render a template then you can simply call return and ProcessWire will still handle the process. I also noticed that whatever string you return from the template ProcessWire will render. You might wonder the use case for this. I find it useful to be able to allow a CMS to use HTTP response codes that typically the server would handle. Being able to send 405 Method Not Allowed, for example, when creating a RESTful API or handling POST forms can be useful. Or if you wish to block POST requests to a certain page. Also, 400, 401, 403 and 500 are useful codes when building web apps. I have adapted ProcessWire to use a MVP pattern so this means I can send out a non-2XX status code before the view (template) is rendered and not have to worry about that part. Unlike a 404, these errors are generally unlikely to be encountered under normal usage are are more indicative of server or application error and so it doesn't matter that the full blown ProcessWire error page is not shown. If there's a better way I'm all ears. ?
  20. Great work, thanks!
  21. P.S. One “gotcha” that caught me out was the items did not appear in the mobile nav until I logged in and out again. ?
  22. Just installed this and it is really good! Thanks @Robin S, I am abandoning my Process class from the other thread. ? One suggestion. Can you dynamically set permissions? If so, it might be nice to restrict the appearance of the menus to a permission. It doesn't really matter for my use case but thought it might be worth adding if it's easy enough.
  23. Thanks, I wasn't aware of the $http variable. ? Looking through the functions I think possibly this is more suitable in this instance. https://processwire.com/api/ref/wire-http/send-status-header/ I'm sure HEAD work work — though I may be wrong! What I am wanting to do is send something other than a 200 status for the current request. It looks like $http->sendStatusHeader(405) would send the right header per my above exmaple. Is it possible to then show the error page template?
  • Create New...