-
Posts
17,140 -
Joined
-
Days Won
1,657
Everything posted by ryan
-
I'm running on a 2013 macbook pro (15-inch) with 8gb ram and 256gb drive. I find it works well for PhpStorm and other web development tools. I don't have photoshop or docker, so can't say about those. It's the most reliable computer I've ever used, and it runs just as well as the day I bought it (not feeling any need to upgrade anytime soon). I do occasionally wish I had 16gb ram, but I don't think I actually need it. This is essentially what I've got, though mine is a couple years older and has half the ram. If you aren't moving your computer to different locations every day, the 15-inch screen is a lot more real estate than the 13-inch, which is useful when it comes to web dev. The 15-inch screen is a big difference to me, and something I can work off of all day. The 13 inch would probably be more challenging, especially in apps like PhpStorm or Photoshop. However, my eyes aren't great. Other things to mention about the 15-inch: It has a 4-core processor, vs 2-core on the 13-inch. But I'm not sure if it makes any difference for the applications you've mentioned. The 2015 model I think is using the older style keyboard (?) which would be a benefit, because it's a lot more reliable from what I understand. Then again, it is used, so who knows. Markets are different depending on location, but the price of the one you mentioned seems high to me, given that it is used. $1275 EUR is about $1500 USD, which is what I paid for my 15-inch MBP brand new. Though when I bought it, it was "last year's model", so the price had come down. But if you are considering the 15-inch, I would look around to see if there are others you could get for less and perhaps be able to negotiate the price down. Notebook computers are much more likely to break than desktop computers, and much more expensive to fix when they do. So a warranty carries a lot of value, and likewise a lack of a warranty should reduce a lot of value. For this reason, I would usually say to buy notebook computers new or refurb (from Apple) if you can, and get as old of a model as possible, that still carries the full warranty. If you buy used, then factor in the risk of something breaking, and on an Apple notebook that could be a $500 repair or more. In fairness, I've had about 5 Apple notebooks over my life, and only 1 of them has had any issues.
-
I don't plan on forcing the option, though had thought that when enabled, we'd give them a login warning notification asking them to enable it, every time they login. I haven't come across any services that forces me to 2FA yet, though I know some companies require it internally. But I think it might depend on the 2FA method being used before you could say if it would be a good idea to force it or not. There are times where you might want to disable 2FA temporarily too. So I think it's best to let the user control it, and maybe annoy them a bit with warnings when they aren't using it. But this is one of those things where I think we'll start fairly simple, but then start fine tuning the options according to what we find are the needs of people using it. I think support in the core is consistent with PW's strategy of making security the top priority. I think we are soon reaching the time (or already have in some cases) where 2FA is considered essential in order for an online application to be taken seriously as having an emphasis on security. I consider it essential for any other online account I maintain (as I imagine many do), so it should be in PW too. If we step outside the security aspect, I think it also builds trust and checks boxes for a lot of bigger companies that may be considering PW or comparing to other options. The support and interface for it will be in the core. The implementation of the interface will be in modules. There will very likely be one implementation module included in the core, though I'm not 100% positive on that yet. Either way, I'll be building and maintaining at least one of the modules that supports it. As I understand it, Google Authenticator is just a standard implementation of RFC 6238 and RFC 4226, like any number of other authenticator apps. As far as I know, they are compatible with each other, but Google Authenticator is just the most widely known/used. I think the compliant you mentioned is the nature of the technology, and not really anything about Google Authenticator in particular. But the complaint is also the reason why it's secure. Once one understands how it works and the steps they should take, I think it all make sense. I'll try to describe. The reality is that 2FA is an extra step, which you can't deny is an inconvenience. But it's like locking your door before you leave the house. Nobody likes having to take extra steps, what they like is the security benefit (if they understand it). And if you lose your keys, then yes you are locked out, unless you've got a backup method. This is why services typically provide backup 2FA methods (like SMS) or one-time use backup codes that you can store securely somewhere in case you ever lose your device. For every place where you use 2FA, you've established "a secret" between your device and the service/website (a long base32 string, which can also be represented by a QR code image). The reason it is secure is because it's not shared anywhere else. If that secret were stored up in the cloud or synced between devices and such, then it is becoming less secure. It is getting passed around networks just like your password, which kind of defeats the purpose of 2FA. If you buy a new phone, and can't restore backup data from your old phone for some reason, the yes you'd want to reset your 2FA for the new phone. If you've got your old device handy, then you'd switch the 2FA to your new device. If your old device is lost or non-functional, then this is where a backup method and/or one-time use code would come into play. If those options weren't available, when it comes to PW, one could also fix any of this by asking a superuser to reset it even temporarily disabling from $config (if nobody had admin access). As I understand it, this is simply a matter of a user 2FA off for some account, then turning it back on, so they can establish a new secret/QR code. There's already a password reset module built into PW. 2FA can be disabled for any individual account as needed. This is what the superuser account is for. ? This is definitely part of the plan. Though with the 2FA methods I've been working with, we can't enable it for anyone that hasn't set it up themselves. Maybe with Netcarver's PPP module when using email, it could work. Or maybe it would work with SMS when you've already got the user's mobile phone number stored. It needs to know the user name in order to be able to look up the user-specific secret for the codes. Technically it doesn't need the password. But 2FA without a password is no longer two-factor, and would have its own security problems, which might be even worse than not having 2FA in the first place. If someone gets a hold of your device, and needs no password for your account, then they essentially have access to your account. Whereas, the intention with 2FA is that both your password AND your device are necessary. It's that combination of factors that makes it secure.
-
This week we’re going to discuss a new security feature that’s currently in development on the dev branch: 2-factor authentication. In this post we look at the benefits of 2FA, how it works, the coming implementation in ProcessWire, and more: https://processwire.com/blog/posts/2-factor-authentication-coming-to-processwire/
- 18 replies
-
- 14
-
-
Maybe we can support other options here, though I'm not going to be able to remember special characters or combinations in this (or be able to easily communicate that to others), just need to keep it as straightforward as possible. I did try "?" but it's too short for autocomplete. I'm not too worried about people not being able to search for "help", as I'm guessing it's pretty rare, and there's already the much more power Pages > Find, if someone can't accomplish something with the live search. Also, this help thing was really about introducing the feature and communicate how to use it in the blog post. I added it last minute as part of writing the blog post, and not certain it's really needed or will stay long term. Though if it did stick around, I suppose it could show a "type 'help' for instructions" link in a tiny dropdown when you are focused in an empty search box. Any module that manages items of any sort. In the core, these modules implement the searchable interface: ProcessField, ProcessTemplate, ProcessCommentsManager, ProcessPageType, ProcessUser. I left pages and modules implemented internally, because it ended up being more efficient to do so. I can't speak to other people's modules, but for me I'm adding support in FormBuilder, DatabaseBackups, HannaCode and ProcessWireAPI. This is primarily a text searching engine. I wasn't thinking folks would search for pages by ID in this search box. But it looks like "id==1001" or "pages.id==1001" does work (like rafaoski mentioned). I'm not sure I understand what you mean about getting your previous search, this sounds more like Lister?
-
@desbest I don't think the above will work, because most of the time when a 404 occurs, that's because the $page could not be found. So there is no $page available. The only place where you could add such a hook would be in /site/init.php, because usually a 404 would have been thrown already by the time your prependTemplateFile gets called—meaning it won't get called, except for doing the rendering of the actual 404 page. Where you might be able to get it to work is for your own manually thrown 404s in your template files. i.e. throw Wire404Exception(); or for pages that exist, but the user didn't have access to view them due to access control settings. Your $page = $event->object; is not a Page object, but rather a ProcessPageView object. If there was a $page available when the 404 was triggered, it would be in $event->arguments(0); That can either be a Page object, a NullPage, or null. Your $dapath variable probably doesn't have what you need, and needs to be sanitized as well. Try using $input->url() instead. Note that it's going to have slashes in it, since it is a URL, which means it's not going to work for your selector where you've got "name=$dapath". You'll want to extract out the first name in the URL and use that, i.e. $parts = explode('/', trim($input->url(), '/')); $name = array_shift($parts); $name = $sanitizer->pageName($name); // now you can use $name in a selector If you needed to, it should be fine to substitute the $input->url() with $_SERVER['REQUEST_URI'] since it is being sanitized with $sanitizer->pageName(). Though I think the values will likely be identical, so I'd prefer the $input->url().
-
Your first example isn't working for two reasons I can see. Though maybe these are ones you already know, but jut in case: 1) it needs to be in your /site/ready.php or /site/init.php file; 2) The addHookAfter() call is commented out, so it never gets hooked; 3) your str_replace() looks to me like it would result in 2 slashes being present at the end, rather than one (due to the rtrim). Another thing to consider is that $page->path() does not return a URL. It returns a page path. The might be the same in many instances, but if PW is running from a subdirectory, they won't. Also, neither are intended to be returning query strings, so it's kind of taking these methods outside the scope of what they are intended. Maybe it's okay to do, I'm not certain but I might suggest instead adding your own custom URL function or method, and using that to get these custom URLs for when you want them. For instance, you could add Page::myurl() method in your /site/init.php file: $wire->addHookMethod('Page::myurl', function($event) { $page = $event->object; $path = $page->path(); // determine if it's a going to be a custom URL if(strpos($path, '/page/') === 0) { // replace /page/ with /article/ list(,$path) = explode('/page/', $path, 2); $path = "/article/$path"; } // convert path to URL $url = $event->wire('config')->urls->root . ltrim($path, '/'); // add in any query string params stored in $input->whitelist $queryString = $event->wire('input')->whitelist->queryString(); if(strlen($queryString)) $url .= '?' . $queryString; // return the URL $event->return = $url; } Now, rather than calling $page->url(), you can call $page->myurl() for any of the cases where you want to use these custom URLs. Another strategy would be to change everything after the entire page has rendered, like with a after Page::render hook. Though I don't think I'd use that if your intention is to add query strings to URLs.
-
Continuing from last week's post, ProcessWire 3.0.108 is now available on the dev branch, and it adds support for a new, more powerful live search in the admin. This week we will take a closer look at how it works, as well as how module developers can make their modules searchable too. https://processwire.com/blog/posts/pw-3.0.108/
- 18 replies
-
- 12
-
-
In this post we preview a new feature coming in ProcessWire 3.0.108, which is a major upgrade to our live search feature in the admin. In this update, PW’s search becomes a lot more versatile and powerful while remaining just as easy to use. Plus, there are some fun and useful power-user features that we’ll cover here too. https://processwire.com/blog/posts/processwire-3.0.108-preview/
- 1 reply
-
- 15
-
-
This week we've got a lot of updates on our core dev branch, including new features, issue resolutions and more. For starters, we've added support for making the Trash and Restore features available to non-superusers, along with related improvements. Plus we've got several new useful and interesting page traversal methods and properties added to our $page API. https://processwire.com/blog/posts/processwire-3.0.107-core-updates/
- 5 replies
-
- 15
-
-
ProcessWire 2.4.0 is a pretty old version at this point, so if this is a site you are still involved with development on, it'd be worthwhile to update it, regardless of FormBuilder. You'd want to upgrade it to 2.7.3, and that would be a fine version to keep it with, if you'd like. For some of the older 2.x sites that I rarely work on, I keep them running on 2.7.3. You could also update it to the 3.x version, but that would be a more major update, and you might not necessarily need it for an older site. But you'd want to update to 2.7.3 first, either way. The upgrade instructions for going from 2.4 to 2.7 are here. As always, it's a good idea to test a major update in a development environment before applying to the production site... especially in this case where you'll be jumping 3 major versions (2.4 to 2.7). However, chances are, it'll be a smooth upgrade. Another possibility—I'm not positive that the current version of FormBuilder won't work with 2.4. Just that 2.7.3 is currently the minimum version that I'm testing with. You could always try it and see. But I kind of think upgrading to 2.7.3 is a good idea regardless of what you need to do with FormBuilder.
-
Like a lot of the stuff coming from PHP's superglobals, using $_SERVER[HTTP_HOST] in that manner actually isn't safe because it comes from request headers, which can be manipulated by the user (a type of user input). $input->httpUrl() on the other hand would be safe, or for just the equivalent of $_SERVER[HTTP_HOST] use $config->httpHost instead (which is validated). If your server uses both http and https (meaning same page accessible via http OR https), then you'll want to point to the https one as your canonical version, like you are doing in your example above. Here's how you might rewrite your example above. If you aren't using URL segments or pagination, then it's also fine to replace $input->url() with $page->url() like you did. The primary difference between $input->url() and $page->url() is that the $input version represents the actual request (including page URL plus URL segments, page numbers, and optionally query string), rather than just the static URL of the $page that it loaded. <link rel="canonical" href="<?php echo "https://$config->httpHost" . $input->url(); ?>" />
-
For those particular cases, your strategy seems fine, since the site/page/?forgot=1 and site/page/?register=1 are entirely different content from site/page/ without the query string (I'm presuming, as it looks like LoginRegister). Another way would be to block them with a meta robots tag in your document <head>, i.e. if($input->get('forgot') || $input->get('register')) { echo '<meta name="robots" content="noindex, nofollow">'; } Or, you could just deliver unique title tags, and omit the meta description tags, for those cases. But that would take a little more code, and these page variations presumably aren't useful to search engines anyway. So I think what you are doing, or the solution above, is a good way to go. For other cases, where the query string doesn't indicate entirely different content (such as a GET var that changes the sort of a list, or something like that), you'd probably want to use a canonical <link> tag. This will tell the search engine that the request can be considered the same as the one given in the href attribute. And the URL in the href attribute is the canonical, or main one. This will prevent the Google Search Console from flagging duplicate titles or meta descriptions on the query string variations of the page. <link rel='canonical' href='<?=$input->httpUrl()?>'> Btw, the $input->httpUrl() includes URL segments and pagination numbers (when applicable) so is more likely to be preferable to $page->httpUrl() when it comes to canonical link tags.
-
I think that's a good idea. Though I'm not sure we've got enough existing material on the forums to warrant creating a new board for the purpose just yet (?), but would suggest maybe the Pub or Beer Garden as a good place for now. We can always create a new board when the amount of content reaches a critical mass, which is the strategy we've been using so far. I don't think we can support video uploads here, though embedding from YouTube/Vimeo is a good way to go for this.
-
I think they are referring to a Drupal setting that maps to CKEditor's config.fullPage, for editing a full HTML document? That's not something we use. Though it's possible I'm missing something. I noticed CKEditor 4 is now up to version 4.9.2 (we are on 4.8.0). Maybe they have fixed the issue in CKE. I'm going to update to 4.9.2 in PW core 3.0.107 this week, hopefully that'll help.
-
I've been traveling in the second half of this week, so will release ProcessWire version 3.0.107 for next week. This week we look at the WordPress vs. ProcessWire series of videos by Jonathan Lahijani. We talk with him about the how the videos are made, what inspired them, what’s been learned, platform strengths, future plans, and more. https://processwire.com/blog/posts/wordpress-vs-processwire/
-
I've run into this problem on a client site before. I was never able to duplicate it myself, but noticed there were style attributes ending up in the CKE field of my client's site somehow, and the client said they pasted from Word. I don't have Word, and I'm not observing the issue occurring with pasting from anything else, so there must be some Microsoft trickery going on, who knows. I don't understand why CKE's ACF allows it. It does seem like a CKE bug. I'm sure it's possible to configure HTML Purifier to remove that stuff, but haven't looked too closely into it. While there is a way to force CKE to paste as plain text (see thread that flydev linked), I don't really like losing links and normal CKE formatting when I paste, because I'm often pasting from one CKE field to another, and having to redo all the formatting is a pain. Usually if I want to paste as plain text, I just use SHIFT-CMD-V on Mac (SHIFT-CTRL-V on PC), as this is a pretty universal way to paste as plain text, anywhere. But the reality is, clients aren't likely to remember it, and many are doing Edit > Paste, rather than using the keyboard. I'd rather not have the client have to think about whether they need to use plain text pasting or not. A simple way to remove style attributes from CKE fields is to hook after the process input, look for them, and then remove them. This hook at the top of your /site/templates/admin.php file should do the trick: $wire->addHookAfter('InputfieldCKEditor::processInput', function($event) { $inputfield = $event->object; $value = $inputfield->attr('value'); if(strpos($value, 'style=') === false) return; $qty = 0; $value = preg_replace('/\bstyle=(["\'])([^\1]+?)\1/i', '', $value, -1, $qty); if(!$qty) return; $inputfield->attr('value', $value); $inputfield->trackChange('value'); $inputfield->warning("Stripped $qty style attribute(s) from field $inputfield->name"); }); Word may be adding some other weirdness too, but I don't have a good example to look at to know what else there might be (MSO-specific class names?). In any case, we could probably remove it in a similar manner.
-
Nicely timed question— this is actually already in 3.0.107, and I've just been testing it locally this morning. If there are any pages in the trash that a user had edit permission to, then they can see the trash, and see those pages in the trash. The trash and restore actions also are now supported for non-superusers. They can't see pages in the trash that they don't have page-edit/page-delete permission, only superuser can see those.
-
Lenz: If you just output that $config var in your <head>...</head> it will take care of it for you. i.e. <?=$config->pagerHeadTags?> It is just a shorter version of doing this (which you can do in any PW 3.x version): <?php if($config->urls->next) echo "<link rel='next' href='{$config->urls->next}' />"; if($config->urls->prev) echo "<link rel='prev' href='{$config->urls->prev}' />"; ?>
-
That's right, field names have precedence, and it also warns you if you try to create a tag that collides with a field.
-
Several core updates this week including a new way to perform $pages->find() searches by using Field tags, a new Field tag manager, new methods added to our $input API variable, new Inputfield traversal methods, and more… https://processwire.com/blog/posts/pw-3.0.106/
- 9 replies
-
- 10
-
-
I'm still working on the latest version of ProcessWire (version 3.0.106) and don't have it quite ready to push to GitHub today, so we'll save that for next week. But I do have a fairly major FormBuilder release ready, and am placing it for download in the FormBuilder support board today. In this post, I'll cover what's new in this version of FormBuilder. After that, there is a how-to guide for using hooks in FormBuilder, though some might also find it also generally useful for any hooks in ProcessWire. Lastly, there's a FormBuilder hooks reference, which has been asked for a few times lately, so figured that was a good way to round out this FormBuilder blog post. Thanks for reading! https://processwire.com/blog/posts/formbuilder-v34/
-
- 12
-
-
-
This latest version on the dev branch adds a new site profile to the core, adds useful new functions to our $mail API variable, and makes significant enhancements to our $sanitizer API variable: https://processwire.com/blog/posts/processwire-3.0.105-core-updates/
- 7 replies
-
- 17
-
-
Today is the last day of school before summer break for my kids—school is getting out early, so I'll keep this post short. But like most weeks, we've got a new core version on the dev branch this week. Core version 3.0.104 contains 13 new commits relative to last week's version, mostly related to resolving minor issues in our GitHub queue. There's not enough interesting material for me to take up your time reading a blog post, so I will save that for next week. But if you are running on the dev branch then it's definitely worth grabbing. If you are using AdminThemeUikit, this version has several minor tweaks and improvements to that admin theme as well. Plenty more to come next week. Thanks for reading, and have a great weekend!
-
- 16
-
-
This week we've got some really nice upgrades to three core modules: SessionHandlerDB, ProcessForgotPassword and FieldtypeComments. This post covers all the details: https://processwire.com/blog/posts/pw-3.0.103/
- 3 replies
-
- 17
-
-
ProcessWire version 3.0.102 on the dev branch contains more than a dozen commits and PRs. I'll save the blog post till next week, as I continue reviewing pull requests and covering issue reports as they come in. But core updates are really going smoothly while the progress and fun continues, with ProcessWire getting better every week, thanks to your reports and PRs. This week I briefly had to do a small WordPress-to-ProcessWire conversion, but the site wasn't quite big enough to warrant automating the content conversion like I usually would. So I did a copy/paste job for the content, which I always kind of enjoy, so long as there isn't too much of it. But it was the first time that I had really used the new copy/paste images feature that we recently added to our CKEditor (outside of testing it during development). And I have to admit this feature is really handy for a case like this. Being able to “Copy Image…” (from another site), and paste at the location I want it to go in CKEditor …while the image uploads and inserts itself into my images field automatically… is pretty awesome. No more downloading images from the old site, on to my computer, then uploading to the new site, then placing them in CKEditor. What used to be several steps now feels like a single natural step. The new copy/paste process is so much simpler, and was a huge time saver this week. I mention it here because it's easy to forget that it's there at all (just like the drag-n-drop into CKEditor option). So if you haven't had a chance to try out the copy/paste image option in CKEditor, give it a try. It's a good thing to know about for those times when the need presents itself, because it'll save you (or your clients) a ton of time. More details about this feature can be found in the post for core version 3.0.87 (if you haven't read it already) where we covered the additions of drag-n-drop and copy/paste images uploads into CKEditor.
-
- 23
-