Jump to content

ryan

Administrators
  • Posts

    16,800
  • Joined

  • Last visited

  • Days Won

    1,545

Everything posted by ryan

  1. The logic you've got there seems to make sense to me. One thing to note about this sort of counter is that it would not work if you had page caching enabled. But so long as you don't, it should be fine.
  2. Jennifer– This is a fantastic site. This makes me proud! Really great work.
  3. From this page on php.net: So for objects === has got to be faster because it only has to compare one thing (memory location). Whereas, == compares lots of things. So I think that === is what you want when comparing two pages to see if they are the same. Most of the time this works perfectly. But there are some situations where that could fail. An example would be if you loaded a page $a, saved page $b, then loaded another copy of page $a, which we will call $c. If you compared $a === $c, it would fail because you'd saved $b. Why? Any time you save a page it clears the memory cache. So while this seems like an unlikely situation, it can happen. As a result, it's technically more reliable to compare pages by their ID property, like: $a->id == $c->id would still work in situations when "$a === $c" wouldn't. You can also do "$a" == "$c", which is the same as comparing the id property. This works in ProcessWire since the string value of any page is its ID.
  4. Theoretically, the more specific you can be with a query, the more potential there is for it to use the best index and locate things faster. But if there aren't other templates using the field you are finding anyway, then it's also possible it could add overhead (though probably not measurable). But like I said, I think more specificity is better overall. Anything you can specify from a selector in terms of finding pages should ultimately be using an index in the DB, except for keywords in %= queries.
  5. This is something that we will most likely be adding soon. This would be a little trickier, as these inputs come from ProcessWire Inputfields rather than FormBuilder. Though I'll keep thinking about alternatives. One alternative is that it's always possible to clone an existing Inputfield, rename it, and place it in your /site/modules/. Install and modify it to produce your preferred output. Assuming I understand correctly, we already have this. But you might have to be on the dev branch. I may lead the project, but we have several core team members already. All the commits still go through my account (for QA), but I'm not always the one coming up with what's in the core. I agree, and I think the Concrete5 marketplace is a good model for us.
  6. It sounds like $user isn't in scope. When you are developing stuff like this, it's good to enable $config->debug=true; in your /site/config.php file. That way, PHP should report notices like this. This is probably what you want: $user = wire('user'); if(!$user->language->isDefault()) $segment = $user->language->name; else $segment = '';
  7. The answer is both Inputfields and Fieldtypes, but they are validating in totally different contexts. Inputfields validate user input. Fieldtypes validate data set to a $page, regardless of where it comes from. Think of Fieldtypes as API-side type validation, and Inputfields as interactive/user-input validation. Here's more detail: Inputfields only come into play when there's interactivity, i.e. a form and a user inputting something. Input should be validated by Inputfields so that the data is valid enough to echo back to the user, or for something else to pull the value from it. Inputfields should always be validated server-side where appropriate, but can also optionally include client-side validation. Inputfields can be used separately from Fieldtypes (they are used throughout ProcessWire in all forms). If there is some kind of input validation that isn't specific to a page or fieldtype, then it should be done by the Inputfield. Meaning, most validation responsibility goes with the Inputfield and an Inputfield shouldn't assume there's going to be any more validation beyond it. Inputfield sanitization/validation is done in $inputfield->processInput() or $inputfield->setAttribute('value', ...). The processInput() method is the first line of defense for values coming directly from a form. Whereas the setAttribute('value', ...) will see values sent from the form as well as values sent from the API to the $inputfield, like an $inputfield->attr('value', 'some value'), call. Where you put your sanitization/validation depends on what you are trying to account for. You may see some Inputfields have a setAttributeValue() function. This is not part of the Inputfield interface. It's just a methodology I sometimes use to isolate setAttribute('value', ...) for more readable code. Inputfields report errors by calling $this->error('error message'); The user will see that error message within the context of the field. Fieldtypes come into play every time a value is populated to a page. This could be from the API, the core, modules, importers, Inputfields… really anything. They need to validate that the value sent to the page is consistent with the type of data the Fieldtype is responsible for (type validation). So if the Fieldtype only stores a string, then it needs to make sure it's a string. If you set something invalid to a $page, the Fieldtype needs to either convert it to be something valid or if it can't, throw it out. For the most part, they should do it as quickly and silently as possible, because they get such a high volume of traffic. Not to mention, Fieldtypes can't assume there's a user present to see anything. Fieldtype sanitization/validation is performed by $fieldtype->sanitizeValue(). Every value set to a $page gets routed through that function, for the appropriate fieldtype. Whatever you do in there needs to be fast. That would be the correct behavior for the Fieldtype, but not for the Inputfield. The scope for Inputfields goes beyond just pages. They don't know what they are being used for. If they did, then their usefulness would be much less. But that's just "in general". There are some cases where you are building a Page-dependent Inputfield and your Inputfield needs to know about the $page being edited. Core examples would Inputfields related to files and repeaters. In that case, make your Fieldtype pass it along to the Inputfield. Each Fieldtype has a getInputfield() method that gets a copy of the $page and $field being edited. It has to return the appropriate Inputfield to edit the provided data. So you can easily send it along to the Inputfield right from there: public function getInputfield($page, $field) { $inputfield = wire('modules')->get('InputfieldSomething'); $inputfield->set('editPage', $page); // inputfield now has a $this->editPage property return $inputfield; } They can report error conditions, but technically they aren't the place for it. Yes. In general, Fieldtypes can't assume there's anyone there to see an error. But if you have some need where you think it is necessary to do from the Fieldtype, try $this->error('message') … it will only be seen in an interactive context. If you want to report an API error, throw an Exception. But if you can keep all of your error reporting in the Inputfield, that is the right place for it.
  8. I agree, we need a directory. I will get around to building it eventually. But if anyone else is interested in taking on this project, just let me know.
  9. Disabling CSRF protection like in the link Pete provided is one way to do it. But if you want to maintain CSRF protection, a better way to go might be to just setup an email filter so that those messages go to your trash automatically. But I will go ahead and add a CSRF specific Exception class to 2.3 so that you can use catch to modify the behavior.
  10. Seems like a good idea! ProcessWire caches a lot of this stuff behind the scenes. Once a page is loaded, it doesn't reload it unless the memory cache gets cleared. Likewise, results of selector queries are cached as well. So the navigation tree would have to be pretty large before preloading would help much. But it is feasible to do. It would mean SQL querying the pages_parents table and pulling out all IDs, then preloading those pages with $pages->getById(array(ids...)). But I'm not sure it would amount to a measurable difference or not.
  11. I think that's a question for Joss, but before he'd asked me to put it in the "discussion" tab of the page. But because nobody really gets notified of changes in there, maybe posting in the forum would be better. What do you think Joss? You might have noticed I still need to update the design for modules.processwire.com. There just isn't enough time in the day. Hopefully soon!
  12. Is it a shared hosting account, or a dedicated/vps? If it's some kind of dedicated platform where you don't have other accounts under someone else's control, then it's not as much of a concern. But I think this is a question for your hosting provider. What's probably happening is that PHP can't write to /site/assets/. Who is listed as the directory owner? It's most likely you, which would mean that Apache is running under an account other than yours that does not have write access. I would check with your hosting provider to see what permissions they recommend for CMSs that need to have a writable directory. This can very from host to host, so it's tough for us to narrow in on it here short of trying different options (that are more secure than 777) till it works.
  13. It depends on the field as to how the data is saved. But for textarea/tinymce it is saved exactly as it is presented, meaning just the HTML that TinyMCE provides. It's okay to edit it by other means. The way I usually solve the TinyMCE static links issue is to perform a search/replace on the DB dump file after exporting it from dev and before importing to live. I guess it's just become part of my workflow. But I really would like to find a native/built-in solution for this particular issue so that nobody ever needs to think about it.
  14. I don't think that we are currently using the jQuery customized version of TinyMCE. It is possible to customize TinyMCE's init with ProcessWire hooks, though it's late in the day here and the exact methods escape me right now. I think that Soma or Diogo might have a better idea. But there should be some good info in the archives of these forums, as I know the topic has come up before. I just don't know what keywords to use to find it yet (tried a few). But if you can tell me more specifically what you are trying to hook into and what property you want to change, I think we can come up with a solution even if we can't track down the previous ones.
  15. There are instances where it could feasibly reduce the potential data set that MySQL has to scan, but I think in most cases it probably doesn't make a difference to performance. But there are other good reasons to specify a template (or parent, or both). For one it clarifies what you are attempting to match, making it more "readable" to you and others that ever look at the code. It also ensures that the code is still matching the right things, should the field being searched for get added to more templates in the future.
  16. I think that a module like this mainly provides value in sending a mobile photo to a web site. The reason for that is that many of these mobile phones have no file-upload capability (at least iOS doesn't). But they can send email. So this module actually solves a need and lets you do something you can't otherwise do. Phillip identified the need and solved it by using Tumblr as an intermediary (since their app will pass through photos), which was a great idea. This module solves the need by using email as the intermediary--the one common thing available to all smart phones (and all credit to Horst and Phillip for the ideas). When we get into specifying other types of data and fields, like what's been mentioned above, it definitely sounds cool and interesting. But the reality is, we don't need email for that… we could just login to ProcessWire. We need email only because mobile phones can't upload files. I don't personally have a need to populate text fields from emails, but it's feasible someone could (like some of the things MarcC mentioned, for example). For that need, I think the approach taken in this module would be a good way to go, and perhaps this module could serve as a good starting point to build that capability, for anyone interested.
  17. Yes, you can definitely whitelist email addresses, and we highly recommend you do. The module configuration screen has a section where you can enter what email address are allowed to post. Keep in mind though that email addresses can be faked, so it's not a guarantee. Though I didn't specifically work with this part and Horst can provide better guidance on that.
  18. We say "mobile" because that's the area where this module is most likely to be useful. However, the module doesn't care what device or computer you email photos from. Aren't you inheriting an iPhone 3g pretty soon?
  19. Send photos from your mobile phone to ProcessWire, from anywhere, on-the-fly. ProcessWire maintains a chronological gallery that you can simply email photos to. Works with any e-mail capable device, whether mobile phone, tablet or desktop. Written by Horst Nogajski and Ryan Cramer Output inspired by the work of Philipp Reiner. Discussion leading to this module can be found here. Uses email libraries by Manuel Lemos Requires ProcessWire 2.2.13 or newer Here is example output from this module. Download from GitHub or Download ZIP file How to Install Setup a new email address at your provider. This address should be dedicated to the purpose of this module. Make the address private and cryptic enough so as not to be obvious or discoverable by others. Place the files included with this module in /site/modules/EmailImage/ In your admin, go to Modules > Check for new modules. Click Install for the EmailImage module. Complete all the settings it asks for, per the email you setup in step 1. Check the box to test your connection, and save. How to Use Email an image to the address you configured. You can include multiple images if you like. After waiting a minute or two, view the URL /email-images/ in your site. This is a page that was installed for you to display images. Repeat and enjoy. How to Customize While this module has everything working out-of-the-box, it is meant to be customized to your needs. For example: You may want to move or rename the /email-images/ page somewhere else. The EmailImage module keeps track of this page ID, so it is perfectly fine to remove or rename it if you want to. Take a look at the /site/templates/email-images.php template file. You may wish to replace it entirely with your own code, or you might build upon what's there, or use it as-is. But chances are you'll at least want to swap in your own header/footer to fit within your site's design. Take a look at /site/modules/EmailImage/EmailImageRender.php. That file contains an example function used to render an image gallery. This is the one called upon by the template file you just looked at. You might copy and paste this function somewhere else into your own site, and modify it to suite your own markup needs. Just remember to name it something different! Please post links to what you create in this thread. How to Uninstall You can uninstall this module in the same way as any other module, by checking the box to "uninstall" from the module settings screen. But please note the following warning: When you uninstall, your system is returned to the state that it was in before this module was installed. Meaning, the EmailImage pages and images will be deleted. So please backup your images somewhere else if you want to lose them during uninstall. After uninstalling, you can safely remove this dir: /site/modules/EmailImage/, and you can remove the template file: /site/templates/email-images.php.
  20. An image has to be present before it'll import it. But it can include subject line text (which becomes the 'title' field) and body text. Because emails often contain a lot of extra junk (client specific stuff, signatures, etc.) you do have to clarify what is your intended body text by surrounding it with an opening and closing tag of your choice.
  21. Great idea and module Pete! Regarding the backup directory, ProcessWire only prevents direct access to .php, .inc and .module files. As a result, it's still possible for some files to be accessible. But this is easy to get around. Just make your backups directory start with a period, like "/site/assets/.backups/" and then the directory will be completely blocked from web access.
  22. I've always had good luck with ImageMagick, but didn't implement it in ProcessWire because it's not near as universal as GD2 and requires an exec(), which is something I didn't want the core to rely on. But would totally support inclusion of other libraries for resizing. Admittedly, I've been pretty happy with the quality of GD2's output (at least, after tweaking the quality settings), but if there are visible quality or size benefits to NETPBM or ImageMagick then it would seem to make sense. Attached is the ImageSizerInterface. If you make your NETPBM class implement this interface, then I can convert ImageSizer to be an injected dependency, enabling the image sizer library to be configurable per installation. The crop options are a relatively recent addition, and I don't think that many people are using them or know about them, so if difficult to implement, they aren't crucial to have at this point. ImageSizerInterface.php
  23. That's funny you mention that because while posting my photos I emailed Horst to see if it was possible. He said that it is. I told him I thought it would be the first request we got, and sure enough -- the request came even sooner than I expected. I've updated the module to support it, and just need to wait for his update before we can test it out. Once we've got that, we will go ahead and release the module.
  24. Horst, your file had comments speculating about what to do with the reasontext. Here's how I added it. Let me know if this makes sense: /** * Send to a URL using HEAD and return the status code (@horst) * * @param string $url URL to request (including http:// or https://) * @param array $data Array of data to send (if not already set before) * @param bool $textMode When true function will return a string rather than integer, see the statusText() method. * @return bool|integer|string False on failure or integer of status code (200|404|etc) on success. * */ public function status($url, array $data = array(), $textMode = false) { $responseHeader = $this->send($url, $data, 'HEAD'); if(!is_array($responseHeader)) return false; $statusCode = (preg_match("=^(HTTP/\d+\.\d+) (\d{3}) (.*)=", $responseHeader[0], $matches) === 1) ? intval($matches[2]) : false; if($textMode) $statusCode = isset($matches[3]) ? "$statusCode $matches[3]" : "$statusCode"; return $statusCode; } /** * Send to a URL using HEAD and return the status code and text like "200 OK" * * @param string $url URL to request (including http:// or https://) * @param array $data Array of data to send (if not already set before) * @return bool|string False on failure or string of status code + text on success. * Example: "200 OK', "302 Found", "404 Not Found" * */ public function statusText($url, array $data = array()) { return $this->status($url, $data, true); }
  25. Sounds good, I think this makes sense for the installer. Thanks also for your additions to this class, I am putting them in today and should have them committed to the 2.3 source before release. One thing I would be worried about is just those cases where there is some firewall that blocks the server from accessing itself. I've run into this issue with a couple of people that were trying to verify their FormBuilder or ProCache license keys, and none of the WireHttp methods worked, despite falling back to sockets. So it seems like for one reason or another, there are servers out there that just don't accept outbound http requests (or have some firewall for local requests). I can't say for certain how common or rare this is, but am hoping it's rare. Can you think of any other fallbacks we should add to WireHttp, or do you think we've already got everything we need? I was toying with the idea of adding a CURL fallback option.
×
×
  • Create New...