Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/25/2022 in all areas

  1. You can create a field stack_prices as a repeater field with three subfields: repeater_product_quantity (integer), repeater_product_stackprice (float) and repeater_product_shipping (float) Add this field to your product-template. Then, on your product page, before you render the add-to-cart button with ___renderBuyButton() you can format these values like so: if ($page->stack_prices != '') : $product->stack_prices = array(); $i = 0; foreach ($page->stack_prices as $sp) : $pricing = array( 'qu' => $sp->repeater_product_quantity, 'sp' => $sp->repeater_product_stackprice, 'sh' => $sp->repeater_product_shipping ); $product->stack_prices[$i] = $pricing; $i++; endforeach; endif; and then send it to the function: echo $kiosk->___renderBuyButton($product); I want to include this field in the module to be created upon installation soon.
    3 points
  2. That's true. The added description and details help a lot. When I looked into this thread there wasn't that much happening. A short intro and a link... which didn't help that much.
    2 points
  3. Here's a fun one this morning. I normally set a custom logo in the admin masthead using the settings in the AdminThemeUikit module (mostly so I know which site I'm in when I've got serveral open at the same time). Today I mistyped the logo name when I was setting this for a site so the logo didn't load. But then when I logged out and tried to log in again I got the dreaded red screen of death. After checking all the usual suspects (file permissions, disc space etc) I renamed the logo file to match my misspelled setting and Bob's your uncle, I can log in again. If I delete the logo file the CSFR error comes back, replace it and it's all good. This only happens in debug mode so my guess is that there's some PHP warning message that's mucking up some javascript but I've not managed to find it yet. I'll log it as a bug on GitHub but thought I'd stick it up here cos it's the kind of bug that could have ages to find and I'm feeling smug that I got it quickly (so no one tell me it's a known bug and I could have just Googled it).
    1 point
  4. I hope that you all are having a great week! This week I've been working on some updates to the User Activity module and have released version 5 in the ProDevTools board. This version focuses on adding several new requested features, including the following: New options to also detect when you (yourself) are editing the same page in 2+ windows and when you have modified a page in a different window. These are the “collide-self” and “modify-self” options in module config. The module now keeps track of what fields have changed in the page editor and stores them with the activity so that they can be shown in the activity viewer or in page edit alerts. When a page has been modified that is also open to another user it now presents them with a dialog giving the option to reload the page or keep editing. A new “lock” option has been added that blocks a user from editing a page when it is already being edited by another. This is an alternative to just warning them with a pop-up, and it literally prevents them from being able to open the page in the page editor. This can be enabled in the module config and can also be optionally disabled for superuser. A new configuration setting has been added that lets you configure the refresh time in the page list (previously it was not editable). Added feature to limit the “you've been idle for awhile…” to the page editor only. When enabled, idle is still tracked for other admin processes, but idle alerts don't appear. Improvements to ProcessUserActivity (the included activity viewer module), including: 1) visible vs. hidden states are now more obvious. 2) Changes made in page editor are now included in the activity information. 3) The ajax drop-down navigation summary has been improved to include more information. Large portions of the module have been refactored into separate classes for better maintainability and other related improvements. This week there have also been a few commits to the core, but mostly just small fixes and phpdoc improvements, so not enough to write about here, but there likely will be next week. Thanks for reading and have a great weekend!
    1 point
  5. I'm working on a one-page, vanilla javascript and php (PW API) shopping checkout module that integrates PayPal server side. Here's version 1.0 https://github.com/dtjngl/kiosk Looking forward to your feedback! DISCLAIMER this is a BETA version at best, it's my first "real" module I'm writing for ProcessWire (and first module I'm writing at all) so please don't eat me alive. I'm aware that it needs a lot of work, but at this point, but it's functional. I'm also aware that it is not very customisable at this point (it's mostly customised for one specific use case), but I promise I will work on that. My main objective is to get more seasoned developers' mentoring, feedback, advice, warnings – and and of course, if you want to look into or help develop it further – pull requests. Please point out any potential dangers you see or anything that raises a red flag for you. I'm learning so much from that. Though the module is held in german, you can translate almost all strings that are in the php files via PW's translate functionality. I cannot help with the strings in the javascript yet, but will do so soon (using a json file that lives on the file system probably). I started working on this module because many checkout systems out there are either overkill and too complicated, didn't fulfil my needs or come with a premium fee that is not worth it. Also, austrian law (and other countries' jurisdiction) demand a different flow than what PayPal's Express checkout offers. So this version makes calls to PayPal on the server. WHAT IT CONTAINS - OnePage checkout system with 4 steps: cart, address(es) form, payment method (paypal and deferred), order overview - "minicart" (the cart-summary in the page's header) - buy button (to add items to the cart) - a dashboard (with admin template) for an overview of all placed orders uses server session storage and browser localstorage REQUIRED WireMail SMTP UIKIT (for best behaviour, will be optional soon) vanilla Javascript (no jQuery required) PHP (DUHDOY!) ProcessWire Version (not sure, but works with version 3.0.200) if you want it in english you need a multi-language installation PayPal Business Account (Live or Sandbox to test with) HOW TO INSTALL 1. Put the folder "Kiosk" in your ProcessWire site's modules folder 2. Install the module Kiosk, this will… - create fields for the order template - create a template for the orders placed - create a template for the orders' parent page - create a parent page "Custom Orders" for all orders under /admin/page/ (you can rename the page, not the template) - create a template "kiosk_checkout" for the checkout page - create a page "Checkout" for the checkout, child to "Home" (you can move the page, you can rename the page, not the template) - install module ProcessKiosk along with it - ProcessKiosk create a page under /admin/ (visible in the module upon creation). Here you will see a table with all the orders placed. 3. check the Kiosk module's settings page (navigate via the module's overview page) and enter details to your best knowledge. Some are not "required" but they actually are. 4. Put the below code (in essence) on "kiosk_checkout.php": if ($config->ajax) { $kiosk->handleAJAX($input); return $this->halt(); } else { $kiosk->handleStaticContent($input); echo $kiosk->renderCheckoutSteps(); } 5. put this line on a page that loads everywhere, preferably on init.php: $kiosk = $modules->get('Kiosk') 6. put this line where you want the "minicart" and toggling cart preview (provided the site runs UIKIT) to be, probably in a header that renders on each page: echo $kiosk->renderMiniCart(); 7. put this line just above you closing tag: echo $kiosk->addScripts(); HOW DOES THIS THE ORDERING WORK? 1. Add items to the cart or update quantity when viewing the cart, continue with "weiter". 2. Enter your address, if your billing address differs, uncheck the "gleiche Rechnungsadresse" and enter the billing address, checked or unchecked, both forms will be sent to the server but handled accordingly, continue with "weiter" 3. Select a payment method, continue with "weiter" 4. formdata object (containing cart items, address(es), payment method) will be sent via AJAX to the server and stored in the server session variable 5.1. if payment method is deferred - AJAX response contains the order summary markup that will render in step4 - don't forget to check " ich habe die Datenschutzerklärung sowie die AGB zur Kenntnis genommen und akzeptiere diese." (privacy policy and terms and conditions) - click on "Zahlungspflichtig bestellen" will send another AJAX request to the server thus submitting the order (continue to WHAT HAPPENS WHEN AN ORDER IS PLACED?) 5.2. if it's paypal, a bit more is happening - server sends a cURL request to paypal containing client ID and secret - response will send a token - server sends that token along with the purchase unit (created from our placed order) in another cURL request to paypal - response will send an "approve"-URL - AJAX response contains that URL - user is redirected to paypal to approve the order - user is redirected to the "checkout" page along with a token and PayerID as GET parameters - token (not needed actually) and PayerID are stored in the server session - with the PayerID in the session variable and the "status" of the paypal approved order in the localstorage the checkout process will head on to step 4: order summary - don't forget to check " ich habe die Datenschutzerklärung sowie die AGB zur Kenntnis genommen und akzeptiere diese." (privacy policy and terms and conditions) - clicking on "Zahlungspflichtig bestellen" will send another AJAX request to the server - second AJAX request will send PayPalAccessToken, PayPalPayerId and PayPalRequestId in another cURL to PayPal which will trigger the payment - response will… continue to WHAT HAPPENS WHEN AN ORDER IS PLACED? WHAT HAPPENS WHEN AN ORDER IS PLACED? an order-page with all the order's details (plus order number from the kiosk's number circle) is created under /admin/page/custom_orders/ (you can find it in the Kiosk Dashboard) number circle is iterated email markup is created using the module's default email template, you can add a path to a custom template in the module's settings email is sent to the site master and the user (check the module's settings for email addresses etc.) order in server session is reset to an empty array paypal session in server session is reset to an empty array localstorage of the browser is deleted user is redirected to a custom url (defined in the module's settings) HOW ARE PRICES HANDLED? prices allow for a stack price functionality. This means that prices and shipping depend on the quantity of items purchased. You can enter different prices and shipping costs for different quantities. If a user's amount of a selected item reaches the specified stack price, the item price and the shipping costs change. HOW ARE PRODUCTS ADDED TO THE CART? a product should be a page object to keep things simple. That page needs an "images" array field (that very name). Below you can see what a product would need. These values are added to the button's data attributes. // This is how you make a product… $product = new WireArray(); $product->id = $page->id; $product->title = $page->title; $product->source = $page->parent->name; $product->url = $page->url; $product->images = $page->images; $product->product_width = 150 // for proportional item image calculation in the cart $product->taxrate = 10 // or what ever the tax rate $product->stack_prices = array( array( "qu" => 1, "sp" => 19.99, "sh" => 5 ), array( "qu" => 10, "sp" => 14.99, "sh" => 0 ), ); $product->stack_prices = htmlspecialchars(json_encode($product->stack_prices)); // then render the "add to cart" button $kiosk->renderBuyButton($product); UPDATE version 1.1: installing kiosk.module will also create a repeater field "kiosk_product_stack_prices" (including 3 subfields as described above) that handles the stack_prices array of arrays (as described above) so you can use the GUI. create a field "kiosk_product_tax_rate" create a field "kiosk_product_width " create a field "images" if there is none in your system. create a template "kiosk_product" with all these mentioned fields use this template for your products (or the fields thereon at least and add to your template of choice) and you should be good to go. CAUTION! If you uninstall kiosk.module it will delete all pages with template "kiosk_product", that's because I'm still figuring out how to detach the fields and fieldgroups without deleting the template. Also, if you're coming from version 1.0 and want to upgrade, please uninstall it in 1.0 first and only then get the new repo (v1.1) to install again. Class kiosk now provides the following hookable methods: ___renderBuyButton(Page $product, (string) 'add to cart') pass a product (preferably with template kiosk_product) and it returns a buybutton with the price for 1 item. This method now accepts the button's label (string) as a second argument. Method is hookable. ___getSpecificStackPrice(Page $product, (int) 5) // 5 is just an example pass a product (preferably with template kiosk_product) and an amount, it returns the price for that amount of items. Method is hookable. ___getSinglePrice(Page $product) pass a product (preferably with template kiosk_product) and it returns the price for 1 item. Method is hookable. So, use template "kiosk_product" for your products, edit the product page to add details, and then do echo $kiosk->renderBuyButton($product, (string) 'add to cart'); to render an "add to cart" button.
    1 point
  6. 404 seems strange to me ? normally you would get a 500 if something is wrong with your PW installation. I would try if XAMPP and your setup is working properly by just creating a simple index.html file in your folder and open it in the browser. Personally I've switched from XAMPP to Laragon, which is much more easier to setup.
    1 point
  7. Yeah, later on I realized that I had been a little bit late to the party...
    1 point
  8. wire('pages')->get('template=template_custom_orders')->delete() uses $pages->get(), which means that it will include pages that are either in trash, or unpublished/hidden. Meanwhile this part... $tcos = pages('template=template_custom_order'); foreach ($tcos as $tco) : $tco->delete(); endforeach; ... will only find non-trashed public pages. One thing to check is that it matches every possible page: $tcos = pages('template=template_custom_order, include=all'); foreach ($tcos as $tco) : $tco->delete(); endforeach; BUT that being said, there's potentially an even easier method: wire('pages')->get('template=template_custom_orders')->delete(true); If you pass "true" to the delete method, it will automatically (attempt to) remove child pages.
    1 point
  9. $rockmigrations->deletePage("/yourpage"); https://github.com/baumrock/RockMigrations/blob/2db2e74407a663150dbc2f423662b287b59d7919/RockMigrations.module.php#L976
    1 point
  10. this installation's paypal function is not working currently though, had to re-install it, there's a bug I'm trying to fix.
    1 point
  11. I'm not sure what the reason for the ID limitation is, but you could set the value of each option to the integer you want:
    1 point
  12. Here's a test installation for you to get a look and feel http://kiosk.datajungle.xyz/shop/ I will provide access to the admin soon so you can view the kiosk settings page, kiosk dashboard and some of the page tree.
    1 point
  13. Hi, sounds like you want this: (only without the negating “!” in your case)
    1 point
  14. First I need... You're an hour ahead of me in France ?
    1 point
  15. To try it, you can just create a dummy page with page's name `hello` and paste the whole code in `ready.php` ?
    1 point
  16. Thanks @flydev ?? this is awesome. I've not even had a chance to try it out yet but I can see I had previously been doing something wrong... /// change the button's label (attribute: value) $submit->attr("value", "Foobar"); Had been trying to target 'label' rather than button value... duh! Probably led me down a blind alley from the get go!
    1 point
  17. Hi @wbmnfktr thanks for your message, I thought "checkout" is a term that speaks for itself. It's meant to be a shopping cart checkout and it doesn't use any third party software except for PayPal (for now). I edited my initial post, which is pretty much the readme.md file on github.
    1 point
  18. I've started with this guide as well, so thx a lot again for sharing that @gebeer but I want to mention that for anybody interested in automatic deployments RockMigrations ships with a ready-made deployment solution that you can use: https://github.com/baumrock/RockMigrations#deployments
    1 point
  19. Woah... there are a lot of moving parts here. First of all: It always takes way longer than anyone expected it would take. I have seen super simple and minimal projects taking weeks instead of days. Yet I've seen quite large and complex projects that took only a few weeks instead of months. In average the PHP/PW part is most of the time the smallest part within a project that's just dealing with content at least in my projects. It can be tricky when you have to deal with lots of data from different sources, especially when you do more than just displaying that data. Most time and energy in my projects go into: Planning out the whole project Designing each and every bit Content audit, creation, and optimisation Frontendwork HTML, CSS, JS Right after that ProcessWire comes into play with these parts: Templates and fields Site structure, setting up basic pages Modules and global settings Backend logic, data automation, cron/lazycron jobs, automated maintenance On average I'd say it's a 70/30 ratio between those two. To get you some numbers here: We talk about at least a few weeks and maybe even months in total with all kinds of related things like meetings, phone calls, organizing, setting up Google and other tools, like tracking tools, newsletter, etc. To make things clear and a bit more transparent, we talk about projects and websites like these: https://www.restaurant-blechnapf.de/ https://www.klippo-nms.de/ https://www.musikschule-neumuenster.de/ In comparison to the above there are projects I built in my spare time without a lot of planning or almost anything - which took a few hours or maybe two days in total. Like these: https://www.jet-fire.de/ https://www.voss-friseure.de/ The main difference is that the first 3 projects are totally custom and fully optimized, multiple user accounts, access rights, automation and maintenance and design-wise on a totally different level. While the last two use UIKIT or Bootstrap, just display simple content and aren't that well optimized to be honest. Last but not least there are projects like this: https://www.restaurants-neumuenster.de/ It started with a simple splash page, a simlpe form and a bit of content and went online within a few hours. Yet as of today there are several hundred hours of work in it. Quite a bit design (had a few relaunches in the past) but way more in terms of data processing, automation, newsletters and lot's of nice things. TL;DR From about 2 days to a couple of months.
    1 point
  20. I hope you are having a great week. Today I've released new versions of two ProcessWire ProFields modules: Table and Combo. In addition to various minor improvements and fixes, the biggest update in both is the addition of file and image fields. Since this is a fairly major feature addition for both modules, please consider these versions in a beta test stage for the moment. Both are available for download in the ProFields board now. Table v23 In ProFields Table both "file" and "image" column types were added. These are fairly basic file upload fields, but a major improvement over not having them at all. It can hold one file per column per row in the table. You can have as many file columns as you need per row. The front-end value of your file or image columns is one you are likely used to using already: Pagefile or Pageimage objects, just like they would be in a regular single-file or image field. This means your file/image values in your Table rows can benefit from many of the built-in methods you already use, such as the ability to present resized images, WebP variations, etc. When you configure a file column you can specify what extensions you want to allow and the maximum number of bytes you are willing for it to accept in an upload. When configuring an image column, you also gain settings to specify the thumbnail image preview size in both regular and HiDPI resolution. Combo v9 The update for Combo fields was similar to the Table field except that file and image fields go quite a bit further in Combo than they could in Table. Specifically, you get almost the full set of InputfieldFile/InputfieldImage configuration settings and features, including the ability to support both single and multi-file uploads, image actions, variations, focus control, description input, tags input and more. The only things missing relative to a regular File/Image field are the manual Crop action (Image field) and the ability to manage separate custom fields for each file or image. The front-end value for your Combo file fields is identical to what it would be on a regular ProcessWire File or Image field. Specifically a Pagefiles or Pageimages (plural) object if supporting multiple files, or a Pagefile or Pageimage (singular) object if supporting 1 file. To say it another way, you can use this exactly as you use other dedicated file/image fields in ProcessWire. Not yet included is the ability to query the properties of a file/image field from selectors, like when using $pages->find(). I'm still working on that part, but since I know most probably don't need that I decided to get this version out first and then continue working on that part. Core updates The core updates this week were mostly minor, even if there were a lot of them. One of the ways that I stay up-to-speed on all the core code is to regularly read through all of it and make small adjustments along the way... anything that makes the code easier to read, or easier for PhpStorm to inspect it. You've seen these kinds of updates pretty much every week for years, but I hadn't thought to mention it before. This week there were more of these kinds of updates than usual so I just wanted to mention that what it's for. What sometimes looks like micro-optimization or minor code changes is usually just me staying fresh and up-to-date with the core. ? That's all for this week. I hope you have a great weekend!
    1 point
  21. Probably my method is in the dinosaur category, but it still works without spending too much time on migrating a database: If I do not mix up production with local then it is fool proof. It takes less than 15 secs from start to finish to clone a small database including all the keystrokes I have to perform at the beginning. Sure, it is the other way round regarding migrating, but for a one man show it is not a big deal. When modifying settings in production, I sometimes have to do the cloning more than once but since the whole process is so fast, for me it is a non-issue. "I am still waiting" for an official automated migrating solution included in the ProcessWire core :P
    1 point
  22. Hey @adrian! Just a heads-up that I posted an updated and extended version of my code as a new add-on module: The functionality seemed pretty specific to one use case so I figured it was best not to bundle it in the main module, but feel free to use anything from my module if it makes sense to you. Turns out that the original implementation missed a few key points and was very specific to a particular site, so this is basically a full rewrite... ?
    1 point
×
×
  • Create New...