Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Gadgetto

  1. OK, here is the simplified code for testing in site/ready.php with "title" field used: // To test, add this to your sites/ready.php wire()->addHookAfter('Pages::added', 'presetTitleField', ['priority' => 99]); wire()->addHookAfter('Pages::saveReady', 'checkTitleUnique'); function presetTitleField(HookEvent $event) { $page = $event->arguments(0); $page->setAndSave('title', 'Test' . $page->id); } function checkTitleUnique(HookEvent $event) { $page = $event->arguments(0); $field = $page->getField('title'); $title = $page->title; if ($page->isChanged('title')) { $exists = wire('pages')->get("title=$title"); if ($exists->id) { // value is not unique! $error = __('Title must be unique'); $exception = sprintf( __('Title [%s] is already in use'), $title ); $inputfield = $page->getInputfield($field); $inputfield->error($error); throw new WireException($exception); // Prevent saving of non-unique value! } } } And thanks for the hint to extend the Page class with a new method!
  2. Thanks @bernhard, before I asked for help here, I searched for related information back and forth but couldn't find any relevant infos. The search results from your screenshot also didn't bring any light into this... 🙂
  3. This looks promising! Thank you. The problem is, I can't use this new class in my module as the PW version requirement is set to 3.0.148. I could borrow the code from this class and build my own method. This would require to rewrite a lot of code instead of getting the hooks working properly.
  4. Yes, I know this field type, but I don’t want to use third party modules in my module.
  5. Hi there, I'd like to prevent duplicate values in a specific page field (FieldtypeText) across all pages. The hook should also prevent saving of the page if a duplicate value is detected. Therefore I created two hook methods but I can't get it to work properly. Here are both hooks placed in init() method of an autoloader module: The first hook is to initially preset the field with the page id. The field value can be customized by the admin before saving. The second hook should check if the value is unique. If I create a new page and try to save, the WireException is already triggered in first step of page creation, where you enter the page title: SKU [] is already in use If I check the value of $sku (with Tracy) it's always empty! Any idea what could be wrong? EDIT: if I remove the second hook, the field value is correctly preset with the page id! $this->addHookAfter('Pages::added', $this, 'presetProductFields', ['priority' => 99]); $this->addHookAfter('Pages::saveReady', $this, 'checkSKUUnique', ['priority' => 101]); And this are the hook methods: public function presetProductFields(HookEvent $event) { $snipwire = $this->wire('snipwire'); if (!$snipwire) return; $page = $event->arguments(0); if ($snipwire->isProductTemplate($page->template)) { if ($page->hasfield('snipcart_item_id')) $page->setAndSave('snipcart_item_id', $page->id); } } /** * Check if the SKU value is unique across all product pages. * (Method triggered after Pages saveReady -> just before page is saved) * * @throws WireException * */ public function checkSKUUnique(HookEvent $event) { $snipwire = $this->wire('snipwire'); if (!$snipwire) return; $page = $event->arguments(0); if ($snipwire->isProductTemplate($page->template)) { $field = $page->getField('snipcart_item_id'); $sku = $page->snipcart_item_id; // SKU field value bd($sku); if ($page->isChanged('snipcart_item_id')) { $exists = $this->wire('pages')->get("snipcart_item_id=$sku"); if ($exists->id) { // value is not unique! $error = $this->_('SKU must be unique'); $exception = sprintf( $this->_('SKU [%s] is already in use'), $sku ); $inputfield = $page->getInputfield($field); $inputfield->error($error); throw new WireException($exception); // Prevent saving of non-unique value! } } } }
  6. Nova definitely supports language server protocol and comes with a bunch of predefined languages! The built in PHP extension is a bit rudimentary (like in VSCode) but there will be IntelliSense extensions available.
  7. Hey there, hope you are all well! I would like to introduce Nova from Panic.inc, a new IDE and code editor for web developers. The application is developed natively for macOS and is the successor of Coda 2 (if you know it). I'm sitting here in my home office (because of Corona) and yesterday I got the invitation for the beta. Now I have been testing Nova for about 1 day. The application is incredibly fast! I haven't used anything comparable so far (including VSCode). The user interface is very clean and skinnable. Here is a small excerpt of the already integrated features (which of course can be extended by plugins): - Project management - Integrated Remote Publishing - Integrated Git Handling (Push, Pull, Commit, etc...) - Integrated Code Completion (PHP, JavaScript, ...) - Full featured integrated remote file browser for all thinkable protocols - Integrated web preview - Integrated console (local and remote) - Tasks (this seems to be huge! I'm telling you more when I figured out what this can do) - etc... This will definitely be my IDE for the next years! Nova is currently in closed beta. No new tester are accepted. But should be in open beta in the next few weeks! Have a nice week and stay healthy! Greetings, Martin
  8. Hi @creativejay, do you still have this issue? If so, could you please file an issue in SnipWires GitHub repo and provide more information: https://github.com/gadgetto/SnipWire/issues I could not reproduce this problem but I think I have too little information.
  9. UPDATE 2020-03-21 SnipWire 0.8.5 (beta) released! This update improves SnipWires webhooks interface and provides some other fixes and additions: Catch module settings access for non super users Fixes [#2] Dashboard not accessible for non SuperUsers Added documentation (php comments) to Webhooks class and hookable event handler methods All Webhooks event handler methods now have a return value (Snipcart payload) Hookable event handler methods: All hookable event handler methods will return an array containing payload Snipcart sent to your endpoint. In addition the following class properties will be set: $this->payload (The payload Snipcart sent to your endpoint) $this->responseStatus (The response status your endpoint sent to Snipcart) $this->responseBody (The response body your endpoint sent to Snipcart) (Use the appropriate getter methods to receive these values!) How to use the hookable event handler methods (sample): $webhooks->addHookAfter('handleOrderCompleted', function($event) { $payload = $event->return; //... your code here ... }); PLEASE NOTE: those hooks will currently only work when placed in init.php or init() or ready() module methods!
  10. Just placed the hook in init.php and now it all works! This is mysterious ...
  11. Good hint with Tracy log()! But I don't understand what you tried to say: You say everything works like expected but then the hook in ready() isn't triggered. So you are having the same problem as I do?
  12. I have written a small test module which simulates the required situation. Unfortunately the hook mentioned above does not work here either. I think I'll file an issue on GitHub. Here is a ZIP with the module files: HookTest.zip
  13. I'll try to write a small test case. Thanks again @bernhard!
  14. Could this be a bug in PW or is it intentional? Should I file an issue? Any ideas from the other pros here? I'm really stuck with this. 😞
  15. Just stumbled across this older post and I want to say: IMHO this is the simplest/best explanation for registering / executing hooks! Thanks! This is also a problem for me when I try to post more complex questions in the forum. I'm often not understood.
  16. If this is the real reason, I don't know how to solve this, as process() needs to be called by a hook. 😵
  17. Changed to a static method call - still not working... 🤯 I'm just thinking it could be a problem that the process() method (which calls the hook method dynamically) itself is also triggered by a hook? public function init() { ... $this->addHookBefore('ProcessPageView::execute', $this, 'checkWebhookRequest'); ... } /** * Check for webohook request and process them. * (Method triggered before ProcessPageView execute) * */ public function checkWebhookRequest(HookEvent $event) { if ($webhooksEndpoint = $this->get('webhooks_endpoint')) { if ($this->sanitizer->url($this->input->url) == $webhooksEndpoint) { $this->wire('webhooks')->process(); $event->replace = true; // @note: Tracy Debug won't work from here on as normal page rendering is omitted! } } }
  18. Are you sure? Maybe I don't understand this correctly... It seems a new method is only added if the specified method name doesn't exist. From the docs: --- You can add new methods to any ProcessWire class in the same way that you would hook an existing method. The only difference is that the method doesn't already exist, so you are adding it. Also, because there is no distinction of "before" or "after" for something that doesn't already exist, you can attach the method using addHook(); rather than addHookBefore(); or addHookAfter() … though technically it doesn't really matter what you use here. Lets say that you wanted to add a new method to all Page instances that outputs a relative time string of when the page was last modified (for example, "45 minutes ago" or "3 days ago", etc.): public function init() { $this->addHook('Page::lastModified', $this, 'lastModified'); } public function lastModified($event) { $page = $event->object; $event->return = wireRelativeTimeStr($page->modified); } Hooking both before and after If you want your hook method to run both before and after a particular event occurs, you can specify that in an $options array to the addHook() call, like this: $wire->addHook('Class::method', function(HookEvent $e) { // ... }, [ 'before' => true, 'after' => true ]);
  19. I changed to addHookAfter but still doesn't work. (had this tried before without success) 🤔
  20. OK, If I call this manually in Tracy Console: $webhooks->handleOrderCompleted(); The hook is triggered! Shouldn't a dynamic method call trigger a hook event? $this->{$methodName}();
  21. I have this part in my ready.php $webhooks->addHook('handleOrderCompleted', function($event) { wire('log')->save('webhookstest', 'hook works'); }); But the log entry isn't written.
  22. This is strange! Why doesn't it work in my environment? None of the hooks I posted above is triggered.
  23. Hi @bernhard, thanks for jumping in! What does that do? The Webhooks class handles Snipcart's web hook events and provides hookable methods to attach custom code to those events. eg. orderCompleted, customerUpdated, ad so on ... A Snipcart webhook event is a POST request which is sent to your site by Snipcart. Each POST request holds json encoded data corresponding to the specific situation. e.g. A orderCompleted event POSTs the full order array to your site. The Webhooks class is available as custom API variable $webhooks. This code in SnipWire main module takes over POST request from Snipcart: /** * Check for webohook request and process them. * (Method triggered before ProcessPageView execute) * */ public function checkWebhookRequest(HookEvent $event) { if ($webhooksEndpoint = $this->get('webhooks_endpoint')) { if ($this->sanitizer->url($this->input->url) == $webhooksEndpoint) { $this->wire('webhooks')->process(); $event->replace = true; // @note: Tracy Debug won't work from here on as normal page rendering is omitted! } } } This line... $this->wire('webhooks')->process(); ... starts the process which handles a Snipcart POST request: https://github.com/gadgetto/SnipWire/blob/cc9922fbe059b3961d3ee63be253e34d4cf96bc1/services/Webhooks.php#L108 Within this processing the specific hookable method within the Webhooks class is called. I thought it should be easy to provide those methods a hookable. But it seems this isn't so easy with custom classes. For example - this doesn't work: $webhooks->addHook('handleOrderCompleted', function($event) { wire('log')->save('webhookstest', 'hook works'); }); and also not this: $webhooks->addHook('Webhooks::handleOrderCompleted', function($event) { wire('log')->save('webhookstest', 'hook works'); }); or this: $wire->addHook('Webhooks::handleOrderCompleted', function($event) { wire('log')->save('webhookstest', 'hook works'); });
  • Create New...