-
Posts
16,772 -
Joined
-
Last visited
-
Days Won
1,530
Everything posted by ryan
-
Apeisa is correct in that inputfields can be represented as arrays, and it's fairly simple to convert them to or from arrays. In the case of FormBuilder, the forms are converted to an array and then to JSON for storage. So far the only place I've found this useful is in FormBuilder, though I'm sure there's more potential. As for manually composing inputfields or forms via arrays, I don't really like doing that because there is no interface… just a faceless array. Reminds me a little too much of configuring forms in Drupal. But I'm fine with supporting the option if people like it.
-
You have to enable it in your Form Builder module settings: InputfieldFormBuilderFile. On an existing FormBuilder installation, you may have to install the module before you can enable it. The $e['file'] should be an array of filenames. In the case of a single file, it would just be an array of 1 file. The actual file URL is protected from direct access, so you have to ask Form Builder to generate one for you. It's not the prettiest in terms of API access, but I think this should work: $form = $forms->get('contact-form'); foreach($form->entries()->find() as $entry) { foreach($entry['file'] as $filename) { $path = $form->entries()->getFilesPath($entry['id']); $url = $forms->getFileURL($form->id, $entry['id'], $path . basename($filename)); echo $url . "<br />"; } } Regarding submission date, Soma is correct that it would be contained in $entry['created']; as a unix timestamp.
-
Seems like we do need another shutdown hook of some sort here that gets called regardless of whether it was a pageview or a redirect. Semantically, it probably makes sense that ProcessPageView::finished doesn't get called on a redirect, though not sure it really matters. What do you guys think would be best of these 3 options: Make $session->redirect() call $processPageView->finished(); before exiting. Add a new ProcessWire::shutdown hookable method that always gets called. Add an optional finished() method to the module interface. Like the ready() method, but gets called automatically (on modules that have it) when the request is done.
-
I'm assuming the 404 you are getting is an Apache one rather than a ProcessWire one. You are seeing mod_security in action. When mod_security gets in the way of legitimate content management, then it's configured in an overly agressive manner. I would ask your host to loosen things up a bit, or if they can't, have them disable mod_security for your account.
-
Looks like you are on the right track there. As for the field name and/or id, I'm guessing you don't want to use the title though. In order to make sure you've got something unique, you might want to use "myfield{$cat->id}" or something like that. If you don't need to support images/files in repeaters, then it won't be too difficult. You would add one or more repeater items at the end, but make them hidden or collapsed. You could have a little javascript link that says "add item" and when clicked, it unhides the next one. Make the fields in each follow a different name format, like "myfield_new1" for the first one, "myfield_new2" for the second one, etc. Basically, some name format that your processor would know is referring to a new item it should add. Then it could process them like this: $n = 1; $name = "myfield_new$n"; while($input->post->$name) { $item = $mypage->myrepeater->getNewItem() // populate any fields in the repeater you want $item->title = $input->post->$name; $item->save(); $mypage->myrepeater->add($item); $n++; $name = "myfield_new$n"; } if($n > 1) $mypage->save('myrepeater');
-
The whole idea of a maintenance mode is something to be careful with on a site that depends on any kind of search traffic. It's not a great idea to make a habit of it, that's for sure. So if you need to put a site in maintenance mode, try not to do it for long. Personally, I have never had the need for a maintenance mode. Though there have been a couple times where I was pushing in a major update to a site, and I temporarily added the following to the top of the /index.php file: die("Go away! We are trying to upgrade the site.");
-
Thanks Soma, I have updated it.
-
I'm guessing that's the case (a blank <p></p> added by Markdown). Can you try replacing your /wire/modules/LanguageSupport/LanguageSupportFields.module with the attached? I think this may fix it. LanguageSupportFields.module
-
I've been making regular updates on the dev branch to the LanguageSupportPageNames module, so if you guys are using this, you may want to keep track of the updates. The good news is that this module is now running a production site: http://tripsite.com/cruises/ (only the /cruises/ site, as the rest of the site is running on a different copy of PW). This morning I pushed an update that makes it easier to tell if a given $page is viewable in another language. Now you can do this: if($page->viewable($language)) { ... } // Language object if($page->viewable('es')) { ... } // Language name That is basically telling you if the page has its "active" checkbox checked. Since these pages would already be excluded from search results, you don't typically need to use it except when on a given page and trying to determine what other languages that page is available in (like if you want to link to them, as the select box at the top of tripsite does).
-
I develop all my sites of subdirectories on localhost, but when migrating them they usually aren't running off subdirs. I usually load the DB sql file into my text editor and do a search/replace "/mysite/" => "/", before migrating the DB to the live site. But it won't be long before we have this task taken care of internally without any need to do replacements.
-
What are your settings for the field? Double check that you've defined the float precision.
-
@k07n: The module looks good. But start your class with an uppercase character, otherwise it might confuse PW's module parser, which is expecting it for categorization purposes. @jmart: 301 would really be the right way to do it and would not be a nightmare. Use Apeisa's redirects module and life will be easy. But if you really need all pages to be accessible at root level (which is not something I'd recommend) you could accomplish it by editing your 'home' template, clicking to the 'URLs' tab and enabling URL segments. Then in your home.php template: if($input->urlSegment1) { $p = $pages->find("name=" . $sanitizer->pageName($input->urlSegment1))->first(); if($p) { $session->redirect($p->url); // 301 redirect to it // echo $p->render(); // or output it here, no redirect } else { throw new Wire404Exception(); } } else { // render homepage }
-
Looks like getlocalization supports JSON and transifex supports YAML. It would be fairly easy to convert to/from formats they recognize.
-
When you get into sending POST data, ProcessWire has an http class that you can use rather than something like CURL. The benefit of using PW's WireHttp class is that it will fallback to sockets if it has to, ensuring the class works just about everywhere. Here's an example of the same web service we outlined above, except that this one posts to it: $data = array( 'username' => 'ryan', 'pass' => 'mypass', 'email' => 'info@grab.pw' ); $http = new WireHttp(); $result = $http->post('http://www.domain.com/path/to/service/', $data); if($result) { $result = json_decode($result, true); if($result['status'] == 'success') echo "Success! $result[message]"; else echo "Error! $result[message]"; } else { echo "error posting data"; } As a side note, this service is using the same password for the user to add, and the web service password. In reality, you'd probably want those to be different things.
-
I'm assuming those $page variables were actually supposed to be $pages? That first set of functions you called in your example have no sort defined. if you don't specify a "sort" in your selector to these functions, the order is either undefined, or by relevance. Functions where sort is inclusive are family functions connected with a page, like $page->children(), $page->child(), $page->siblings(), etc. You can expect those to use a predictable order. But a $pages->find() or $pages->get() with no "sort=" in it means you can't expect any particular order. Except when you are trying to partial match a string, it would attempt to sort them by relevance. If someone had a selector like yours, I would guess they probably wanted this instead: echo $pages->get('/')->children("include=hidden"); // all // or echo $pages->get('/')->child("include=hidden"); // first
-
Getting fake URLs (with UrlSegments) returned in search results
ryan replied to adrian's topic in General Support
I'm a little confused by how the whole thing works, despite reading the code a couple times. But if it works, then seems like it should be fine. The only thing I'd worry about here is scale, as you have potentially numerous find operations going on in these loops. But if you don't need it to scale too large, then it may not be an issue. Since I'm confused by the code itself, let's step back and go to the original question: Another option here would be to go ahead and implement a template file for your 'person' pages, and just let your search connect with the output of those pages. If you didn't want to go that route, you could always just make your search output loop handle pages using template 'person' differently: if($m->template == 'person') { foreach($m->categories as $c) { echo "<li><a href='$c->url'>$c->title</a></li>"; } } else { echo "<li><a href='$m->url'>$m->title</a></li>"; } -
Thanks for letting us know. That's cheap enough to make me jump. Already had a namecheap account, so went ahead and registered a few that were still available: runs.pw (maybe a sites directory?) grab.pw (fwd to the github maybe?) mods.pw (fwd for the modules dir) processwire.pw (why not) skyscrapers.pw (for the demo site) skyscraper.pw (for the demo site) wires.pw (who knows?) Anyone else find or buy any good ones?
-
Glad to hear this. We have so many here that are part of the MODX community too that it seems like a family, and I really want to see MODX do well.
-
That's correct. When PW 2.4 is here, it won't matter, because PW will require PHP 5.3+ as well. But this could be a recurring issue with PHP 5.4, 5.5, etc. I recommend that any modules available on the modules directory be required to have the same PHP version requirements as the version of PW they are written for. An autoload module that requires PHP 5.3 when they only have PHP 5.2 could take down someone's site.
-
My mind doesn't seem to understand pseudocode so well, but seems like you are on the right track. For something like this you'll want to test it all out to confirm it works the way you want to. Nobody can say for sure it'll work the way you want until it's confirmed to.
- 11 replies
-
- countdown time
- $session
- (and 2 more)
-
The PW API is always the same regardless of context. One of strengths of PW is in it's flexibility when it comes to sending or receiving web service data, and this is one of the things I use it for quite a lot. But you do have to tell it what to do, rather than it telling you what to do. At the simplest level, you could validate against an IP and/or password for authenticating the request. That may or may not be adequate, depending on who/what you are dealing with. In either case, use POST rather than GET. Here is a simple web service that adds a new user (written in the browser / not tested). This would simply be code written into a template file. Ideally you'd split this up a bit more, but just trying to keep it self contained for example purposes. $message = ''; $success = false; if($input->post->pass === 'mypass' && $_SERVER['REMOTE_ADDR'] === '123.123.123.123') { $name = $sanitizer->pageName($inpust->post->username); $pass = $input->post->pass; $email = $sanitizer->email($input->post->email); if($name && $pass && $email) { $u = $users->add($name); if($u->id) { $u->pass = $pass; $u->email = $email; $u->addRole($roles->get('some-role')); $u->save(); $success = true; $message = "Added new user: $u->name"; } else { $message = "username '$name' is already taken"; } } else { $message = "missing required fields"; } } else { $message = "you aren't authenticated"; } $result = array( 'status' => ($success ? "success" : "error"), 'message' => $message ); echo json_encode($result);
-
Very cool Adrian! A few suggestions: Make your version number 2 rather than 002. PHP might interpret that as Octal or something. Add an ___install() method that does a class_exists('imagick') and throws a WireException if it doesn't. Make the ___install() method add the document_pdf field, or make the module configurable so people can tell it what field to use. Put it on GitHub. Add to the modules directory. Profit! (as Adam would say)
-
Create a role called "top-level-editor" (or whatever you prefer). Give that role edit permission, but not delete permission. If you want the role to be able to sort children of these top level pages, then you'll want to assign page-sort permission to the role as well. Assign that role to the template used by your top level page(s). Create another role. We'll just call it "editor". Give that role edit, delete, move and sort permission. Assign that role to the templates indicated, but not the templates where you assigned top-level-editor. Don't forget to assign both of these roles "top-level-editor" and "editor" to your user(s) that you want to have this access. I think this was the part WillyC was trying to communicate.
-
I had to go get some coffee after seeing that photo. Just got this thing yesterday called an Aeropress. The guy that invented the Aerobee (frisbee) apparently locked himself away on a multi-year caffeine binge and came up with this clever device that supposedly makes the best coffee in the world. The coffee beans were just roasted from a place a block away from here, tasty.
-
You can match in either the filename, description, or tags via any of the DB-find functions too. $pages->find("files=myfile.jpg"); $pages->find("files%=myfile"); $pages->find("files.description*=some text"); $pages->find("files.tags%=mytag"); One thing to note is that description and tags have fulltext indexes, but the actual filename doesn't. As a result, if you need to perform a partial match on filename, you can only use the "%=" operator.