Jump to content

froot

Members
  • Posts

    720
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by froot

  1. I have new questions… Right now I have a separate Kiosk.config.php file that handles user provided settings on a settings page (accessible on the modules overview). I know for a fact that this is not mandatory, many modules have all in one page yet they still use a separate settings page. Anyways, let's keep in for now, it keeps things in order. My question is though, how do I properly access these settings? At the moment I do $kioskConfig = wire('modules')->getConfig('Kiosk'); inside the class. This seems verbose. Shouldn't something like $kioskConfig = $this->getConfig() work as well? (asking because it doesn't) Or would that indeed require to move the code from inside Kiosk.config.php over to the module's (main) class (I only use one class, I think that's normal). I can access the user provided settings info with the verbose version above but I guess I should define those settings as module properties? Because what I'm doing now is store it in a variable and repeat that in each method which is most likely not the right way. And where and how do I define these user provided settings (and other default ones maybe)? Do I use init()? or __construct()? I guess is a matter of taste of preference. However, I can seem to get it right. I tried with something like… public function init() { $kioskConfig = wire('modules')->getConfig('Kiosk'); $this->whatever = $kioskConfig->whatever; // doesn't work } I guess there's one underlying question that I need answered, how to access the modules config properly?
  2. OK thanks, yes better to anticipate the user mights change path or name of the processs page(s). However, when you say you cannot delete a page without id, why would I select pages WITH an ID to delete them? The initial problem was that I uninstalled the module which left a null page behind that was still visible in the admin menu but not deletable. Clicking on it would return an error "unkown path" or what ever.
  3. I spoke too soon, installing and uninstalling doesn't (yet) properly work. I created a module that extends class Process to create a little dashboard. I uninstalled the module for some reason and somehow it does half the job. I still have the dashboard's title in the above menu but it's an unknown path. Trying to delete it returns an error saying: Page (0) cannot be deleted: it is a NullPage Here's my code: public function ___uninstall() { // ... $dashboard = wire('pages')->get('/admin/kiosk_dashboard/'); if($dashboard){ $dashboard->delete(); } // ... } On a positive note, the fieldgroups don't seem to cause any issues anymore ^^
  4. can you return an admin page within a process module? Seems like that page is not accessible, any other page works fine with the same code but not a page with admin template under /admin/page/ If not, how can I do that?
  5. @Jan Romero thanks, exactly what I meant!
  6. another question, I'm saving some values in a field of type FieldtypeTextarea that lives on a custom page I create. Then I want to return that value in a table in a Process-module. I want line breaks for that value, so when I add the value I simply put <br> inbetween the lines but the Process-module doesn't know HTML so it just spits it out as is. So how do I do that? Is there a way to just tell the Process-module that this is HTML? Should I use a sanitizer? Or should I create a different type of field to begin with? If so, which type? Basically my question is, how to add HTML markup in a Process-module table?
  7. thanks @teppo for the input! I actually managed to get it to work the other day, some of what you mention here is what made the difference. - yes, the loop with ->count is of course nonsense, just a typo from copy-pasting - yes, I delete the fieldgroup somewhere later in the code - yes, it most likely needs to be ->childTemplates, ->childrenTemplates doesn't cause any issue, but not sure either if it actually works, so I'll change that - and lastly, thanks for the last tip, I was actually running into issues, something with "null page" cannot be deleted or whatever, so I did something with if($mypage->id>0) which is not so elegant and probably your suggestion will fix that. So, resuming, I can tell that this order works for me (not sure if others work but this one does)… ___install: 1. check if field exists and if not create field 2. check it template exists and if not create the fieldgroup, 3. add name to fieldgroup 4. add title-field to fieldgroup 5. add custom fields to fieldgroup 6. save the fieldgroup 7. create template 8. set the fieldgroup of the template 9. save template ___uninstall: 1. delete template(s) 2. delete fieldgroup(s) 3. delete field(s)
  8. Admitted, it's a working module without fieldgroups, but also without fields……
  9. I just removed all mentions of fieldgroups in my code, uninstalled all fields, templates and pages in the context of my module, emptied the trash, updated the PW version and then tried to reinstall my module and guess what… Template 'template_custom_orders' cannot be saved because it has no fieldgroup assigned So if you don't need fieldgroups to get started on modules, how can that be? So tired of this ?
  10. haha OK I see what you did there ? Just cause I succeeded to the point where I uninstall it doesn’t mean the installation went smoothly. Whichever order I create fields, fieldgroups and templates, or no fieldgroups at all, I always get some error mentioning fieldgroups, different maybe but never without. So I couldn’t care less about field groups but PW seems to insist on it despite of what everyone says. Either that or something else is fishy. Run my code if you want and tell me you don’t get an error like that.
  11. For my module I need a couple of templates and fields. These templates don't use a corresponding php template file because they don't need to be rendered in the frontend. The pages using these templates and fields are admin area only. I have another module which extends the Process-class that would list the contents of these pages in a table, but that's not relevant here I guess. Here's the full code so far… class Kiosk extends WireData implements Module, ConfigurableModule { public static function getModuleinfo() { return [ 'title' => 'Kiosk', 'summary' => 'Checkout System', 'author' => 'FRUID', 'version' => 1, ]; } public function ___install() { $fields = wire('fields'); $templates = wire('templates'); $fieldgroups = wire('fieldgroups'); // FIELDS if(!$fields->get('custom_order_id')) : $custom_order_id = new Field(); // int or text $custom_order_id->type = $this->modules->get("FieldtypeInteger"); $custom_order_id->title = 'Custom Order ID'; $custom_order_id->name = wire('sanitizer')->pageName($custom_order_id->title, true); $custom_order_id->label = 'Order ID'; $custom_order_id->tags = 'kiosk'; $custom_order_id->save(); endif; if(!$fields->get('custom_order_products')) : $custom_order_products = new Field(); $custom_order_products->type = $this->modules->get("FieldtypeTextarea"); $custom_order_products->title = 'Custom Order Products'; $custom_order_products->name = wire('sanitizer')->pageName($custom_order_products->title, true); $custom_order_products->label = 'Products'; // $custom_order_products->derefAsPage = 1; // $custom_order_products->parent_id = $this->user->parent->id; // $custom_order_products->labelFieldName = 'custom_order_products'; // $custom_order_products->inputfield = 'InputfieldSelect'; // $custom_order_products->required = 1; $custom_order_products->tags = 'kiosk'; $custom_order_products->save(); endif; if(!$fields->get('custom_order_customer_name')) : $custom_order_customer_name = new Field(); // text $custom_order_customer_name->type = $this->modules->get("FieldtypeText"); $custom_order_customer_name->title = 'Custom Order Customer Name'; $custom_order_customer_name->name = wire('sanitizer')->pageName($custom_order_customer_name->title, true); $custom_order_customer_name->label = 'Customer Name'; $custom_order_customer_name->tags = 'kiosk'; $custom_order_customer_name->save(); endif; if(!$fields->get('custom_order_customer_address')) : $custom_order_customer_address = new Field(); // text $custom_order_customer_address->type = $this->modules->get("FieldtypeTextarea"); $custom_order_customer_address->title = 'Custom Order Customer Address'; $custom_order_customer_address->name = wire('sanitizer')->pageName($custom_order_customer_address->title, true); $custom_order_customer_address->label = 'Customer Address'; $custom_order_customer_address->tags = 'kiosk'; $custom_order_customer_address->save(); endif; if(!$fields->get('custom_order_customer_emailaddress')) : $custom_order_customer_emailaddress = new Field(); // email $custom_order_customer_emailaddress->type = $this->modules->get("FieldtypeEmail"); $custom_order_customer_emailaddress->title = 'Custom Order Customer Emailaddress'; $custom_order_customer_emailaddress->name = wire('sanitizer')->pageName($custom_order_customer_emailaddress->title, true); $custom_order_customer_emailaddress->label = 'Customer Email Address'; $custom_order_customer_emailaddress->tags = 'kiosk'; $custom_order_customer_emailaddress->save(); endif; if(!$fields->get('custom_order_shipping')) : $custom_order_shipping = new Field(); // shipping $custom_order_shipping->type = $this->modules->get("FieldtypeText"); $custom_order_shipping->title = 'Custom Order Shipping'; $custom_order_shipping->name = wire('sanitizer')->pageName($custom_order_shipping->title, true); $custom_order_shipping->label = 'Shipping'; $custom_order_shipping->tags = 'kiosk'; $custom_order_shipping->save(); endif; if(!$fields->get('custom_order_total_taxes')) : $custom_order_totalTaxes = new Field(); // totaltaxes $custom_order_totalTaxes->type = $this->modules->get("FieldtypeText"); $custom_order_totalTaxes->title = 'Custom Order Total Taxes'; $custom_order_totalTaxes->name = wire('sanitizer')->pageName($custom_order_totalTaxes->title, true); $custom_order_totalTaxes->label = 'Total Taxes'; $custom_order_totalTaxes->tags = 'kiosk'; $custom_order_totalTaxes->save(); endif; if(!$fields->get('custom_order_total_and_shipping')) : $custom_order_totalAndShipping = new Field(); // Total and Shipping $custom_order_totalAndShipping->type = $this->modules->get("FieldtypeText"); $custom_order_totalAndShipping->title = 'Custom Order Total and Shipping'; $custom_order_totalAndShipping->name = wire('sanitizer')->pageName($custom_order_totalAndShipping->title, true); $custom_order_totalAndShipping->label = 'Total and Shipping'; $custom_order_totalAndShipping->tags = 'kiosk'; $custom_order_totalAndShipping->save(); endif; if(!$fields->get('custom_order_status')) : $custom_order_status = new Field(); // order status $custom_order_status->type = $this->modules->get("FieldtypeText"); $custom_order_status->title = 'Custom Order Status'; $custom_order_status->name = wire('sanitizer')->pageName($custom_order_status->title, true); $custom_order_status->label = 'Order Status'; $custom_order_status->tags = 'kiosk'; $custom_order_status->save(); endif; // FIELDGROUPS if(!$fieldgroups->get('fieldgroup_custom_orders')) : $fieldgroup_custom_orders = new Fieldgroup(); $fieldgroup_custom_orders->name = 'fieldgroup_custom_orders'; $fieldgroup_custom_orders->add($this->fields->get('title')); $fieldgroup_custom_orders->save(); $this->message('creating fieldgroup fieldgroup_custom_orders'); endif; if(!$fieldgroups->get('fieldgroup_custom_order')) : $fieldgroup_custom_order = new Fieldgroup(); $fieldgroup_custom_order->name = 'fieldgroup_custom_order'; $fieldgroup_custom_order->add($this->fields->get('title')); $fieldgroup_custom_order->add($custom_order_id); $fieldgroup_custom_order->add($custom_order_products); $fieldgroup_custom_order->add($custom_order_customer_name); $fieldgroup_custom_order->add($custom_order_customer_address); $fieldgroup_custom_order->add($custom_order_customer_emailaddress); $fieldgroup_custom_order->add($custom_order_shipping); $fieldgroup_custom_order->add($custom_order_totalTaxes); $fieldgroup_custom_order->add($custom_order_totalAndShipping); $fieldgroup_custom_order->add($custom_order_status); $fieldgroup_custom_order->save(); endif; // TEMPLATES if(!$templates->get('template_custom_orders')) : $template_custom_orders = new Template(); $template_custom_orders->name = 'template_custom_orders'; $template_custom_orders->fieldgroup = $fieldgroup_custom_orders; $template_custom_orders->pageLabelField = 'title'; $template_custom_orders->tags = 'kiosk'; $template_custom_orders->save(); endif; if(!$templates->get('template_custom_order')) : $template_custom_order = new Template(); $template_custom_order->name = 'template_custom_order'; $template_custom_order->fieldgroup = $fieldgroup_custom_order; $template_custom_order->pageLabelField = 'title'; $template_custom_order->parentTemplates = array($template_custom_orders->id); $template_custom_order->noChildren = 1; $template_custom_order->tags = 'kiosk'; $template_custom_order->save(); endif; $template_custom_orders->childrenTemplates = array($template_custom_order->id); $template_custom_orders->save(); $parent = wire('pages')->get('/admin/page/'); if ($parent->hasChildren('name=custom_orders') == false) : $c = new Page(); $c->parent = $parent; $template = templates()->get('template_custom_orders'); $c->template = $template; $c->title = 'Custom Orders'; $c->name = 'custom_orders'; $c->save(); endif; } /** * Optional method called when the module is uninstalled * * This method undoes anything that the install() method did. * For instance, remove installed DB tables, files, etc. * */ public function createCustomOrder() { // TODO } public function ___uninstall() { $fields = wire('fields'); $fieldgroups = wire('fieldgroups'); $templates = wire('templates'); $custom_order_pages = wire('pages')->find('template=template_custom_orders|template_custom_order')->count(); // if ($custom_order_pages > 0) // throw new WireException("There are pages using custom-order-templates. Remove those first before uninstall"); foreach($custom_order_pages as $custom_order_page){ $custom_order_page->delete(); } if($fields->get('custom_order_id')) : foreach ($fields->get('custom_order_id')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_products')) : foreach ($fields->get('custom_order_products')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_name')) : foreach ($fields->get('custom_order_customer_name')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_address')) : foreach ($fields->get('custom_order_customer_address')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_customer_emailaddress')) : foreach ($fields->get('custom_order_customer_emailaddress')->getFieldgroups() as $fieldgroup) { $fieldgroups->delete($fieldgroup); } endif; if($fields->get('custom_order_id')) $fields->delete($fields->get('custom_order_id')); if($fields->get('custom_order_products')) $fields->delete($fields->get('custom_order_products')); if($fields->get('custom_order_customer_name')) $fields->delete($fields->get('custom_order_customer_name')); if($fields->get('custom_order_customer_address')) $fields->delete($fields->get('custom_order_customer_address')); if($fields->get('custom_order_customer_emailaddress')) $fields->delete($fields->get('custom_order_customer_emailaddress')); if($fields->get('custom_order_shipping')) $fields->delete($fields->get('custom_order_shipping')); if($fields->get('custom_order_total_taxes')) $fields->delete($fields->get('custom_order_total_taxes')); if($fields->get('custom_order_status')) $fields->delete($fields->get('custom_order_status')); if($templates->get('template_custom_orders')) $templates->delete($templates->get('template_custom_orders')); if($templates->get('template_custom_order')) $templates->delete($templates->get('template_custom_order')); } }
  12. fair enough, but I'm sure PW has some sort of revenue that would benefit from a clearer documentation. Templates, fields and many more things are explained throroughly but fieldsgroups and many other things completely fall through. I know I'm not in the position to complain but it's frustrating when anything I develop requires me to start countless forum threads. I'm sure most developers here had to go through the same process of countless trial and errors and now they just know it. I disagree but maybe I'm just not experienced enough. And then, what's the relevant file regarding fieldgroups? I still don't get it. Do I absolutely need a third party module to get my first module to work?
  13. found in RockMigrations: You can edit your field or template and copy the code from there (I recommend to only copy the settings you need to make your migration files more readable): I don't get this sentence. What code of my fields and templates? copy from where? Are you implying that fields and templates are created with the PW API? So if I copy over the code that creates the fields and templates and put in the site/migrate.php file, my module's relevant code and files would be all over the place wouldn't it? I'm sure that can't be what this sentence means but then again no clue how else to read it. And then, again, what about fieldgroups, does RockMigrations take care of that "in the background"? Thanks for help!
  14. No offense but RockMigrations sounds like yet another API to learn to make things "easier". I still wonder why do I even need fieldgroups when almost all other modules don't use them. Anyways, I will look into it, but I still want to understand this fieldgroups stuff. As usual, I can find zero documentation on the subject, I can only reach out to the forum, if I google the error message all I get is the PW github repo where the error message is manifested in the first place. So do I attach the fieldgroup to the template or field? Do I first create the fieldgroup and then attach fields to it and then the template? Or what's the proper order? And what about uninstalling, what do I need to do first?
  15. why do I need fieldgroups?! I checked so many other modules where there's no mention of fieldgroups. But if I uncomment all lines that handle fieldgroups in my code it throws that error that I need a fieldgroup. Why is that? I never needed fieldsgroups, cannot make sense of fieldgroups and it's not well documented.
  16. However, second question… I read somewhere in the forum that you do NOT need fieldgroups when installing/constructing a module. However, when I create some fields and templates I get Template 'my_template' cannot be saved because it has no fieldgroup assigned I have not clue what that means.
  17. I'm working on a module, having troubles getting ___install() and ___uninstall() to work properly. First, how do I check if the fields exist? Because in order to get things right I need to install and uninstall back and forth a couple of times. But any time I install or uninstall it, there's another problem, so it just does half the job which messes up the next attempt, and so on. So from my first uninstall test, some fields weren't uninstalled, leaving a half installed module installed. So instead of uninstalling the fields manually, I want to add a condition that checks if the fields are already installed. Makes sense? Long story short, this doesn't work: $fields = $this->wire('fields'); // neither does $fields = wire('fields'); if(!$fields->get('my_field')) : $my_field = new Field(); // int or text $my_field->type = $this->modules->get("FieldtypeInteger"); $my_field->title = 'My Field'; $my_field->name = wire('sanitizer')->pageName($my_field->title, true); $my_field->label = 'My Field'; $my_field->tags = 'my_module'; $my_field->save(); endif; Why, I know not. Thoughts? EDIT: (SOLVED) OK my bad, this actually works, I'm just tired I guess.
  18. actually the biggest problem I'm facing right now is handling server and client sessions. First you would authorise an order with PayPal, so on the server you do a cURL request to PayPal and it returns a link. This link you pass to the client (I do that in an AJAX response) and when the user clicks on that link, they get redirected to PayPal to approve the order. That works fine when everything happens in the same browser tab, the server session is the same throughout all tabs. But what if for some reason the user opens that link in a new tab or window? That would be a new client session which messes up the whole logic. Is that a valid concern? How can I manage the client sessions for this issue not to happen?
  19. Thanks a lot for the feedback, it all makes sense. I am sure SnipCart is a good module in its own right, but for this client project that I have in mind, it's an overkill and not very suitable. Also, it's a Canadian company and hosted in Canada (?). So it seems like it's foremostly designed to work for American and Canadian standards, not so much for Austria and Germany. It also requires jQuery which is something I refrained from for the entire project (using Vanilla JS instead). So for this few functionalities that we actually need, it didn't make sense to not solve it locally and without jQuery. Moreover, my client despises any features that he doesn't absolutely need. That's why it felt like a good idea to build a custom solution. I thought how hard can it be when it doesn't need many functionalities (see above), it's almost like a contact form if you think about it. (To be fair, PayPal is also not local either but there's not much one can do about that.) At first I used the PayPal checkout express button which works like a charm, however, things changed around a bit. According to European law that PayPal Express Button is not compliant, you need to approve the order on the merchant's site, the button needs to have an exact wording and the user needs to see the order-overview before submitting. So yes, I totally understand that I was or actually still am underestimating the workload of coding my own solution. At first it was much less but with said juristic requirements the workload got more and now I'm pretty deep into it, wondering if I should push through or reconsider, hence my asking. But I can also see now that the suitable alternatives are not more than I thought after all.
  20. I had a feeling someone would bring that up. And then, what if I write my own custom solution, would that be wise?
  21. I need some basic checkout functionalities… - add to cart - change amount or delete - enter shipping/billing address - choose payment option (paypal or deferred payment) - see order overview with button "zahlungspflichtig bestellen" (required by Austria and German law) - submit order Also need adjustable layout. No fancy stuff like "customers also bought" or "last viewed items" or login functionalities or whatnot. What are the options in the PW-universe? What do you use? Don't suggest SnipCart though, I tried it before and it's overkill, and therefore it's not worth the price. Thanks for help!
  22. SOLVED! second post uses POST too, the comment where it says GET is a typo. Anyways, I think to have figured it out, as often, the problem is with the headers. It needs both: secondAJAXXHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); secondAJAXXHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); This seems so random to me, at least until I understand this headers stuff. That said, will that cause issues in different browsers, clients and whatnot?
  23. I need to make two separate AJAX calls method POST on the same template/page. Somehow the first one works fine but the second just won't send the data. Any ideas? // template file <?php namespace ProcessWire; if ($config->ajax) : $action = $input->post->action; $response = array(); if ($action == 'sendFormData') : // first ajax call uses POST method // some logic else : // second ajax call uses GET method // some logic $response['action'] = $action; echo json_encode($response); endif; return $this->halt(); else : ?> <div id="content"> HELLO WORLD </div> <?php endif; ?> // javascript file // first call sendFormData() // later secondAJAX() function sendFormData(formData) { var firstAJAXXHR = new XMLHttpRequest(); firstAJAXXHR.onreadystatechange = function () { if (firstAJAXXHR.readyState !== 4) return; if (firstAJAXXHR.status >= 200 && firstAJAXXHR.status < 300) { let response = firstAJAXXHR.responseText; response = JSON.parse(response); console.log('hello AJAX #1'); console.log(response.action); // sendFormData } }; firstAJAXXHR.open('POST', '', true); firstAJAXXHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); firstAJAXXHR.send(formData); } function secondAJAX() { var secondAJAXXHR = new XMLHttpRequest() secondAJAXXHR.onreadystatechange = function () { if (secondAJAXXHR.readyState !== 4) return; if (secondAJAXXHR.status >= 200 && secondAJAXXHR.status < 300) { let response2 = secondAJAXXHR.responseText response2 = JSON.parse(response2); console.log('hello AJAX #2') console.log(response2.action); // null but why? $%!#& } } // var request = {'action' : 'capturePayment'}; var request = 'action=sendEmail'; secondAJAXXHR.open('POST', '', true); secondAJAXXHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); secondAJAXXHR.send(request); }
  24. I'm having a weird issue, at least to me. Long story short: I cannot see the GET variables in the url (nor is it stored in $input->get) but I can see the url with GET variables in the Network-Developer-Tool. How come? Long story, if relevant: I'm currently implementing a paypal payment method on a project. For that, I'm using curl (as described on developer.paypal.com), so the request happens server-side. In a nutshell, it works like this: you send a curl "authentication" request to paypal paypal returns an token for authentication then you send another curl "create order" request to paypal along with the token paypal returns an array containing the "approve" link that link brings the user to paypal.com where they log in and approve the payment the user is then redirected to the site and PayerID and token are passed on as GET-variables (then I need to do some more coding to, finally, withdraw the amount due) So again, the issue now is, I don't see the GET variables in the url but they are present in the Network-Developer-Tool. Is that an issue related to PW? Something with how it handles the urls? .htaccess? Thanks for help!
  25. Though I understand that handling pages is still the easiest approach in PW, my requirements are actually pretty simple. Just a couple of things to be saved somewhere and displayed on an admin page. It doesn't need a dedicated url, no further interaction with the user, there are no user accounts that users login to and whatnot. The info is merely for the content manager. But anyways, when using pages, I would just do public function ___install() { $t = new Template(); $t->name = 'some_template'; // add some settings $t->save(); } and then public function ___uninstall() { $templates = wire('templates'); $templates->delete($templates->get('some_template')); } and that's it? Pretty much what you explained above with the GUI, only this time with the API.
×
×
  • Create New...