Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by teppo

  1. It's very likely that your IP will change every now and then. My understanding is that regular ISPs often charge extra for static IP addresses, yet (at least around here) some don't even offer this sort of service to consumers. When your IP changes and session fingerprinting is enabled, you'll have to renew your login session. This is unrelated to session lifetime limit. That's a valid question! In many services that I use the situation is exactly the same as with ProcessWire. if I disconnect from the company VPN (or first log in to the service and only then connect to the VPN) I'm forced to redo the login process, which in turn may involve new 2FA confirmation request. Most likely these services use a similar fingerprinting mechanism as ProcessWire. On the other hand I wouldn't be terribly surprised if some big services skipped this setp, especially if they happen to have many "consumer users". It can indeed be problematic for some, and on the other hand session hijacking can be mitigated using other measures as well. Storing the cookies securely and so that no one should get easy access to them is the most important step (obviously ProcessWire does that as well.) According to Invision Community documentation our forum software has IP address based fingerprinting enabled by default. They recommend keeping it on, unless it causes issues. Just for the heck of it I just tried to "hijack" my own session β€” and so far it looks like our forum doesn't care about which IP I'm using, what my UA string look like, etc. I was able to "transfer" my session to another browser, and it continued to work after IP address change. It's important to keep in mind that lacking session fingerprinting is not a security issue in itself, more like a precaution that could've (and, in my opinion, almost always should've) been taken, yet wasn't. In this particular sense our forum is indeed less secure than a typical ProcessWire site where fingerprinting is enabled πŸ™‚
  2. I don't want to dismiss your frustration β€” I get that problems like this one can be really annoying! β€” but I do want to stress a couple of points about this: This is very much a needed (even required) security feature. I wouldn't recommend disabling it unless it's causing major issues, and even then there's a 99% chance that you should just fall back to one of the "less strict" options (as mentioned earlier). Without session fingerprinting attacks involving session hijacking are a very real possibility. Providing UI way to disable any security feature is something I'd be wary of. Of course it depends on the situation, but generally decisions like these should be a) made by folks who have enough technical know-how to make educated decisions knowing what the consequences will be, and b) disabling any security feature should never, ever be something you can do "on a whim" β€” it needs to be a decision made after serious consideration. Of course technical know-how and well considered decisions don't equal being a developer with access to site's config files or code, but the point is that providing an easy way to decrease the security of the system is definitely not something I'd consider a best practice. Quite the opposite, in fact. Also, one more thing to consider is that if someone did somehow gain illegitimate access to the admin panel, providing an UI way to disable security features could potentially allow them to escalate the attack. (This particular setting is not the best example of that, but generally speaking.) As for session fingerprinting: I've personally not had real problems with it, but I know others have, so not trying to dismiss this problem. It should, though, only happen if your IP or user agent string changes constantly, which is a pretty rare situation β€” though I'm not an expert in this subject. For me the only case where I've experienced something similar was while testing the site using developer tools, going between mobile UA string and regular UA string... πŸ™‚
  3. @LostKobrakai did some testing related work back in the day as well, he might have some additional insight on this πŸ™‚ (https://github.com/LostKobrakai/pw-test-helpers etc.)
  4. I added tests for two of my modules, VersionControl and ProcessChangelog, back in the day. VersionControlTests is the more recent project, though I haven't touched or used it in years. There's only one test class in that project, and sadly I'm pretty sure it goes against so many best practices that I probably wouldn't consider it a very good starting point πŸ™‚ While I did use PHPUnit, it wasn't really unit testing β€” more like integration testing. The test class starts from a blank ProcessWire installation with required module files included, installs the module, sets up language support and adds some languages, makes changes to page(s) and after each one checks what was stored in the database, etc. In the end it attempts to restore the site to its original "untouched" condition, so that new tests can be started. In my experience ProcessWire involves so many interconnected parts and processes that creating "good enough" mock data would've been a major pain, and still wouldn't really have answered the question of "does this module work as expected in all supported ProcessWire versions, different operating systems, and different database system(s/ versions)". Of course there's still need for unit testing, but in my case it just didn't seem like the best approach πŸ™‚ As for current testing best practices with ProcessWire, I'd definitely check out Process Nette Tester. And β€” this is very opinionated, sorry in advance! β€” I'd probably steer away from PHPUnit. I mean... I'm sure it's an amazing tool once you really get to know it, but the more I've worked (read: fought) with it, the more frustrated I've become. In my humble opinion it's not particularly developer friendly, and there are too many limitations. Again, this might be a result of using it for wrong type of testing, so take it with a grain of salt. I just feel that there are now better options out there.
  5. This is generated on the fly when a result is rendered. Behind the scenes Renderer::renderResultDesc() and Renderer::renderResultsJson() both get field values using Renderer::getResultValue(), which in turn calls Renderer::getResultAutoDesc _auto_desc "pseudo field" (as in: not a real field) is requested. There's currently no public API for accessing this directly, but if you've got a use case that can be solved by adding one, I wouldn't be against it. Though in that case I'd like to know a bit more about the context πŸ™‚ Sorry! Accidentally introduced a dependency for ProcessWire 3.0.160 in the Config class. This is now fixed: latest module version (0.25.1) provides proper fallbacks for core versions prior to that.
  6. Regarding a) and b) you might perhaps find some useful bits and pieces from here: https://github.com/teppokoivula/VersionControlTests/blob/master/tests/VersionControlTest.php. If I remember correctly, installing language support and adding new languages was indeed relatively simple, though if you want ProcessWire to recognize them right away you need to go through some extra hoops (look for "reloadLanguages" and "LS_init"). In fact reloadLanguages() was initially added for this case. That being said, this is some very old code, so I have no idea if it still runs (properly) πŸ™‚ Edit: looks like you solved it already πŸ˜›
  7. Looks like GitHub itself is down right now, so this probably has nothing to do with SettingsFactory πŸ™‚
  8. Heya folks! Just wanted to say that I finally got a chance to properly test this module, and... wow. Amazing work! It looks like you had a bunch of additional stuff planned, but the features that already are there are very useful, and apart from a few minor glitches the module seemed to work like a charm. While the built-in template editing tools we have in the core are not at all bad, at least for me the workflow with Designme is still a huge improvement πŸ™‚ At this point I'm mostly curious about what else you might've had in store when you said that the module was "far from being good enough for release". @elabx, care to provide some insight on this? I mean... it feels to me like you could've removed some of the "less "critical" features (widgets, perhaps even the code editor, etc.) and just released the module as-is. I might be missing something important, of course, but that's my impression anyway. Either way I'm blown away by just how awesome this module is! πŸ™‚
  9. Quick heads-up: SearchEngine 0.25.0 was just released. This version adds support for the new selector operators added in ProcessWire 3.0.160, and also adds a new details section below the selector operator setting. If someone has defined the operator in site config ($config->SearchEngine), that's still a valid option and new operators can be used there as well.
  10. πŸ™‡β€β™‚οΈ Makes sense. I've added this to my todo list, will take care of it soon. Again, makes sense. I'm personally not a huge fan of tutorials β€” it's just not my thing. I prefer to learn by finding a project to work on, or alternatively by digging into existing implementations. Probably explains why there's no tutorial available for Wireframe either. Another item on my todo list πŸ™‚ Yes. On a very minor note the API for redefining component view would look like Wireframe::component('foo')->setView('bar'). Also: I typically choose the view in the component, i.e. the constructor picks the most suitable view based on the params it received. Both approaches are fine though, depends on the context! πŸ™‚ Interesting idea! I can definitely see value in this, but I'd still like to give it a bit more thought. It's easy to add features, but hard to remove (or significantly alter) them, so I prefer not to rush things πŸ™‚ Out of interest, how do you see this comparing to Markup modules using render method(s)? For an example: <!-- RockSearch with partial --> <section><?= $packages->RockSearch->partials->searchform() ?></section> <!-- SearchEngine --> <section><?= $modules->SearchEngine->renderForm() ?></section> One benefit would be that if I wanted to use the default search form as a starting point and start building on top of that, I could just copy the file to local partials directory and change the reference in the layout. This would, obviously, mean no more easy updates, so it's a double edged sword. In SearchEngine I decided to go with a set of interconnected render methods, each tasked with some specific part of the markup. I felt that this provided the best balance between reusability and customization: one can get pretty far by modifying config settings, but if that isn't enough, it's also possible to make more drastic changes using hooks. All in all I really like the idea, but it will require a bit more thought and probably some experimenting to strike the perfect balance πŸ™‚ Hopefully I'm answering the right question: Controllers and views are specific to a single template. Controllers' job is to accept arguments, process data, and pass processed data to the View layer. View β€” which consists of layout(s), view files, and partials β€” is there to output said data, so it should be as "dumb" as possible. View doesn't need to know anything about what's going on behind the scenes. Partials were originally just "include files" without the ability to accept params or a dedicated approach for processing data. They were great when you had a relatively static block you wanted to repeat in multiple templates, but if you wanted to pass them params, you'd have to define them in the parent context, etc. Components were added to fill this void. There's always a class that can accept arguments and process data, and usually there's at least one view file meant to render output. (Components can also render output directly by implementing the render() method, or they might not produce any markup at all, so technically component views are optional.) ... and then things changed a bit when partials also got the ability to accept params. Now the biggest difference between components and partials is the class: I prefer not to mix code with markup, which means that if I need a reusable "thing" that needs to, say, fetch data from an API, it's a component. On the other hand if I just need to reuse a block of HTML and perhaps iterate/output some variables in there, most of the time I go with a partial. In my mind controllers + views (and layout(s)) are the typical way to use Wireframe. Components are handy when you need an element that should be reusable across multiple templates. I guess they're sort of "template-agnostic miniature controller + view" bundles πŸ™‚ Note: how you actually use Wireframe may vary. Your site might not have any controllers, relying on components instead. Or you could produce all the markup in the layout and have no other files (apart from the bootstrap file). What I've described above is just the way I prefer to do things πŸ‘Œ
  11. I'm not really familiar with this module, but it looks like the formatted output will indeed be a single date. Have you tried $result->getUnformatted('programm_date_advanced') to get the unformatted version?
  12. Check the "Advanced" tab in the Template settings. There you'll find an option to make the createdUser modifiable:
  13. Hey @michelangelo! just a quick heads-up: the Modules area of the forum is reserved for third party module support threads, one per module. This topic is about a core feature, so I'm moving it to General Support instead.
  14. I could be too tired to wrap my head around this properly, but it seems to me that your module's init/ready is going to be called after the (admin) page::render method is called, which would explain why it has no effect at all. Your module is not autoloaded, so the init/ready should only trigger when this specific inputfield is being rendered, which is likely too late in the process. Might be easier to go along the lines of what Adrian suggested and a) split the hook into a separate module that extends Wire, and b) make that separate module autoload (preferably with conditional autoloading, i.e. when the template is admin or something) πŸ™‚ (Note: making the Inputfield module itself autoloading should probably work too, but this way you'll end up loading some unnecessary baggage even when it's not necessarily needed.)
  15. Don't worry, it's not a stupid question πŸ™‚ You can definitely build a custom search feature and get great results with that, but things tend to get a little more complicated if your site contains a larger amount of fields, and particularly if you're using Repeater, RepeaterMatrix, PageTable, or other types of fields with repeatable content β€” or perhaps page reference fields gluing content from different pages together. In other words content that isn't technically (directly) part of the page, but needs to be tied with the page in the context of site search. Although in many cases you could no doubt include all those fields in your search queries, this can result in pretty complex queries, and such queries also tend to become inefficient. Generally speaking the more fields you join in the query, the more complex the resulting SQL query will get, and the more time and resources it'll take to process. Not a great thing for scalability. First version of SearchEngine was really just an easy way to reuse bits and pieces of code that were developed over time to mash field values together so that they could be searched more efficiently. Soon after along came the markup generating parts (which now make up a notable portion of the module), a set of features for automatically filtering and sanitizing queries and processing the index, JSON output option (mostly for AJAX requests), indexing support for field types requiring specific handling (core ones as well as third party), etc. From the initial post in this thread: These days in my projects I install SearchEngine, set it up, and trigger the render function. The module takes care of everything else and "just works". In a nutshell SE bundles most of the stuff a typical site search will need into one package, and tries to do it efficiently and following best practices πŸ™‚ Hope this answered your question!
  16. In the end I couldn't reproduce this issue: when a page is indexed, output formatting should be disabled, and thus this sort of problem shouldn't happen. Likely there's some scenario I've missed, so in 0.24.0 I switched that get() to getUnformatted(). I hope that resolves the problem β€” but if not, I may need a bit more information on how to reproduce it πŸ™‚
  17. Quoting myself here, but just wanted to add that they do indeed have a solution for this πŸ™‚ ... so if you're using purge as defined in the Tailwind config file you need to make sure that NODE_ENV is not production when you're doing your dev build.
  18. I had to take a closer look, and it's actually mostly related to our PHP task, which runs PHP_CodeSniffer (which can be very time-consuming). You can use this with any files, though β€” check out https://www.npmjs.com/package/gulp-cached. It's really easy to add, basically just require the package and add a single line to your gulp task. The basic idea is that gulp-cached keeps track of files, and makes sure that files are only passed downstream if they've changed since last run. What this means in practice is that when using watch, the initial build may still be slow (none of the files being watched are cached) while subsequent ones are going to be much, much more performant, as all files that didn't change will be skipped over. Other differences I can see with our setups: You seem to be running sourcemaps on every build. If this is really the dev/watch process, then I don't really see a reason to do that, and it's definitely going to slow things down. We're using gulp-if to check for env and only setting sourcemaps up if it's a production build (basically gulp build vs. gulp watch). I'm not seeing anything related to purge here. If you're using the purge setting in Tailwind config, this is a relatively new thing and I really can't say anything about that β€” for me it seems easier to just run purge as a part of the gulp task: // Tailwind extractor for purgeCSS const tailwindExtractor = (content) => { return content.match(/[A-z0-9-:\/]+/g) || [] } ... .pipe(gulpif(argv.prod, purgecss({ content: [ config.paths.base + '**/*.php', config.paths.base + '**/*.js', config.paths.site + 'modules/InputfieldCKEditor/*.js', ], extractors: [ { extractor: tailwindExtractor, extensions: ['php', 'html', 'js'] } ] }))) ... Actually it shouldn't β€” just having something like px-3 in a file with nothing else should be enough. Again this is based on the code I've posted above, so if the native feature is using some sort of "advanced" matching algorithm, it could be a major problem for a lot of code. Weird. Note also that unless Tailwind has a mechanism for disabling purge on dev builds, you're going to be doing a lot of work that you probably don't need there. That could be another bottleneck. I'd probably just stick to a manual purge declaration in gulpfile. There's good documentation for that here, in case you need more details: https://tailwindcss.com/docs/controlling-file-size/.
  19. Got to agree with Kongondo here. In my case the dev hot reload takes < 2s, and that's with some recent slowdowns (not sure what's going on in my system, but it used to be < 1s). Of course this also depends a lot on what you're doing at dev stage: are you running purge here as well, what else are you running on each rebuild (pre- or postprocessors and whatnot), which files are you watching, etc. Depending on your setup there may be steps you can take to get it down considerably. In our gulp based workflow, for an example, one major bottleneck was solved by adding gulp-cached β€” on a moderately large site this took dev build time down from what was originally probably 6-10s to 1-2s. Never had this issue either. There could be something else wrong, but usually this would mean either that you're actually not going through all those PHP files in the purge step, or you're using some sort of "constructed" class names (px-<?= $x ? 1 : 2 ?>). Not saying that you're doing something wrong, but again: this has been working perfectly for us. Note: I've got some beefs with Tailwind myself, but those are all about the general methodology. Tech wise it's been really, really slick πŸ™‚
  20. teppo

    Request Error

    The modules directory issue is now fixed. @eydun, note that this is not a module support thread, so I've moved it to the General Support area of the forum. "Modules/Plugins" area is reserved for module-specific support threads, one per module.
  21. First of all: I definitely agree with your first point. I need to do some testing and probably add additional configurability to the SearchEngine module after these updates. Some pretty interesting options we've got now! In the past I've steered away from the full-text index because it has resulted in way too many "oddities", i.e. some queries just don't work either due to stopwords or something else, and it seems to be (in my experience) particularly problematic if the site is authored in some other language than English. You've given me a reason to revisit this, though πŸ™‚ As for plurals, it sure is an issue with other languages as well. I have no idea what you've got planned in that regard, but one problem here is that it gets pretty complex if you want to support other languages than just English (which is, actually, one of the easiest languages in this regard). And then there's of course the bigger issue of stemming β€” considering your goose example, if a client was searching for "hanhi" (goose in Finnish), it's true that they would likely expect it to also match "hanhet" (plural), but if that works then why not other forms such as "hanhia", "hanhen", "hanhien", "hanhesta", "hanheen", etc. Anyway, very much looking forward to what you've got planned! Just wanted to point out that this can be a pretty big issue to tackle, at least unless limited to English only, or perhaps made so modular that each language can have its own set of rules. Also it's a slippery slope, and once things like stemming come into play we're in really deep waters πŸ˜„
  22. AJAX request detection is based on the X-Requested-With header. You need to set its value to XMLHttpRequest: // via default settings: axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // or via config object when making the request: axios.post('/post/', { pageID: this.pageID, text_heading: this.text_heading }, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }) Written in browser and untested, but that's the general idea anyway πŸ™‚
  23. Hey @adrian! I'm pretty sure that those issues were already fixed. Could you check that you've got 2.1.0 installed?
  24. No worries, I get what you're saying πŸ™‚ The way SearchEngine is built makes it (in my opinion) really simple to use when you basically just want a search feature and are happy with some visual modifications to the form and list of results etc. But once your needs get more complex, there's a bit of a learning curve there. I've tried to keep the complexity to bare minimum, but it can still be a bit overwhelming at the beginning, especially if you're not particularly familiar with the way ProcessWire itself works. You can definitely do the kind of query you mentioned above with SearchEngine. At least for now the index field is just a regular FieldtypeTextarea (or FieldtypeTextareaLanguage for multi-lingual sites), which means that you can perform queries against it just like with your own custom fields. +1 to this right there. Selectors are one of the biggest arguments for ProcessWire: not only do they make complex queries a breeze, but by sticking with them you can easily avoid some of the gotchas you'd have to worry about working with raw SQL (injection attacks, etc.) Behind the scenes almost every field you see in the admin is what one might call a "custom field", and each of those has a database table of its own. ProcessWire makes extensive use of JOIN queries, which do indeed make things more complex if you're trying to write raw SQL, but again: this is something you should almost never do anyway πŸ™‚
  25. [18-Jun-2020 03:42:32 America/New_York] PHP Fatal error: require(): Failed opening required '/home/niklcicr/public_html/wire/config.php' (include_path='.:/opt/alt/php56/usr/share/pear:/opt/alt/php56/usr/share/php') in /home/niklcicr/public_html/wire/core/ProcessWire.php on line 1199 I don't have an answer to you, sadly, but looking at the post you linked to, this seems like a different issue. In that other case the problem was that the host only had 32MB of memory available, which wasn't enough to actually run (or even install) the system. In this case it seems that PHP is unable to include the config file. I would start by making sure that it actually exists in the path mentioned above. If it does, it could be a permission issue: depending on the setup PHP may be running as some user that doesn't have access to this file. Could also be something entirely different, so what I'd really suggest doing would be contacting support on the host in case they've got an idea what's going on. Note: this is a little off-topic, but your host is running PHP 5.6.40. That's a very old version that hasn't received official security updates since January 2019, so I'd suggest updating to PHP 7, and preferably at least PHP 7.3. And if that's not possible on this host, it might be best to look for a new one... πŸ™‚
  • Create New...