Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/16/2014 in all areas

  1. Hello I've written a little module that backs up your ProcessWire site to Amazon S3 (might add support for other storage providers later, hence the generic name). Pete's ScheduleBackups was used as a starting point but has been overhauled somewhat. Still, it's far from perfect at the moment, but I guess you might find it useful. Essentially, you set up a cron job to load a page every day, and then the script creates a .tar.gz containing all of the site files and a dump of the database, then uploads it to an S3 bucket. Currently, only linux-based hosts are supported currently (hopefully, most of you). The module is available on github: https://github.com/DavidJRobertson/ProcessWire-ScheduleCloudBackups Zip download: https://github.com/DavidJRobertson/ProcessWire-ScheduleCloudBackups/archive/master.zip Let me know what you think EDIT: now available on the module directory @ http://modules.processwire.com/modules/schedule-cloud-backups
    12 points
  2. Hi i just finished website that i build on processwire. Im a frontend developer and noob with php. But with processwire i managed to build this site, so i want to thank you for giving us such a great tool for building websites. Here is website in Polish, and in a month or so i will release english version of the site. http://hejtuje.com english version will be avaible in here : http://hate.it Some feedback would be nice . Thanks PW!.
    5 points
  3. This looks fantastic djr! I've had a need for something exactly like this and will definitely look forward to using it. I took a quick look through the code and think it looks very well put together. I do have a few minor suggestions: Rather than backing up the DB to the root path (where it is temporarily web accessible) I'd recommend backing it up to a non web accessible directory, like /site/assets/cache/. Likewise for the tar/gz file. Beyond just looking for "runbackup" in the request URI, I recommend designating a page that it will only run on. For instance, if you wanted it to only run on the homepage: $shouldBackup = $page->path === '/' && (strpos($_SERVER['REQUEST_URI'], self::RUN_BACKUP_PATH) !== FALSE) && $this->wire('input')->get->token && $this->wire('input')->get->token === $this->token; This might be a good module to experiment with conditional autoloads. In your getModuleInfo, you can do this: 'autoload' => function() { return (strpos($_SERVER['REQUEST_URI'], self::RUN_BACKUP_PATH) !== FALSE); } In truth, conditional autoloads are more reliable in PW 2.5 (a few minor issues have been fixed) so this may be a v2 kind of thing as well. In PW 2.5, you can also isolate the entire getModuleInfo() to a separate ModuleName.info.php file. Beyond just the token, it might be worthwhile to have an IP address limiter since there's a good chance one's CRON job is always going to be coming from the same IP. Though not sure it's totally necessary. In your docs file, I would mention if possible what command you recommend for the CRON job, for instance: wget quiet no-cache -O - http://www.your-site.com/runbackup?token=abc123 > /dev/null Lastly, might be good to mention that it requires exec/system access for executing commands (many hosts have these disabled by default, but there's usually a way to enable them). Please add to the modules directory when ready! Thanks for putting this together!
    4 points
  4. Hey guys, got asked to share how to set up mpdf with processwire so it's time to make a little tutorial Disclaimer: ( ) This is my first tutorial and I'm not a real coder yet so every tips and hints are highly appreciated Grab a copy of mPDF unzip it and put it in a nice place outside of your Processwire folder(s) - (as far as I remember is has to be outside or within a module to work, but I could be wrong?!) Open the template from which you want to create the PDF from In my case I have a "course.php" which is showing a page with a weekly schedule table and I wanted to provide this schedule as pdf next to the website version. I turned on urlSegments for "course" template, because I find it nicer than a get variable Then in my course.php template file after the normal website output I added the following It's probably better to have this logic at the very top of the template file to prevent unnecessary code execution right?? Aha, now I remember why it's at the bottom. I have some more logic above it which I wanted to share for browser output and pdf creation and this was the easiest way, probably I'll rearrange everything to make it faster At least the if( file_exists logic could go at the very top <?php // In case you don't have other urlSegments it's better to throw a 404 when someone types a non existing url, // could be managed better but at the moment it's easier if($input->urlSegment1 && $sanitizer->pageName($input->urlSegment1) != 'pdf') throw new Wire404Exception(); // if urlSegment /pdf/ output course table as PDF file if($sanitizer->pageName($input->urlSegment1) === 'pdf') { // $config->paths->files = PWs /assets/files/ folder, page ID and the title of the page could be any field or anything else // maybe you want to add the date $pdfPath = $config->paths->files . $page->id . "/" . $page->title.'.pdf'; // Options for wireSendFile because they're needed more then once $wireSendOptions = array('exit' => true, 'forceDownload' => true, 'downloadFilename' => ''); // If file already exists force download it and stop further execution which is handled $wireSendOptions 'exit' => true if(file_exists( $pdfPath )) wireSendFile($config->paths->files . $page->id . "/" . $headline.'.pdf', $wireSendOptions ); // include mPDF.php conditionally for localhost and productive website, you probably don't need it if structure is the same // included it at this point because we don't need it to provide an existing file // you could even include it after your output logic just before PDF creation.. if($config->httpHost == 'localhost') { include("../../../../classes/MPDF57/mpdf.php") } else { include("../../../classes/MPDF57/mpdf.php"); } // at this point you create the logic for your output // I'm not sure wether mPDF understands single 'quotes' properly // TCPDF doesn't really liked them so I stick to double "quotes" for now // just a little example how it might look you can of course have a loop populate everything from $page or somewhere else ;-) $pdfOutput = '<table class="data"> <tr> <th>Entry Header 1</th> <th>Entry Header 2</th> <th>Entry Header 3</th> <th>Entry Header 4</th> </tr> <tr> <td>Entry First Line 1</td> <td>Entry First Line 2</td> <td>Entry First Line 3</td> <td>Entry First Line 4</td> </tr> <tr> <td>Entry Line 1</td> <td>Entry Line 2</td> <td>Entry Line 3</td> <td>Entry Line 4</td> </tr> <tr> <td>Entry Last Line 1</td> <td>Entry Last Line 2</td> <td>Entry Last Line 3</td> <td>Entry Last Line 4</td> </tr> </table>'; // now the best part // the next comment explains the mPDF() parameters as in the manual http://mpdf1.com/manual/index.php?tid=184 // mode, format, default_font_size, default_font, margin_left, margin_right, // margin_top, margin_bottom, margin_header, margin_footer, orientation $mpdf = new mPDF('utf-8','A4-L', 0, '', 5, 5, 16, 6, 5, 5, 'L'); // The header is repeated on all pages, it's possibly to have different headers (even/odd) and other fancy stuff // You can have images as well, just have a look at the documentation it's pretty good $mpdf->SetHTMLHeader("<h2>{$page->title}</h2>"); // this one puts your table, created above, into the file $mpdf->WriteHTML($pdfOutput); // I'm saving the PDF file to the disc first as set in line 9 // 'D' would output the file inline in the browser window but then we're not able to store it for faster serving $mpdf->Output($pdfPath,'F'); // Thanks to Ryan and his nice functions we can use wireSendFile (as above) to get the created file and force download it wireSendFile($pdfPath, $wireSendOptions ); } // End if /pdf/ If you want to create the file everytime it's called and don't want the it to get stored just strip line 12, 15 and 67 and change the 'F' in line 64 to 'D' If you want to have a newly created file each time you change the page you have to install a little module to hookAfter page save It's just one file, I called it like hooks.module because maybe I will add some hooks later and there is no need to have each hook in a separate module. <?php class Hooks extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Custom Hooks', 'summary' => 'Hooks, PDF deletion on page save for example', 'version' => 1, 'autoload' => true, // You want it to autoload, otherwise it would never get called ); } public function init() { $this->pages->addHookAfter('save', $this, 'deletePDF'); //initialise the hook } // Most of it is just copied from Pages2PDF module from Wanze, a little 'simplified' though^^ public function deletePDF(HookEvent $event) { $page = $event->arguments[0]; $pdf = wire('config')->paths->files . $page->id . "/" . $page->title.'.pdf'; if (file_exists($pdf) && is_file($pdf)) { $name = $page->title.'.pdf'; if (@unlink($pdf)) { $this->message($this->_(sprintf("The following file got deleted '%s'", $name))); } else { $this->error($this->_(sprintf("Failed to delete '%s'", $name))); } } } } Hope you can follow the steps. Please let me know if not and why Any improvements are welcome because I would love to learn more as well
    3 points
  5. @Can - could you possibly share how you setup mpdf with PW? maybe on a tutorial thread? cheers!
    3 points
  6. Just to explain the difference between what diogo and I wrote. His is simpler, but mine is more descriptive. child on it's own will always be the first child. With children, you can further select last(), or use eq(n) to choose the exact one in the list of children by its numerical order index. Hope that helps.
    2 points
  7. @benbyf nice website you have there. I particularly like the way you present your works. Elegant animation on the buttons and the filter effect is way cool.
    2 points
  8. Here you go Macrura https://processwire.com/talk/topic/7025-how-to-create-pdfs-with-pw-and-mpdf/ Any tips are highly appreciated
    2 points
  9. Hi guys! I'm working on several processwire 3d wallpapers. Hope you like it. I will upload more soon. Wallpapers: Signatures:
    1 point
  10. i am trying to save a page array as a .json string. i tried: $values = $pages->find("title=foo"); $jsonFile = wireEncodeJSON($values->getArray()); yet i simply get : [{},{},{}] i figured this didn't work becase the array has values which are objects, and they don't get converted properly. i can probablly go through every child and convert it to an array and bulid the json manually, yet i wonder if there is an easier way to do this. thanks
    1 point
  11. Hello Tramvai, welcome to the forum! Make this your 'cars' template: <?php $session->redirect($page->child->url) edit: Adrian was too fast
    1 point
  12. Hi Tramvai and welcome to PW. This can be accomplished easily with a redirect. Place this in the template file that is connected to your Cars page: $session->redirect($page->children->first()->url); Of course you could also be more specific about the page that it redirects to, but in this example it will always go to the first child of the parent page.
    1 point
  13. Just had a quick thinking about this and the first impression that I have is that it would be enough to have the same approach as Soma's image manager (1 page -> one folder) but add the ability to change the url to that folder in the .htaccess (probably this would have to be done manualy after knowing the ID of the page) and extend the files module so ->url uses the new url instead.
    1 point
  14. I implemented a similar thing a while ago and ended up with the code below. I think it was pieced together base on some previous code we had lying around at the company, and I'm not sure why the distance value is so precise at 8.047. It's not a perfect circular distance either, but it seems to work for what was needed at the time. // $lat and $lng should be float values of the location to search $distance = 8.047; //in km $radius = 6371; // earth's radius in km = ~6371 // latitude boundaries $maxlat = $lat + rad2deg($distance / $radius); $minlat = $lat - rad2deg($distance / $radius); // longitude boundaries (longitude gets smaller when latitude increases) $maxlng = $lng + rad2deg($distance / $radius / cos(deg2rad($lat))); $minlng = $lng - rad2deg($distance / $radius / cos(deg2rad($lat))); $query = "coords.lat>=$minlat, coords.lat<=$maxlat, coords.lng>=$minlng, coords.lng<=$maxlng"; In that code, 'coords' is the mapmarker field.
    1 point
  15. This is great and very useful. Thanks a lot Can! May have spotted an error. In line 33 you define the HTML table as $pdfOutput. And the in line 71 you go $mpdf->WriteHTML($table); I think it should read $mpdf->WriteHTML($pdfOutput); I will most likely put this to use. Only waiting for the customer to finally confirm that they want this feature. I will add the cart logic as discussed in the other thread and publish my code here. Will take another month more or so. Cheers Gerhard
    1 point
  16. I got this working. Not sure where the problem was, but it is now ok.
    1 point
  17. Looks like you have to set a RewriteBase (just delete the # in front of the first line "RewriteBase /" or if your installations lays in a subfolder change it to "RewriteBase /subfolder/") And please check if modrewrite is installed on your server: http://stackoverflow.com/questions/9021425/how-to-check-if-mod-rewrite-is-enabled-in-php
    1 point
  18. Maybe a bit late but check out this wonderfull piece of code by Nico.
    1 point
  19. I just finished this article and wanted to post it here as I'd love to get some feedback from you guys in the comments of the article explaining why you work with ProcessWire. There's a great chance here to help spread the word a bit more for this awesome CMS we all love. If you have five minutes, please share your thoughts in the article comments. I'd appreciate it. ProcessWire vs WordPress
    1 point
  20. There was a free PHP/jQuery Snippet in the last CMS i used with a Kind of HannaCode addon [[rating]] where needed. It works with a separeted sqllite db - maybe could used as a base or snippet for a simpler or free usecase. https://github.com/tlongren/colorrating
    1 point
  21. Take care what you put in the _init.php. it can get executed multiple time if you use to render() pages inside the templates. Every render triggers slay what you have in init. Just good to know.
    1 point
  22. Thank You, hope you enjoied your vacation. It was a real quick port I needed up and running. I'm sure that you - not being new at pw as am I - will be able to port the idea in a better and more elegant way into your more known and tested module. kindly
    1 point
  23. Absolutely possible and no problems! One thing you might want to check out is Soma's Soft Lock: http://modules.processwire.com/modules/page-edit-soft-lock/ This warns (or optionally prevents) users from editing the same page at the same time which could otherwise result in data loss. EDIT: You might have issues with multiple superusers changing field/template config settings.
    1 point
  24. Here is a screenshot of the admin for the table. It consists of tables for each service category. They are then joined together in the page to make one price table separated into different service sections.
    1 point
  25. Guys, Sorry I have been rather quiet in the recent past. You may have noticed I am in holiday mode and have been following, rather keenly, the trajectory of a certain spherical leather object ....Two more weeks to go and I should be back in play....(forgive the pun )
    1 point
  26. Yes I changed to 1 minute but no results. My original idea was to publish some stuff to facebook wall after saving a page in the admin area, title, description and images. I got and external php that does exactly that and works: <?php include_once 'inc/facebook.php'; $appId = '703738********'; $secret = 'd30530a5dcd*************'; $returnurl = 'http://myweb.es/facebook/post.php'; $permissions = 'manage_pages, publish_stream'; $fb = new Facebook(array('appId'=>$appId, 'secret'=>$secret)); $fbuser = $fb->getUser(); if($fbuser){ try{ $message = array( 'message' => 'foo' ); $result = $fb->api('/me/feed/','POST',$message); if($result){ echo 'Published'; } }catch(FacebookApiException $e){ echo $e->getMessage(); } }else{ $fbloginurl = $fb->getLoginUrl(array('redirect-uri'=>$returnurl, 'scope'=>$permissions)); echo '<a href="'.$fbloginurl.'">Login with Facebook</a>'; } ?> I'm trying to implement that in a hook, there is a checkbox, if is on then publish to facebook $this->pages->addHookAfter('save', $this, 'fb'); ..... if($page->facebook==1) { include_once 'fb/facebook.php'; $appId = '70373825******'; $secret = 'd30530a5dcd4e5829e6c8b********'; // $returnurl = 'http://indinet.es/facebook/post.php'; $returnurl = 'http://pwpage.com'; $permissions = 'manage_pages, publish_stream'; $fb = new Facebook(array('appId'=>$appId, 'secret'=>$secret)); $fbuser = $fb->getUser(); $this->message("user " . $fbuser); } // facebook .... I'm trying first to check the user id, but the result is just 0, whereas in the original file outside pw I get the user id without problems. Any ideas, Why?
    1 point
  27. Update: Blog version 1.2 Read below before updating. For new installs, proceed as normal ------------------------------------- Changelog TL:DR: Comments visibility settings + Posts' Bulk Actions + Update Script Comments Comments visibility can be controlled 'globally' as well as on a 'per post' basis Default is that comments and comment form are visible. You do not need to specify this setting; it just applies A post's comments SPECIFIED visibility overrides the global setting except for one case (see below). Post Comments Settings are set via a page select on a Post's page (also in 'Settings' tab in Blog Dashboard - see below) No selection: Default [comments and comments form will be shown] Always Show Comments: This will enforce overriding of global setting (e.g. Disable Comments) Disable New Comments: Will show old comments but not the comments form; visitors will not be able to submit new comments & message 'Comments closed for this post' will be shown. Disable Comments: Will neither show old comments nor the comments form; visitors will not be able to submit new comments & will see message 'Comments not allowed for this post'. Old comments WILL NOT be deleted . Global Comments Settings are set via a page select on the Comments page (in Dashboard as well). Settings here DO NOT override a Post's Comments settings WHERE A SELECTION has been made (i.e. if NOT empty). No selection: Default [comments and comments form will be shown] Disable New Comments: Similar to above Post setting except will affect all Posts' comments where no comments visibility selection has been made. Disable Comments: Similar to above Post setting except will affect all Posts' comments where no comments visibility selection has been made. Global Maximum comments allowed per post. If any number > 0 is specified in this new setting, IRRESPECTIVE of a Post's comments settings, if a post's comments is greater than the maximum set here, then 'Disable New Comments' will kick in. So, this takes precedence. Note: If you are logged in as superuser, even PENDING and SPAM comments are counted; so, the Global Maximum may be 'temporarily reached', if that makes sense Recap of comments visibility, in order of descending priority: 1. Global Maximum comments allowed for posts (/blog/comments/) 2. Any comment visibility SPECIFIED on a post (i.e. not empty) (/blog/posts/your-post/) 3. Any Global comment visibility SPECIFIED on comments page (/blog/comments/) 4. Default. 'Settings' Tab You can also set both the Global comments visibility and the Global Maximum comments allowed per post on this tab. The current setting will always be selected in the input field. Note: A blank Global comments visibility means no setting specified . So, if you want to change to 'no global setting specified', just select a blank and save [equivalent to deselecting a page select] (hope this makes sense). Note: Where no Global Maximum comments is set (i.e. blank), saving in the 'Settings' Tab's General Settings will subsequently show a '0' [zero]. This is equivalent to a blank, so not to worry Bulk Actions Introducing Bulk Actions for the Posts Tab! Make bulk changes to posts: Unpublish/Publish Comments visibility (as specified above for Posts' Comments visibility). In this case, also a 'Default Comments View' selection available. This is the equivalent of the 'no selection' specified in page selection field above. Trash Delete (note: no warning given before delete; careful with this one!) New column in Posts' Table also shows currently specified Comments visibility for each post. 'Default' means no selection made. Other - Some code clean-up. - See blog-side-bar.inc issue below. UPDATING I have written an update script (attached) that will add the new features in Blog 1.2 (2 fields, 1 template, 3 pages, 2 page updates, etc.). I have thoroughly tested the script. However, try this first on a test/non-essential install! If everything works, you can use it on your live environment Note: This assumes you haven't changed the native Blog paths and page names. Otherwise, it won't work properly. It won't corrupt any data but may just not install some stuff Note: You will still need to update the module as normal in your PW admin! Above is just to save you manually creating the extra fields, etc. To update: # Copy and paste the contents of blog-upgrade-version1-2.txt at the very top of one of your template files. Save the template file. # The script will only run if you are logged in as a superuser so other users won't know what's happening. # View a page using the template file you've just amended. The new fields, template and pages will be created. # Reverse the changes to your template file and save. # Update Blog via PW Admin as usual (to version 1.2) # Copy blog.css to /site/templates/css/. blog-upgrade-version1-2.txt If you are using the blog-side-bar.inc you might want to make/note the following changes. This only affects existing Blog installs! (not new ones) There was a missing <br> tag + $item->date instead of $item->blog_date. This will ensure Recent Comments widget also show the Post's date. If you are using the code from this file, you can make the following changes: OLD: $date = $blogOut->formatDate($item->date); $out .= "<li><span class='date'>$date</span> <a href='{$item->url}'>{$item->title}</a></li>"; NEW: $date = $blogOut->formatDate($item->blog_date); $out .= "<li><span class='date'>" . $date. "</span><br> <a href='{$item->url}'>{$item->title}</a></li>"; In addition, the code has now been changed not to show 'recent posts widget' on the blog home page. @Adrian idea, thanks! Screens Happy blogging!
    1 point
×
×
  • Create New...