Jump to content

ryan

Administrators
  • Posts

    16,714
  • Joined

  • Last visited

  • Days Won

    1,515

Everything posted by ryan

  1. If you've got a page that is being saved 5000 times a day, then presumably that's because it is displaying some dynamic data. That page would be inappropriate for ProCache, since it caches the entire page output. Though if the page is being displayed more than 10k times a day, then it might still be worthwhile to use ProCache. But keep in mind that there is a small amount of overhead associated each time ProCache saves a cache of your page. So you have to factor that in to the equation. With a page focused on displaying dynamic data, you might be better off doing selective caching with MarkupCache, or just not using the cache. Another technique I'll often use is to handle the dynamic data with javascript, perhaps sending an ajax request back to the server and displaying the result after the cached page has already rendered. But if you are literally saving the page 5k times per day, that's just a lot of cache saving and clearing either way. Isn't there some way you could queue those changes to be committed once per hour or per day or something, so that you can still benefit from a cache?
  2. ryan

    Form Builder

    It can. Our sites directory is a good example of this, as it does pretty much everything you describe with FormBuilder. However, we review the submissions before approving them to be published on the site, and I always recommend this even if FormBuilder will let you publish directly. For instance, I've had a few submissions that were spam (though not obvious at first). Anything that gives users access to publish something on your site needs some eyes on it, unless you are dealing with a limited group of trusted users. But FormBuilder will let you do either.
  3. Is $page->image a single image (max files = 1?). If so, access $page->image is an object of type Pageimage, which has no remove() or delete() or deleteAll() methods. Those are instead methods of the WireArray that contains the file(s)/image(s). You could access that a couple of different ways. One way would be to get the "unformatted" value, which for files, always returns the containing WireArray: $page->getUnformatted('image')->delete($page->image); Another way would be to access the 'pagefiles' property of the image, which also refers to the containing WireArray. $page->image->pagefiles->delete($page->image); I mention the above examples for explanation, but PLEASE IGNORE THE ABOVE. Any time you are performing manipulations to a page, you should have the page's output formatting turned OFF. So there really isn't any situation in which you would use the above API examples... because it would mean you are modifying a page that is in an output-ready state, rather than a change-ready state. That's why ProcessWire throws an exception if you try to save a page with output formatting state active. The second point I want to make is that simply calling a delete() is queuing a deletion, not executing it. You still need to $page->save() or $page->save('image') before the deletion is committed. Given all this, I think this is what you want: $page->of(false); // turn off output formatting $page->image->delete($page->image); // you can use this line... $page->image->deleteAll(); // ...or this line (choose one) $page->save('image'); // or use $page->save(); if also saving other changes
  4. $config->paths->[property] refers to the server disk paths, and $config->urls->[property] refers to the corresponding URL. A Page object is something represented in a database, not a disk path on the server. So you can't draw a literal relationship between server paths and a page, since there is no physical file or directory for a page. Where you can draw the relationship is that the term 'path' or 'paths' always refers to the internal, server-side representation. Whereas the term 'url' or 'urls' always refers to to the external, client-side representation (something you would deliver to the browser).
  5. Your showIf statements look alright to me, though I don't think that matters to what you are trying to achieve here. Assuming I understand correctly, $page->column is a PageArray of pages under /columns/ and you want to access the $columnOption property of those pages, which are themselves page references. (Either: Batch and Font Awesome). Your code for home.php seems correct, except that you aren't accessing the $columnOption property at all in your code. You'd mentioned "checking if a selected option is active or not". Is something like this what you are trying to achieve? foreach($page->column as $c) { if($c->columnOption->name == 'batch') { // output Batch icon echo "<i class='icon $c->batchClass' data-icon='$c->batchDataIcon'></i>"; } else if($c->columnOption->name == 'fa') { // output Font Awesome icon echo "<i class='fa $c->faClass'></i>"; } // output everything else echo "<h3>$c->title</h3><p>$c->body</p>"; }
  6. The change to PDO was motivated more by the support of named parameters. Though bringing more abstraction to the DB layer also seemed like a good move for the long term, even without current plans to support other DBs. While PDO does abstract some of the considerations with supporting other databases, ProcessWire's queries are designed for MySQL, and are optimized for MySQL behavior. There's a lot of influence from the book: High Performance MySQL. Supporting another DB platform like PostgreSQL would probably not be such a straightforward thing. Though the truth is I don't know for sure, as I've not worked enough with PostgreSQL to know how similar or different the queries we use would be. But if you are looking at implementing some new fieldtypes, it would be best to look for how you might implement them with MySQL, since support for other DBs like PostgreSQL is not currently in the short term plan.
  7. I think that usernames as MD5 hashes are going to be difficult to look at on the admin side, and kind of defeats the purpose of the name field being a readable, unqiue identifier. I would create a separate field to handle your md5 hash and add that to your user template. Lets say you created a text field called user_hash and added it to your user template. You could have it automatically updated every time a user is added or saved just by putting some hook code in your /site/templates/admin.php file $pages->addHook('saveReady', function($event) { $page = $event->arguments(0); if($page->template == 'user') { $page->user_hash = md5($page->name . time()); } });
  8. ryan

    Wiki

    ProcessWire is a tool for building things, so a Wiki wouldn't build itself. But when you've got a need for such things, it's always good to evaluate the software that is already out there to perform the task. For instance, I quite like the IP.Board forums, so see no reason to go build our forum in ProcessWire. Likewise, Wikis are an entire category of CMSs, with MediaWiki being the most widely known/used. After evaluating the options, if you decide not to use a turn-key package and that you'd still like to build it in ProcessWire, you'll find it'll be a whole lot easier than trying to build a Wiki elsewhere (I've always thought a Wiki would be quite fun to build in PW).
  9. Thomas, there isn't any reason why it should take that long. Number of children/siblings makes no difference to how long it takes to add a page. As a result, I would look at what else is happening on your front end or in any modules that may be taking part here. Because the time seems to increase with quantity of pages, most likely you've got something loading all those sibling pages and pulling something from them. In particular, look for any $parent->children() or $page->siblings() calls that lack "limit=n" selectors in them. Feel free to post the code you are using and we can take a look at it.
  10. You've got a hard-coded page assets URL in your javascript there, and the 1023 in it is referring to the page ID. Somehow you'd need to replace that with the ID of the page you are referring to, or better yet, call the $page->filesManager->url() to get the entire URL to it, rather than trying to construct your own. Getting either of those things will be fairly simple if your javascript here lives in one of your template files, as you would just refer to $page->id, or $page->filesManager->url() directly, and insert that value into the javascript. If this JS instead lives in an external JS file then you'll need to communicate that to the javascript somehow. One good way to do it is to use data attributes in your markup generated by your template file. Example: <div id='map' data-page='<?=$page->id?>' data-files='<?=$page->filesManager->url?>'> </div> Then from Javascript (jQuery), you can pull those values easily: var pageID = $('#map').attr('data-page'); var filesURL = $('#map').attr('data-files');
  11. ryan

    Lister

    Here's a video of a module we're working on that I thought you guys might like. The module, Lister, provides a different type of Page List than the tree that you usually interact with in ProcessWire. It gives you a table of pages with customizable columns, filters and actions. Rather than try to explain what it does, I figured I'd show you. This module also uses a new (soon to be released) Inputfield invented by Apeisa, developed by me, and sponsored by Avoine, called InputfieldSelector – it's what you see on the configuration screen as well as the Filters tab. I recommend bumping up the size/quality to 720p so that you can properly see everything. The video has no sound... I tried to do one with narration, but that didn't work out.
  12. Remi, I'm not sure I fully understand the question, but it looks like you are getting a different result from swapping the order of your sanitizer calls? It should make no difference, but if it does then my best guess would be that something in the $translation object is getting changed as a result of accessing the 'clean' or 'translation' property.
  13. I'm currently working on a couple modules that require newer versions of ProcessWire and newer versions of specific modules (as dependencies). Currently, there is no way to specify versions with module dependencies other than having your install() method throw an exception. As a result, module dependencies have been updated (on dev branch, 2.4.1) to include support for module versions, as well as PHP and ProcessWire versions. The best way to describe it is to show an example of how you'd use it. I'll take an example from the first post here and update it (note the 'requires' line at the bottom): public static function getModuleInfo() { return array( 'title' => 'Log Master (Process)', 'version' => 100, 'author' => 'Lumberjack Bob', 'summary' => 'Displays the logged actions in the admin', 'requires' => 'ProcessHello>=101, ProcessWire>=2.4.0, PHP>=5.4.0', ); ); The 'requires' line above specifies that this module has the following requirements: ProcessHello module version 1.0.1 or newer ProcessWire version 2.4.0 or newer PHP version 5.4.0 or newer If no particular version of a module is required then you'd simply omit the operator and version, as you've done with dependencies in the past. Another thing to note above is that the 'requires' line accepts a CSV string. Before, you had to use an array if you wanted to specify multiple dependencies. You can still use an array if you want to, but it's not required. The above 'requires' line as an array would look like this: 'requires' => array('ProcessHello>=1.0.1', 'ProcessWire>=2.4.0', 'PHP>=5.4.0') For ProcessWire or PHP versions, you need to specify a 2-3 part version string like "2.4.0". But for modules, you can specify either an integer or a 3 part version string. It's more consistent, and thus a little bit preferable to specify an integer (like in my first example) since that is already how versions are specified in the getModuleInfo 'version' property (i.e. 101 rather than 1.0.1). However, it doesn't really matter.
  14. ryan

    New Logo

    Thanks for helping me debug this. I'm not the developer of the stylesheets and so I'm still learning how this particular part is supposed to work. But the #top-buttons css in global.css is not something that I added there. It's always been there as far as I know. It's there because the mobile-first technique being used in the stylesheets dictates that the buttons don't show on mobile. But if you look in the layout.css file, which comes later in the CSS order, it has code to reveal them for the desktop views. It had a display: block for #top-buttons, but also needed a display: block; for #top-buttons .wire-button. I added it in there and that seems to have fixed it. But it's still a mystery to me why, as I don't think there had been any changes to these stylesheets for anything to do with the #top-buttons. But clearly there must have been. I think I can only blame it on not drinking my coffee fast enough one morning this week.
  15. ryan

    New Logo

    I definitely don't see them–tried in 3 browsers, they are gone in each. I'm only seeing the aroused chevrons in Chrome though.
  16. ryan

    New Logo

    Regarding the logo, we have Soma to thank for that (though others have also contributed). It was motivated by the need to stand out on Bitnami, though we've generally needed a mark for a long time. Soma worked tirelessly on dozens (maybe hundreds?) of variations of different logos, and came up with consistently fantastic work. Like ProcessWire, it's simple, but spend some time with it and you'll see it does more than you thought at first. You'll find it to be constructed of a wire, and the letter P (and a wire) being formed both in positive and negative space. Hope that you guys like it. Thanks again to Soma for the great work. I didn't remove the buttons, as far as I know. Though I did add the logo on the site a couple of days ago–maybe I screwed something up in the process? I don't know what. Also not sure what's up with the chevrons but I've been enjoying that too... though they aren't so much fun anymore. I'm going to dive in and see what's up. But I didn't do the front-end development for this site, so it's still somewhat unfamiliar to me. If anyone has a better clue of what's wrong with it, please let me know.
  17. Thanks for making this Horst! Tested here and got it working. I did have to modify your to() function (my fault, since I changed the WireMail interface for that function in the last update), but that was easy, and everything else worked (testing it with Gmail). I particularly liked being able to test the settings from the module screen. Your getModuleInfo() returns singular=true. The intention with WireMail is that it would be singular=false, so that you'd start with a new/fresh instance every time you get it from wireMail() or $modules->get('WireMailSmtp'). Otherwise, it might already have the to/from/subject/body settings from the last use still in there. Why necessary to specify the sender email address in the module settings? Will this prevent someone from being able to change the $mail->from(); address from the API side? Also was wondering why it's necessary to specify the hostname in the module settings? Does it go into an envelope from header or something?
  18. Thanks Teppo, this is great! I'm looking forward to using this one. I did try to install but ran into some troubles. I was unable to get it to save SMTPServer or SMTPPort. I tracked that down to an issue with field dependencies (in the core, not your module). I've now fixed that in the core, but you may want to remove the requiredIf condition from those two fields if possible, at least temporarily, as I need to do more testing with the core changes I made before committing to GitHub. Once I was able to save the SMTPServer and SMTPPort settings, I tried to use the module but keep getting this message: Fatal error: Class 'Swift_Message' not found in /Volumes/RyMain/Users/ryan/htdocs/cpi/site/modules/WireMailSwiftMailer/WireMailSwiftMailer.module on line 261 It looks like this condition is failing somehow: if ($this->transport != "Smtp" || $this->SMTPServer && $this->SMTPPort && $this->senderAddress) If I remove that line above (as well as the closing brace further in the function) then I no longer get errors. Following that, I configured it for Gmail per the instructions you linked to. The instructions said to choose "SSL/TLS". I chose "TLS" first, but that didn't work. So next I tried "SSL", and that worked. So SMTP setup is now working for me and it seems to work great. Some other things to mention: 1. The module should not be autoload, if possible. WireMail is intended to be loaded on demand rather than on every request. 2. The module should not be singular, if possible. When someone makes a call to wireMail(), we want to make sure we're returning them a brand new copy rather than one that might already have some email settings populated in it. That's why singular should be false, so that every time the module is retrieved a new instance is born. 3. The module version number shouldn't have preceding zeros, as this starts PHP thinking it's an octal number or something else (I don't recall). So version number should be 6 rather than 006. 4. The require() statement in your init() function should likely be a require_once(), and it should ideally include the full path, just in case another copy of of the same directory name exists elsewhere in the PHP path. i.e. require_once(dirname(__FILE__) . '/Swift-' . self::SWIFT_VERSION . '/lib/swift_required.php');
  19. Thanks, just pushed a fix for this. Good point! While I almost never use a "TO: name" (and many email clients, including gmail, don't even display it), it does make sense to support it. I've just updated it to support this. I went a little bit different route than you mentioned though, because there's always a chance two recipients might have the same name, but not likely they would have the same email. So I didn't think name would be workable as an array index. I also wanted to maintain consistency with how it's storing 'from' and 'fromName' separately, so the 'to' and 'toName' are stored in separate arrays. The 'toName' array is indexed by the email address. So now if you want to support use of 'toName' in your send() method, you'd do this: foreach($this->to as $email) { $name = $this->toName[$email]; if($name) { // send to: Name <$email> } else { // send to: $email } } If you don't need/want to support the "TO: name" (as in WireMailTest) then you don't have to do anything, as the means by which you access and iterate $this->to has not changed. As for how to supply to "TO: name" from the API side, you can do it any of these ways: // you can also use a string (or CSV string for multiple), like you would with PHP mail wireMail('User Name <user@example.com>', $from, $subject, $body); // array may be simplest if sending to multiple email addresses wireMail(array('user@example.com' => 'User Name'), $from, $subject, $body); // from the object side you can supply it as an optional 2nd argument to the to() method $mail = wireMail(); $mail->to('user@example.com', 'User Name'); // or in an array $mail->to(array('user@example.com' => 'User Name')); // or as a string (or CSV string for multiple) $mail->to('User Name <user@example.com>'); // the WireMail::from has also been updated to support a second argument or string $mail->from('sender@example.com', 'Sender Name'); $mail->from('Sender Name <sender@example.com>'); One other change is that the to() method no longer clears out any existing to() addresses on every call. So you don't have to supply all of your to: addresses in the single function call, you can call it multiple times, each with a separate email address if preferred. But if you do want to clear out the list, then just call the to() method with no arguments and it'll clear them. Yes, once we've merged the WireMail class into the master branch (stable), then I'll put out an updated FormBuilder that uses wireMail() rather than mail(). Though if anyone needs it sooner, I'll be happy to post an updated FormBuilderEmail class that uses wireMail().
  20. Lots of people have been asking for a way for ProcessWire to support sending of email, outside of just using PHP's mail() function. I haven't really wanted to expand the scope of ProcessWire that deep into email sending, but I have been wanting to setup a way so that people could override how emails are sent, with modules. For people that are interested in making other ways of sending email in ProcessWire, I've setup a new module base class called WireMail, and a new function called wireMail(). The wireMail() function will use whatever WireMail module is installed. If none is installed, then it will use PW's default WireMail implementation (based on PHP's default mail function). The wireMail() function replaces all instances of PHP's mail() function in ProcessWire's source. It works in a similar way as PHP's mail() except that supports a few different usages. Standard usage would be this: // to, from, subject, body wireMail('user@domain.com', 'ryan@runs.pw', 'Mail Subject', 'Mail Body'); Another usage would be to give it no arguments, and it'll return whatever WireMail module is installed for you to use yourself. If no WireMail module is installed, then it returns ProcessWire's WireMail. $mail = wireMail(); $mail->to('user@hi.com')->from('ryan@runs.pw'); // all calls can be chained $mail->subject('Mail Subject'); $mail->body('Mail Body'); $mail->bodyHTML('<html><body><h1>Mail Body</h1></body></html>'); $mail->send(); Since all of this stuff is only on the PW 2.4 dev branch at present, I'm posting this primarily for people that are interested in creating WireMail modules. For instance, I know that both Teppo and Horst (and perhaps others?) have put together such modules and ideas, so this is all aimed at coming up with a way for those ideas to be easily integrated into PW by way of modules. To make your own WireMail module, you simply create a module that extends WireMail and provide your own implementation for the send() method. Of course, you can go further than that, but that's all that is technically necessary. I've attached an example module called WireMailTest that demonstrates a WireMail module. When installed, it is used rather than PW's WireMail. This WireMailTest module includes lots of comments for you in the code of it, and you may find it helpful to use it as your starting point. WireMailTest.module For you guys developing modules, please throw any questions my way and I'm happy to help. Likewise, let me know if you think I'm missing anything important in the base interface that the modules are based upon and we can update it.
  21. @cstevensjr - I grew up in McLean, VA and think I used to go to that doctor, or at least one in the same building or next door to it. It's been while, but I thought the address sounded familiar so viewed it on Google Streetview and sure enough I recognize the location. I navigated around on Streetview and see my old Starbucks, Total Beverage, McLean Racquet Club, and Giant grocery store are all still there. (I haven't been there for 10-15 years)
  22. An HTTP hosts whitelist is important from a security aspect because http_host comes from the request rather than from the server... Meaning it can be forged. Maybe not a big deal since we always sanitize it, until you are dealing with cache, which the opens up the possibility of cache poisoning for any page that makes use of the http host. Imagine a hacker priming your cache with their own URL. Unfortunately, PHP's safe server_name variable is not reliable enough to reflect the potential diversity of http host names. So the only safe thing to do is to have a whitelist. If you aren't using the whitelist, I recommend adding it to your config.php. It's actually a little unusual for the http host to be used in PW because usually you'd just use the url() methods, which just output paths and not hosts. There's really no reason to use httpUrl() in most cases. So if you are using it, double check that you need to - it's extra unnecessary bytes unless you need to switch hostnames or schema. But with the next version of ProCache supporting multi-hosts, having an http host whitelist is now absolutely necessary.
  23. Users still getting logged out? Just as a test, what happens if you open another window along the way, whether hitting the payment gateway URL with a target=_blank, or what not. Just curious if that keeps the session active.
  24. Gebeer, you can ignore that guest required message. It really doesn't mean anything and I've actually got it suppressed in the latest PW. All it meant was that it was assigning the guest role at runtime, and that's something that should just happen in the background- the error message was just making confusion. As for the other issue you mentioned, the guest role is meant to collaborate with the language named "default", but it can be changed at runtime - this is exactly what the language support page names module does.
  25. ryan

    Hanna Code

    Marty, not sure why there is no sanitizer entities method there. Maybe we didn't have it in 2.2, I don't recall. Try replacing your wire/core/Sanitizer.php file with a fresh copy. It should be fine to take the one from 2.3 or 2.4. Jean-luc, glad to see you found the getForPage method. This is exactly the way that repeater pages are meant to refer to their containing page, whether in a Hanna code or elsewhere.
×
×
  • Create New...