Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/31/2023 in all areas

  1. I also have a 100% working spam protection technique I always use (and nothing more). See it working here: https://www.szepelet.com/about-us/contact-us/ Human Detection is a pure PHP random number, rendered by :after {content: attr(data-attr);} and the css class is deliberately not named with a related term, just to make it more obscure. No bots have been smart enough to crack it so far.
    3 points
  2. This is how I do it: http_response_code(200); But 200 is the default anyway. It should always be sent unless you change it or an exception happens. I think @Denis Schultz may be on to something with the Content-Type header?
    3 points
  3. $repeaterOwner should be the public page (i.e. 2905), so you now just created a superfluous entry in field_vouchers. You can delete that with 'delete from field_vouchers where pages_id=2906'. What stumps me is that a select on field_vouchers with pages_id 2905 returns an empty result, yet you still get the primary key error. Off the top of my head, I can only think of two scenarios where this could happen (a) your table's index got corrupted somehow, or (b) you're using InnoDB and there's an open transaction that should have inserted the row in question but hasn't sent a commit yet. To be on the safe side, you should probably export your repeater items and for-page-2905 using PagesExportImport and store that. This lets you recreate your repeater pages with identical ids even if PW decides to throw them away at some point. Afterwards, you can try running the SQL query 'check table field_vouchers' and see if the result shows any errors.
    2 points
  4. That's okay. I just wanted to be sure that it's actually empty and not filled with incorrect data. Since the pages still exists, this little snipped should do the trick: if($user->isSuperuser()) { $repeaterParent = $pages->get('/admin/repeaters/for-field-513/for-page-2905/'); $repeaterOwner = 2905; $sth = $database->prepare( 'insert into field_voucher ' . '(pages_id, data, count, parent_id) ' . 'values ' . '(:page, :repeaters, :count, :repparent)' ); $params = [ ':page' => $repeaterOwner, ':repeaters' => $repeaterParent->children()->implode(',', 'id'), ':count' => $repeaterParent->children()->count(), ':repparent' => $repeaterParent ]; $sth->execute($params); echo "<pre>Inserted repeater</pre>"; }
    2 points
  5. This is how i do it: // Return a valid status code such as 200 OK. header('HTTP/1.1 200 OK'); // By most Webhooks,i also want to give a json return header('Content-Type: application/json');
    2 points
  6. @flydevThanks for this suggestion. Already thought about this too. Guess this would indeed be the best approach. However I came up with another option, as the entire PW booking site should also not show up in Google at all. I simply hid the entire PW side behind a .htaccess AuthBasic login. I may update my PW PHP script creating the booking pages to add .htusers credentials as well or just use a global AuthBasic login for all of the 100-150 users and a unique BookingID per user. So far I am good to go for a limited internal test, just two days ahead of the deadline for the concept study 🙂. However I will play around with PW frontend login and the FrontendForm module until the project goes live, as I think that‘s indeed the way I should go, as PW already adds security measures for free. Thanks for all your suggestions so far. Highly appreciated.
    2 points
  7. After a previous request for Webp support (6 years ago, times flies…) that Horst and Ryan kindly introduced in PW 3.0.132, I'm back with another request for a new image file format, AVIF, which has landed in almost all browsers. I'm actually surprised no one here in the PW community has been asking for AVIF support in ProcessWire as it seems to be provide much more consistent gains in compression and greater relative quality over Webp, and of course over good old JPEG. My experience using it definitely confirms this. I've been using Cloudinary to serve AVIF images to the browsers that support it, but of course I'd rather not use a third-party service, and use it natively in ProcessWire. Imagemagick supports AVIF if I'm not mistaken. Anyone else is interested?
    1 point
  8. @BoostGuess you talk about converting WordPress site to PW site - right? Would just develop as usual using localhost for the new PW site and then just upload stuff to the server once ready. Usually I have three site/config.php files (config.php, config_server.php, config_local.php) which just differ in the DB credentials and the root host. Once my localhost PW site is up and running, I zip it (.htaccess, index.php, site/ and wire/) and upload the zip file to my server via Ftp together with a simple PHP unzip script. Then I run the unzip script on the server. Than I cooy/rename site/config_server.php to config.php). Last step is to enter my server PhpMyAdmin and just delete old DB tables and import the sql dump from localhost.
    1 point
  9. Cool. Will test this option too, once I showed the demo to my client and it was decided if and how to proceed with the project. You guys are all awesome and gave me a lot of tips, hints, links and code snippets to check out. @AndyThanks for your sanitizer snippets, already using those on all input data by default. Even do whitelisting whenever appropriate in addition.
    1 point
  10. @flydevThanks for your suggestions and links to posts and code examples. Highly appreciated. Got the idea and philosophy already partially by Bernhards YT video, which brought me to PW first place. Was about to start with pure PHP/MySQL, HTML/CSS/JS. Pretty sure I wouldn‘t be that far, as I did my last serious PHP/MySQL project about 5 years ago. So far I am pretty happy with PW and I know I just revealed the absolut basics yet. Looking forward what more to come in the future.
    1 point
  11. Oh, sorry. I've gotten turned around a bit here without noticing it. I must have looked too long at this line when I assembled the sql query: $vv = wire('pages')->find('parent=2906, template=230, sort=sort, include=all'); The sql query with "2906" I had you do was wrong then and should have been 'select * from field_vouchers where pages_id=2905'. Can you run that again? Since there's still data there, let's take a look at what that is before I jump to conclusions (supposedly empty, but who knows, since it shouldn't have gotten into this state at all).
    1 point
  12. Just to understand right, the repeater field is no longer on the template of your main page, right? (If it isn't, don't add it yet!)
    1 point
  13. OK I figured it out. $images = $pages("template=media-manager-image, include=all"); foreach ($images as $image) { $preview = $image->preview; $description = $image->media_manager_image->first()->description; if ($preview != '') { $image->of(false); $image->media_manager_image->first()->description = $preview; $image->save(); $image->of(true); } }
    1 point
  14. Wild idea, but the little maths question system I wrote for this contact form is, as far as I know, GDPR complient and is used on a site that has no cookies or sessions on the front end interface. It therefore has no CSRF protection, yet has been 100% effective (several years so far) at preventing spam submissions. There are a few things I'd change if doing a v2, but overall, it's worked very well. Reload the page a few times to get a feel for how the question system works. If you are not worried by being GDPR complient and are willing to use sessions, then writing something like this would be even easier as there are no extra anonymisation hoops to jump through. Just stash a target answer in the session and re-generate a maths question that leads to that answer on each page render.
    1 point
  15. yep. You set the header of the return package. The next line is from my snippet...
    1 point
  16. Yes, that's what is good with this tool, you are not required to be stick with a fixed solution. You can implement what's you have in mind and how you want to implement it. Really glad to see where you already are on using ProcessWire, it seem you got the freedom philosophy it bring to you 👏👏 The module FrontendForms from @Juergen look a good candidate to me as he maintain it and did a fantastic job on it. Also, I saw @AndZyk linked LoginRegister Module in other thread which could fit good here, for free. I remember we discussed years ago on some customization tricks that could give you ideas. Below you can find a thread about it, but keep it for later as I see you are short on your deadline 🫡 The original blogpost for the Pro version, just in case: https://processwire.com/blog/posts/login-register-pro/ You will find also a lot of tips (generally using code from quite deep in the core) from @Robin S in the forum, there are so much of them that you will need google to find them 😂 PS: I am going to add a comment on your other threads about the spam protection.
    1 point
  17. That is also a option. 😀 If you just want to exclude search engines, you could make your page hidden and exclude it in your robots.txt But if you wan to protect your page, a .htaccess protection works as well. You could try the free LoginRegister module, if you want a better looking login form integrated with PW: https://github.com/ryancramerdesign/LoginRegister There is also a commercial successor of this module: https://processwire.com/store/login-register-pro/ Regards, Andreas
    1 point
  18. Hi, just added a fifth option to keep Google and unwanted users out. I Just hid my entire PW booking side behind a .htaccess AuthBasic access. But will try the FrontendForm module too as it seems to already provide all the features I want to implement myself already out of the box 🙂.
    1 point
  19. Welcome to the PW forums @Tenzing 🙂 You can achieve this by setting the URL segments you want to $input before you render the page. E.g. $input->urlSegment1 = 'foo'; $input->urlSegment2 = 'bar'; echo $thepage->render();
    1 point
  20. Ryan has already responded to the Github issue and will merge the fix as soon as it can be confirmed. Passing along a PW API method call he shared that can fix this in case anyone that runs into this and wants to skip working in the DB directly.. $query->exec('RENAME TABLE tmp_field_body TO field_wvprofile_body'); Thanks @ryan!
    1 point
  21. I will read my answer again tomorow on the morning, but just throwing an idea about the form. Instead of trying hard to fight bots and potential hackers, you could benefit from existing protections of the login process by using a custom login form, by storing the bookingID in a field of the template user, you could differentiate each user by generating a username, for example "user_`$bookingID`", the username is not important here, and the password (which could be generated from the bookingID and a salt), not important either. However, bots or hackers will have trouble getting through. You can also add a captcha like Mosparo to respect data collection.
    1 point
  22. @AndZyk: Thanks for your input. Will try first with the free FrontendForms module as I am quite new to PW and do not have a lot to deal with web dev recently (more C#, Python stuff for Windows Desktop). Hence I don‘t want yet to spend the 179€ for the pro module unless I will know for sure using PW more often in the future. cheers zx80
    1 point
  23. I did a little more digging too. It seems as part of the field rename process, the corresponding (old) table is temporarily renamed to tmp_field_yournewname, and then tries to rename this temp table to the correct new name: field_yournewname. This second part fails because the table already exists, so I believe this throws an Exception and you would expect the admin to re-render with an error notice. (Like it does with the normal duplicate field name error). However, since the underlying field's DB table has been renamed to its _tmp version, there's another exception, showing the error. At least I think that's what's happening. DB table names are lowercase by default ($config->dbLowercaseTables is true unless overridden), so 'Body' will try to create 'field_body'. @FireWire, you might find there's a tmp_field_body table in your DB, with all your content intact. Good to know there's a Github issue opened.
    1 point
  24. There was nothing special in the setup, it's a very similar setup to what I usually use on sites. Really appreciate you looking into it and running some tests! This is it. It was the uppercase B in Body that I accidentally put into Name instead of Label that conflicted with another field named body. Really appreciate @Robin S @wbmnfktr and @iank working to figure out what happened, I don't have the time to troubleshoot right now (deadlines!) and you really helped out. If I didn't find out what happened I would be kind of uneasy about the website. Ideally I think it would be best if field names were restricted to lowercase, but that would be a big breaking change at this point. Many situations could cause this: Text intended for the Label could mistakenly be put into Name and all data is lost for that field (my case) A developer may be familiar with this bug, but not know or have forgotten that a field already exists with a name that will conflict Accidentally mistyping with a capital letter where a lowercase letter would have shown the appropriate duplicate field name error I have opened a Github issue for this bug.
    1 point
  25. Hello @zx80, I would go with a module for forms like the commercial FormBuilder or aformentioned FrontendForms. I have build forms in the past, but nowadays I use FormBuilder for every form, because forms can be complex to develop and maintain. Both FormBuilder and FrontendForms have protection well covered: https://processwire.com/store/form-builder/#spam-filtering-features https://github.com/juergenweb/FrontendForms#spam-protection-and-security-features For protection I am always using a honeypot and Google reCAPTCHA field with filtering by specific mail addresses or keywords, when I still get Spam. FormBuilder has an extra module for a Google reCAPTCHA field. Regards, Andreas
    1 point
  26. @MarkE What I'm intending to communicate is that it's up to the module developer how many of the WireCache features they want to support. That's because, as I understand it, it's not possible to support the the full WireCache feature set with something like Redis. The core WireCache (WireCacheDatabase) will continue to support the full feature set, as it always has. For 3rd party WireCache modules, the required feature set would just be the ability to get, save and delete cache by name ... what the majority of cache use cases are. If they can support more than that, great. But I think it's better to keep the door option to more cache options by not requiring specific and lesser-used cache features unique to PW. If a 3rd party module has to support the full WireCache feature set then likely there won't be 3rd party WireCache modules. For cases like yours, where you are depending on specific features, you'd probably want to stick with using the core default (WireCacheDatabase), unless future 3rd WireCache module is able to support them. @BitPoet Great! Yes, that's correct, the core does not use anything but get/save/delete by name. But it does use wildcard matching (for FileCompiler). Does Redis allow for matching by partial cache name? For instance, a cache name that has a wildcard at the end like "MyCache*"? If not, there are ways around it, but I was just curious. Maybe that is a good way around it. Though having to hit the database in addition to Redis might reduce the benefit, or make it slower than just using the database cache. Maybe another way around it is for WireCache to fallback to the WireCacheDatabase when a particular feature is needed that's not supported by the WireCache module. Good idea, I will add that. @kongondo I don't think so because the cache would have to write and read from the same place, otherwise I don't know how it would find caches that it wrote. But PW does support separate read and write connections for the database (WireCacheDatabase), and it will use them when they are provided.
    1 point
  27. Looks like a perfect application for LazyCron. A quick and dirty snippet of code you can place in site/ready.php (or inside a template's PHP file, just make sure that a page with that template is viewed regularly): <?php namespace ProcessWire; // Add daily hook to clean up incomplete, stale pages wire()->addHook('LazyCron::everyDay', null, function(HookEvent $event) { $ts = time() - 86400; // 24 hours ago // Find matching pages, adapt selector however you want (e.g. limit to certain templates or parents) $stalePages = $pages->find("created<$ts, title=''"); foreach($stalePages as $stalePage) { $pages->trash($stalePage); } });
    1 point
×
×
  • Create New...