Jump to content

Leaderboard

Popular Content

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

  1. As for feature set: my aim is not to solve each and every e-commerce situation there is. I would consider this more for "small shops" at this point, haven't tought about scalability for hundreds thousands orders for example. Here is short feature lists what I have so far and what I am planning for release: E-Commerce modules: Shopping cart Support for different delivery modules (these changes whole checkout process, what fields to ask from customer, what to show after payment success / fails etc. Currently I have done "DeliveryEmail" which only asks email address from customer and then sends email confirmation with possible download links. I will implement more general "DeliveryPostage", where we ask postal addresses also) Support for different payment methods (currently stripe implemented, looking for paypal too for the release - payment methods are independent, so they can be used in other projects too than only this shop) Admin page to manage downloads Fieldtype to attach downloads to products (products are always pages) Since products are pages, support for variations etc are easy: just use repeaters or PageTable. Admin page to manage orders: printing packing slip, mark them as delivered etc... (50% done) Admin page for simple monthly reports (todo) Multiple taxes and taxes for products (todo) These E-Commerce modules are planned in a way that first you build your product catalog (just using ProcessWire) and then install these modules (only those modules you need). So in a way these are quite a "transparent" glue there. Shop profile (might implement this after the beta period): Starter profile for "full featured" shop: product template, categories, tags, product search, related products etc... Can be used as a standalone shop or just for educational purposes (look how certain features are implemented and add them in own store).
    6 points
  2. I hope to open beta testing soon - planning to open it first for just one or two person and then after that start selling it with 50% off beta pricing. Yes, this is totally new system, no single line from current shop module used. Yesterday I got file downloads working. Couldn't use PW:s pagefiles, since those would have been public (because product page is public). So I ended up having general "downloads" section, where shop admin can add/edit/remove file downloads, and then new "downloads fieldtype", which allows attaching those downloads to page. This method has one drawback: adding file downloads is two step process (first add file into downloads section, then go edit product to attach it). There are some good sides also, especially if same downloads are found from mulptiple products and the files are updated every now and then. File downloads work by "codes", which are unique for each file and each order. You can set rules how long codes are active: for n or unlimited downloads or until certain date or always. There is also possibility to "re-deliver" digital downloads order from shop admin, so customer gets new email with fresh download links.
    6 points
  3. I agree with what you've stated. I've also worked with various ecommerce systems including: Magento: too overengineered, excruciatingly difficult to theme, slow, only makes sense sites that would take advantage of all its complexity; fun fact: it's 8 million lines of code, and the team consists of 8 developers; I believe the version 2.0 rewrite has been in the works for almost 4 years now Shopify: good but working with a remotely hosted / SaaS ecommerce system has its limitations. i also don't like how the catalog system is structured. Lemonstand: never worked with it but they went the remotely hosted / SaaS route OpenCart: looks nice on the outside, but once I dove in, I didn't like how certain things worked Prestashop: same as Opencart Volusion: SaaS and it sucks BigCommerce: SaaS; never used it but probably a good competitor to Shopify WooCommerce: not bad, however I've moved away from WordPress and since it's a WP plugin, it feels very second class, clunky and uses WP's architecture. it doesn't have a refined feel to it. also, a lot of functionality that should be built into it comes via extensions. given how the prices of extensions have sky rocketed for woocommerce, expect to spend around $500 to $1000+ dollars to bring it the features you will eventually need, that then may have issues with successive WP and Woocommerce updates... plugin hell. makes more sense to go with a dedicated ecommerce system where everything is built tightly together given those reasons. CS Cart: looks good, but I did some research and now I forgot why I didn't like it If I were to go with a dedicated ecommerce system, I'd either go with: Spree: Rails based solution. Got recently funded by GoDaddy with $5 million. Open source. Very promising and big names behind it. Built in a way where integrations can be done nicely. Sylius: Symfony based system. Looks promising as well. I don't take on too many ecommerce projects these days, however if I do, I keep it simple with ProcessWire + FoxyCart + OrderDesk. It's a simple but extremely flexible approach since ProcessWire makes it easy to build out a catalog that conforms to a site's unique catalog structure and product types without bending backwards and having to override a bunch of things. I'm interested to see what FoxyCart version 2 brings to the table. I'm also patiently awaiting Apeisa's system. Need any beta testers or perhaps some general feedback Apeisa?
    5 points
  4. Just for the record, here's how PW itself (in current dev branch) is doing it: $config->cli = (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || ($_SERVER['argc'] > 0 && is_numeric($_SERVER['argc']))));
    3 points
  5. -Home --Credit Card ---Newsletter (only renders) --Widgets ---Social ---Newsletter (holds the content and renders it) Right? Than see above. Or - alternatively for a specific field - use $page->get("selector").
    2 points
  6. Not sure if I understand your question right, but you can render the content of a page easily with another page. See here: http://wiki.processwire.com/index.php/Including_a_page_in_another_page
    2 points
  7. To create a sitemap.xml you can use Pete's Sitemap XML module, or you can create a template file and page to do it for you. This post explains how to create a template to do it for you. The benefit here is that you may find it simpler to tweak a template file than a module, though either is a good solution. Here is how to do it with a template file and a page: sitemap-xml.php <?php namespace ProcessWire; /** * ProcessWire Template to power a sitemap.xml * * 1. Copy this file to /site/templates/sitemap-xml.php * 2. Add the new template from the admin. * Under the "URLs" section, set it to NOT use trailing slashes. * 3. Create a new page at the root level, use your sitemap-xml template * and name the page "sitemap.xml". * * Note: hidden pages (and their children) are excluded from the sitemap. * If you have hidden pages that you want to be included, you can do so * by specifying the ID or path to them in an array sent to the * renderSiteMapXML() method at the bottom of this file. For instance: * * echo renderSiteMapXML(array('/hidden/page/', '/another/hidden/page/')); * */ function renderSitemapPage(Page $page) { return "\n<url>" . "\n\t<loc>" . $page->httpUrl . "</loc>" . "\n\t<lastmod>" . date("Y-m-d", $page->modified) . "</lastmod>" . "\n</url>"; } function renderSitemapChildren(Page $page) { $out = ''; $newParents = new PageArray(); $children = $page->children; foreach($children as $child) { $out .= renderSitemapPage($child); if($child->numChildren) $newParents->add($child); else wire('pages')->uncache($child); } foreach($newParents as $newParent) { $out .= renderSitemapChildren($newParent); wire('pages')->uncache($newParent); } return $out; } function renderSitemapXML(array $paths = array()) { $out = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; array_unshift($paths, '/'); // prepend homepage foreach($paths as $path) { $page = wire('pages')->get($path); if(!$page->id) continue; $out .= renderSitemapPage($page); if($page->numChildren) $out .= renderSitemapChildren($page); } $out .= "\n</urlset>"; return $out; } header("Content-Type: text/xml"); echo renderSitemapXML(); // If you want to include other hidden pages: // echo renderSitemapXML(array('/path/to/hidden/page/'));
    1 point
  8. This module adds page to Admin -> Setup -> Redirects where you can add 301 redirects (inside your site or to other domains). Screencast: http://www.screencast.com/users/apeisa/folders/Jing/media/e29abcca-5ef0-44dd-ac9a-2cc70f53d2c6 (I have Chrome with Instant on so it previews pages before hitting enter.. but I'm too laze to record another screencast. Also there is sneak preview to my upcoming admin theme...) Download & Installation: https://github.com/apeisa/ProcessRedirects/archives/master, unzip all the files to /site/modules/ProcessRedirects/ folder, check new modules from bottom of the modules page and hit install on ProcessRedirects. More information and "tutorial" how this was done can be found from here: http://processwire.com/talk/index.php/topic,167.msg1071.html (and like you can see, most of the code came from Ryan's hands, I just wrapped it all together). Hope you guys find this useful. Not tested yet on many servers, so all the feedback is more than welcome. ProcessRedirects5.zip
    1 point
  9. TemplateEngineFactory The main idea of this module is to support the developer separating logic from markup. This is achieved by turning ProcessWire templates into controllers which interact over a new API variable to template engines like Smarty or Twig. The TemplateEngineFactory ships with a default engine "ProcessWire" that uses the internal TemplateFile class to render the templates (some of you may already be familiar with this concept). However, the module is constructed in a way that any template engine can be used, implemented as separate modules. Please check out the readme on GitHub for more details how it works: https://github.com/wanze/TemplateEngineFactory ... or in the modules directory: http://modules.processwire.com/modules/template-engine-factory/ Implementation of Smarty: https://github.com/wanze/TemplateEngineSmarty Implementation of Twig: https://github.com/wanze/TemplateEngineTwig Implementation of Jade (by dreerr, thanks!): https://github.com/dreerr/TemplateEngineJade How does it work? A controller (aka ProcessWire template) can have an associated template file which contains the markup to render. The folder where those templates are stored is configurable for each installed engine. If the Factory finds a template file with the same name as the controller, an instance to access the template is provided with a new API variable (called "view" by default). Over this API variable, you can set the dynamic variables that should be rendered. Hopefully the following example makes things clearer: // In controller file: /site/templates/home.php if ($input->post->form) { // Do some processing, send mail, save data... $session->redirect('./'); } // Pass variable to the template $view->set('foo', 'bar'); $view->set('show_nav', true); $view->set('nav_pages', $pages->get('/')->children()); As you can see, there is no markup echoed out. The corresponding template file is responsible for this task: // In template file: /site/templates/view/home.php <h1><?= $page->title ?></h1> <p>Foo: <?= $foo ?></p> <?php if ($show_nav): ?> <ul> <?php foreach ($nav_pages as $p): ?> <li><a href="<?= $p->url ?>"><?= $p->title ?></a></li> <?php endforeach; ?> </ul> <?php endif; ?> In the example above, "ProcessWire" is used as engine. If Smarty is the active template engine, the corresponding template file could look like this: // In template file: /site/templates/smarty/home.tpl <h1>{$page->title}</h1> <p>Foo: {$foo}</p> {if $show_nav} <ul> {foreach $nav_pages as $p} <li><a href="{$p->url}">{$p->title}</a></li> {/foreach} </ul> {/if} Note that the API variable acts as a gateway which connects you to the activated template engine. We can switch the engine behind without changing the controller logic! (I know that this is probably not a very common need, but it's a cool thing anyway ) For further information, please check out the readmes on GitHub. Please ask questions if anything makes no sense - sometimes it's hard to get my explanations Cheers
    1 point
  10. 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
    1 point
  11. Thanks Today I pushed a little update (v.1.0.2) with some improvments. If you update to this version and already installed/used Smarty or Twig, make sure to update those modules as well. What's new? When loading a template file with the factory, you can optionally tell the module to use the given file behind the API variable: $factory = $modules->get('TemplateEngineFactory'); $view = $factory->load('pw_rocks', true); Setting the second parameter to true, the template file 'pw_rocks' is now used as active template behind the API variable. In the example above, the template file is also assigned to '$view' which reflects this change also to the $view variable which is locally scoped in controllers. Whatever template is set behind the $view variable is used by the module when rendering the output of a page.
    1 point
  12. Great Guys thanks a lot, Problem solved!
    1 point
  13. I've seen this before and if I recall correctly in our case this was due to a PHP version below (<) 5.3.8. When we updated the problem was gone.
    1 point
  14. Well.. I never heard about this error before. But I think it's always a good thing to stay updated because of compatibility and stability reasons. And I think Processwire kind of releases a huge updated only once a year this shouldn't be as annoying as with WordPress which offers an update like every day. And I think that repeaters were more like in a beta stage in 2.2 or at least really buggy as this search will show: https://www.google.de/search?q=processwire%202.2%20repeater%20bug&rct=j
    1 point
  15. @horst, so how is things working . I was forced to fix with a different fix again . It was in `DatabaseQuery` execute method. public function execute() { try { $database = $this->wire('database'); $query = $database->prepare($this->getQuery()); $query->execute(); } catch (Exception $e) { $msg = $e->getMessage(); if (strstr($msg, 'MySQL server has gone away')) { $database->closePdo(); } throw new Exception($e->getMessage()); } return $query; } and in the `WireDatabasePdo` adding a new method public function closePdo() { $this->pdo = null; } Hope this fix will help everyone . One still problem is one query can be missed which got the failure. To execute that I think it is good to call `execute()` again with some flag set. Your thoughts ?
    1 point
  16. Ok, so firstly, your search-form.php needs to access: $input->get->objective $input->get->status $input->get->new_old Then you need to build up the final selector to include these along with "q" I have to head out now, so don't have time for a full example, but if you look at the sksyscraper search you'll see how it builds up the selector by concatenating the pieces together like: $selector .= Not sure on your php knowledge, so in case you don't know the dot before the equal sign means to add to the last value of the variable. To troubleshoot, try testing a final example selector and once you have that working and returning the results you need, work backwards to figure out how to build if from the component search elements. I'll check in later and see how you are going.
    1 point
  17. Thanks for all the details - good to see that your form is using "get". Sorry for maybe getting distracted by that - my fault. In your form I see three select fields, all named "type" - should they be different filters? Anyway, the key thing seems to be simply that you don't deal with the type field in search-results.php. You need to make use of $input->get->type and add it to the selector that finds the matches. Does that make sense?
    1 point
  18. So where is it failing? Is your filter form really sending the search parameter "q" via the url? We need to know the name of the select field that is sending the objective filter and how that is being passed to search_form.php It might potentially be as simple as using : $input->get->objective but it's impossible to tell without seeing more of your code. Is your form being submitted (post) to search_form.php, or are you redirecting to a url like: mysite.com/?objective=xxxx (get)
    1 point
  19. I know you specifically asked for a way using a selector and that you didn't want to foreach through the templates, but I don't think that is possible and no-one has responded with anything better yet, so $tid = $templates->get("template_name")->id; $validTemplates = array(); // this array will be populated with templates that have the required parentTemplates settings foreach($templates as $t){ if(in_array($tid, $t->parentTemplates)) $validTemplates[] = $t->name; } Not ideal I know, but it seems to processes quickly and I think it gets you what you need, although I am guessing you probably knew how to do this already
    1 point
  20. i think what was happening then with the date/time is that it is getting server time, as opposed to processwire time.. $this->emailMessage->SetHeader("Date", date("D, j M Y H:i:s \G\M\T P")); so the problem could be for someone who is using a server in a different timezone could we override this at the template/api level? Also - to elaborate more on this use case: last year i found it necessary to setup future sending emails to some clients (hosting invoices, payment plans etc..) and the only solution i could come up with was a service called LetterMeLater; but i thought while using it, that it would not be so hard to build this in processwire... so after about 2 hrs of setup i was able to replicate that and it works well, better than the original service i was using; some features I've been able to accomplish over the last few days of creating this: Select Identity to send from (and then uses that identity's signature) Select multiple recipients using a profields table, setup a schedule of sending, along with placeholder texts for each sending instance Attachments to the message (page) Attachments from a central repository of attachments Links to documents/media Render inline images in body and signatures (using string replacements for the image urls - prepending the site URL), also floating images are working List of attached documents Send offset (so you can select a due date and then offset to send the message X days early; this way you can set the dates in the table to the due dates and avoid date confusion) Boilerplate insertion (select from an array of generic pre-written 'boilerplate' texts and insert them..) this is going to really save a lot of time for me! I'm also using Mandrill to send these, so i can check to make sure they were sent, and also i can see if the recipient opened the message..
    1 point
  21. Just wanted to note here in this post that I've built a configurable module for this and also included optional support for automatically generating the password for the new user. You can read more about it here: https://processwire.com/talk/topic/7051-email-new-user/ Also, there was some discussion above about how to get the entered password in plain text, but I don't think anyone actually came up with a working solution. I found that you can hook on InputfieldPassword::processInput and then you can get the plain text password with $event->object->value
    1 point
  22. If I remember correctly, I did that at template level, I can check that later (not at computer now). For all you interested in e-commerce and pw: I am working on new set of modules to create really robust base for pw e-commerce. Some of the modules will be open sourced (like general payments modules, stripe is already done, released soon) and some will be commercial. I hope to release these this summer, along with full featured shop profile. Currently working on paid downloads and tax support. Thanks for Nico for "pushing" me to build this, it's looking very promising so far.
    1 point
  23. @muzzer jsPDF library can handle floating divs and images pretty well. I set up a quick and dirty test page at http://jspdf.webseiten-fuer-alle.de/ Underneath "Choose examples" select the last one "** NEW addHTML()" and you'll instantly see the result. For floating divs with mpdf have a read here: http://mpdf1.com/manual/index.php?tid=385 As far as I understand it in your example the text wrapping the div also needs to be wrapped with float and width (but then it won't wrap the div anymore).
    1 point
  24. 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
  25. Thanks Nico, we are planning to release a beta version soon. Hello guys! It's been a few days since the last update - so I'd really like to tell you about two important additional features of PassiveCron and cron.pw. 1. Enable or disable PassiveCron per Module We hope that module developers will adapt PassiveCron's task handling to improve all ProcessWire sites' speed. But at the same time, we want the user to keep control over the tasks that are able to run in the background. So right from the module's settings page, the user can en- or disable background task handling per module. 2. minimize.pw When PassiveCron launches, we will enhance ProcessImageMinimize / minimize.pw to adapt PassiveCron. This will increase the performance of minimizing one site's images even further. At the same time, this will allow minimize.pw to minimize images even with Pro Cache turned on. Best of all: ProcessImageMinimize's background tasks won't reduce your daily tasks limit! We are very excited about PassiveCron. We are looking forward to share a few screenshots with you in the next update! Thanks and stay tuned! Marvin
    1 point
  26. Dear Horst, Thanks for this tip. I had read the post by Hari, and Ryan's response. It seems to me that the reconnect to mysql code would come in handy, but it also seemed that it was meant for situations where there was quite a lag between commands, like with thousands of records being processed. In my case, it was happening with load balancer hits against the index page. Also, my version of PW didn't have the file 'WireDatabasePDO.php'. It just had Database.php. But... your post, and Hari's comment on the GitHub page, https://github.com/ryancramerdesign/ProcessWire/pull/366, stimulated my little grey cells, so I went and looked at the wait_timeout value. It was set to 30 seconds, and the load balancer checks every 30 seconds, so I thought that might it. So I raised the value to 300 seconds. I'm hoping that will fix it. Crossing my fingers. Thanks for your help! Peter
    1 point
  27. Hello Peter, PW 2.3.0 uses PDO and it seems that with some server configurations this can happen. There is a fix from Hari KT, that I have used instead of the existing WireDatabasePDO.php in a PW 2.3.5 Installation. And since then I haven't had that (rare) error anymore. Ryan already has included it into the current Dev Branch (PW 2.4.1), too. Maybe you like to try it. WireDatabasePDO.zip
    1 point
  28. Yes it is working well. I have a site on a shared host where I have got sometimes this "2006 Server has gone away" error, especially when the client was working in the admin with large pagelists (he wants to have the default limit of 50 increased to 200). But this wasn't the only time when this happens. Now after update it with your patch I think we have to wait a week or two to be really sure it is solved. But actually I think yes it will be!
    1 point
  29. Many thanks. Have installed it.
    1 point
  30. Doh... Solved my own problem.... Changed this... foreach($page->comments as $comment) To this... foreach($comments as $comment) Sorry for diverting you here... but thanks for looking! Here is what I have ended up with... // DISPLAY PAGINATED COMMENTS $limit = 10; // comments to display per page $start = ($input->pageNum-1) * $limit; $selector = "page=$page, sort=-created, start=$start, limit=" . ($limit+1); // find the comments. replace "comments" with the name of your comments field $comments = FieldtypeComments::findComments("comments", $selector); // output the comments foreach($comments as $comment) { if($comment->status < 1) continue; // skip unapproved or spam comments $cite = htmlentities($comment->cite); // make sure output is entity encoded $text = htmlentities($comment->text); $date = date('m/d/y g:ia', $comment->created); // format the date echo "<p>Posted by $cite on $date<br />$text</p>"; } // output the pagination links if($input->pageNum > 1) echo "<a href='./page" . ($input->pageNum-1) . "'>Back</a> "; if(count($comments) > $limit) echo "<a href='./page" . ($input->pageNum+1) . "'>Next</a>"; Thanks guys
    1 point
  31. Was this taken any further as I am interested in how to clone/copy pages? Sorry, I have just found the module for this here.
    1 point
  32. digitex, look at the markup and you see a somewhat 2 dimensional list. That's always done using nested foreachs. foreach( $pages->get("/someparent/")->children() as $pa ) { // $pa is the page echo "<h2>$pa->title</h2>"; echo "<ul>"; // cycle the repeater field as if they are pages (they are) foreach( $pa->repeaterfield as $rp ) { echo "<li>$rp->info</li>"; } echo "</ul>"; }
    1 point
×
×
  • Create New...