Jump to content

bernhard

Members
  • Posts

    6,629
  • Joined

  • Last visited

  • Days Won

    358

Everything posted by bernhard

  1. no clear all your unnecessary server and client cache+sessions+cookies etc related to that site and try it again.
  2. that's exactly why using tracy is so great, because now you know that the hook did not execute it's the same for me. don't know why it is not executed. maybe it's a bug, maybe we are using the conditional hook wrong. I didn't use conditional hooks for a long time and sometimes hooks with if-statements are even easier to read. so it's totally up to you which one you use.
  3. use tracy and debug $event: wire()->addHookBefore('Page(template=user)::changed(0:last_name, 1:first_name)', function($event) { bd($event); }); hookevents ($event) always have the object (class) and the arguments (parameters), in this case $event->object is the class ($page you are looking for) and ps: i prefer addHookAfter most of the time to be sure that the method itself does not overwrite the value again... don't know if that makes sense in your case but just wanted to point out that you have to take an eye on that. you see very well that $event->object = user, $event->arguments(0) = field name, (1) = old value, (2) = new value. it did only work for me like this: wire()->addHookBefore('Page(template=user)::changed(0:email)', function($event) { bd('user changed'); bd($event->arguments(0)); bd($event->arguments(1)); bd($event->arguments(2)); bd($event); }); id didn't work with multiple fields in the changed() part. don't know why. you can investigate this on your own with the help of tracy and some try&error.
  4. no, but saveReady belongs to the pages class, so the template condition won't work. You could use Page(template=user)::changed(0:first_name, 1:last_name) i guess... but saveReady hooks with an if statement are totally fine
  5. the if-statement is totally fine. you can also use conditional hooks: https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks don't think that there is a best practice or any performance difference between conditional hooks and if statements but that's just a wild guess...
  6. hi laps, i strongly recommend using tracy during development, then you can see instantly whats going on in most of the cases... $wire->addHookAfter('Pages::saveReady', function($event) { $page = $event->arguments('page'); bd('page title: ' . $page->title); }); just put this in your /site/ready.php and save any page you like and you'll see the output in your debug bar: just put it in your /site/ready.php file - you don't need to define anything else. Prepend and append files are for rendering the frontend.
  7. ... Of all hookable methods that are executed. So when you save a page you would see all methods you can hook into in the right order... Save, saveready, saved...
  8. That's not true and an unfair statement in this context. I agree that "no listed vulnerabilities" is no proof of security but it does also not mean that security is not a main goal. Security by obscurity definitely helps to protect us from lots of threats but it's definitely not the only and also not the most important part of the puzzle... https://processwire.com/docs/security/
  9. Thanks adrian. I've never really used the debug tools as I didn't find them really helpful. Maybe I'm missing something and just don't know how to use them properly? But what I wanted to achieve with the hookrecorder was some kind of execution plan of all hookable methods. A list where you can see which method get's called after the other. Ideally it would also show some additional information (like which page was saved, wich arguments where provided...). Maye it would also be possible to have some kind of nesting in it? The result could be something like this: ProcessPageView::execute ProcessPageView::ready ProcessPageEdit::buildForm (id=mypageid, ...) InputfieldWrapper::render (name=myfield, ...) Inputfield::render (name=myfield1, ...) Inputfield::render (name=myfield2, ...) Inputfield::render (name=myfield3, ...) ProcessPageView::finished I have no idea if that Execution Plan is correct... I'm quite familiar with hooking all around and looking for the right hook in the code but still I don't know exactly WHAT is going on WHEN. But looking on sime kind of list like above everybody would instantly get what is going on and would get a tremendously better understanding of how pw works. Then one could go further and look into the related class' code and inspect it. This list could also show additional info, as I already mentioned. And what I mean is on the one hand information about some variables what is currently happening (like which field is going to be rendered etc.) and on the other hand maybe it could list all hooks that are currently applied to this method (similar to the hooks list of the debug tools, listing hooks by priority so that you instantly get an idea of what is going on). I think such a tool would not only be of HUGE help for newbies but also for experienced devs. For example you could have a problem with some kind of pagesave actions... you have a hook that should change the page title to "myval" after every pagesave... Pages::save (id=123) execute hook from file /site/ready.php on line 12: collapsed hook code [...] $page->title = 'myval'; [...] Pages::saveReady (id=123) execute hook from file /site/modules/mymodule.module.php on line 240: [...] $page->title = 'my wrong value'; [...] Pages::saved (id=123) no hooks executed you would instantly see what's going on and that there is a conflicting saveReady hook overwriting the page title. I hope you get my point now. Or maybe I should start using XDebug and that's exactly what it is doing? PS: The list of hooks we have in the debug tools seems to be a list of all active hooks? And the sorting order is not helpful for me - it is even confusing... Is there any system in the order they are presented?
  10. Does anybody know how those security listings work? Where do they get the information? For example if one of my pw sites would get hacked, I would not tell those providers about it But another Idea just came up in my head... I'll have to think about it... Does anyone know a Linux Server Expert?
  11. Agreed, that's one reason why I'm working on this (where it will be possible to choose the local profile or to download one from a given URL):
  12. thanks @adrian very nice library! I've used google charts and chartjs in the past but it seems c3 has some very nice concepts as well. will have a look. @kongondo I guess you are working on a C3 module or are you really talking about D3 itself?
  13. I know what you meant And that's why I said it sounds weird. Because it seems you are doing it "wrong". I say it again: Take yourself 20minutes and do the Hello Worlds Tutorial. Step by Step. And I mean DO it, not just read. Especially when you have some programming background the concepts of ProcessWire will be different than you expect. And I bet when you are done with the tutorial you can answer your questions from the first post yourself. I don't want to sound lecturing... haha, I knew it and I just wanted to add: Invest that 20minutes and have fun for the next years enjoying the ease of pw PS: Seems it made click in 7 minutes, not in 20 ^^
  14. hi timberwolf, welcome to the forum 2 hints here: many of us are using google to easily search the forum: https://processwire.com/talk/topic/6196-easy-search-on-pw-forums-with-google/ maybe you did'nt find anything because getting data from the database is just too simple with processwire that's a common problem when starting with processwire: you look for problems/compexity that you know from other systems but that simply don't exist in the pw world here it already starts sounding strange... also in your code example you are mixing some things up and are making things more complex than they need to be! give yourself 20minutes and do the https://processwire.com/docs/tutorials/hello-worlds/ tutorial step by step. I'm sure it'll make "click" after that PS: you are mixing up $pages->find() and $page->get() in your example! see https://processwire.com/api/ref/pages/find/ and https://processwire.com/api/ref/page/get/
  15. yes, you can do anything you want... https://processwire.com/api/hooks/ https://processwire.com/api/hooks/captain-hook/ send an email when a field changed, modify the description of an inputfield, inject custom javascript into your page... anything.
  16. hi @adrian today I revisited my old idea of a hook recorder ( see https://processwire.com/talk/topic/10857-making-hooks-visible-hookrecorder/ and this post by @Robin S https://processwire.com/talk/topic/12208-tracy-debugger/?do=findComment&comment=137508 ). I tried another approach than Robin suggested and failed (just found his post now by coincidence) Another possibility might be to modify the Filecompiler somehow so that it adds logging functions to every "public function ___" method. I think hooks are still hard to grasp, especially for new users. See https://processwire.com/talk/topic/18037-2-date-fields-how-to-ensure-the-second-date-is-higher/?do=findComment&comment=158168 for example (that brought up my idea of the hookrecorder again). Robins solution does not sound too hard to implement. Maybe it's even easier now you integrated the ready/init/finished option for the console? But even for advanced developers this feature could be very handy i think! Looking forward to hearing your thoughts and thanks for all the input for datatables
  17. @SamC it's really as simple as that: https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks Update 2022: $wire->addHookAfter('Pages::saved', function(HookEvent $event) { $page = $event->arguments('page'); bd('page saved'); bd($event, 'event'); bd($event->object, 'event->object'); bd($event->arguments(), 'event->arguments'); }); in the beginning it can be a little confusing when to use event->object, event->arguments and event->return but with the help of tracy you can quickly bring light into the dark: add the code above to the tracy console, set the radio on the right to load it on "ready" (same as placing the code in the site/ready.php file) and save any page: $event->arguments('page') is the same as using $event->arguments(0) that you will see very often and in the tracy dump you see that 0 is simply the key for the first argument in that hookevent. you can also collapse the "data" property of the hookevent and you would see the same: You can also use your IDE to quickly find what the HookEvent is returning/containing in which hook. Let's take the common saveReady hook as an example: We know that the hook is attached as Pages::saveReady (eg because we have read that somewhere) That means that the hook is part of the "Pages" class, which is located at "/wire/core/Pages.php" - that's easy to find out using CTRL+P in VSCode: Searching for "___saveReady" lets us find the corresponding method: Now we see, that we have ONE "arguments", being Page $page - this means $event->arguments(0) would return the page being ready for saving $event->object would be the class, here "Pages" $event->return is the return value of that method, here $data (line 1739) Edit: There's some additional explanations in this post: https://processwire.com/talk/topic/27248-pagestrashtemplatefoo-vs-pagestemplatefootrash/?do=findComment&comment=224659 #search afraid of hooks
  18. Several options. Admin custom files module. AdminOnSteroids has this option too I think. And finally my favourite way: via hook (several possibilities here again)
  19. via page save hook would be the only reliable way. via some javascript would be the more user-friendly way. $(document).on('change', '#Inputfield_yourdatefield', function(e) { var yourdate = $(e.target).val(); var yourotherdate = ...; if(yourdate < yourotherdate) { alert('yourdate must be higher than ...'); // reset field $(e.target).val(''); } }); doing both would be the best don't think there's a built in way...
  20. actually that's a good point because requesting the data from the server is one thing whereas presenting it is another. at datatables you have cell renderers that render your values differently in different situations. so your datefield would ideally be an integer (making it sortable) and be DISPLAYED in the table as a formatted string (using moment.js). so you would not need to format the date via sql because that is done on the client maybe that's why i was not really eager about it and you thought it would be more important. but having a findObject/Array method in the core would justify that feature to some extend. regarding the datatables there will also be an option for defining php functions (see here https://processwire.com/talk/topic/15524-preview-rockdatatables/?do=findComment&comment=158061 ). $table->data( $pages->find('template=item'), [ ['col_name1', 'label of this column', function() { return $this->page->title; }], ... So that would make it really simple to setup tables - you would not have to know or write anything related to SQL. You could just use php's date('Ymd', $page->yourdatefield) function. So all the SQL options are really only meant to be used for complex tables. I think every developer working with that kind of complex tables should not be afraid of using some (very simple btw) sql queries thanks for all your input!
  21. I get your point but I don't think this level of reduction is good. For example if you looked for a way to format your date you would google "mysql date format" and see this example: SELECT DATE_FORMAT(BirthDate, "%W %M %e %Y") FROM Employees; I think it's a lot easier to communicate in the docs that you have to use the "data" column in your query than changing the syntax. So your query would be DATE_FORMAT(data, '%W %M %e %Y') I'm still hesitant about how often that would be needed... But if needed often this could be a handy timesaver for sure.
  22. Don't think that would be a good idea because if you want to query repeaters or the like you can concat strings from subqueries and so on with my route. Maybe we could add a check wheter the statement begins with SELECT or not. If it begins with SELECT it takes the whole query, if not it creates the query for you... 'myfield' => 'YEAR(data)' --> (SELECT YEAR(data) FROM field_myfield WHERE pages_id = p.id) AS myfield 'myfield' => 'SELECT ... FROM ... WHERE ...' --> (SELECT ... FROM ... WHERE ...) AS myfield Not sure how often one would need this short syntax? But also no problem to implement...
  23. not at all, sounds like this could be a great companion! at the moment I think I will also release the datatables module as open source. I've never worked with d3 but the company I'm writing my thesis at does some crazy stuff with it maybe a dedicated "d3 preview" thread would be nice? I really enjoy the discussion and the input here
  24. hi francis, thanks for your suggestions! You mean something like "make a piechart of column x and y"? I'm already thinking of that but don't know if it's really worth the effort when you can write nice charts with some lines of chartjs code... maybe a simple example/tutorial would be of more help... Thanks, I already knew kendo and like the style very much. Though I'm sure I cannot provide all those features. But I already built my module to be extendable via plugins so everybody will be welcome to contribute. The filter plugin will for sure be one of the most important ones and your examples are nice starting points! and https://demos.telerik.com/kendo-ui/grid/filter-menu-customization Yeah, I also thought of that option. Would be quite easy. Could be used like this: $pages->findObjects('template=basic-page', [ 'id', 'templates_id', 'mydate' => 'SELECT YEAR(data) FROM field_mydate WHERE pages_id = p.id', 'multilang_example' => 'SELECT GROUP_CONCAT(#data# separator '|') FROM field_test_page WHERE pages_id = p.id' ]); 2 things here to mention: using subqueries makes this very easy to implement multilang would be possible replacing #data# by data1234 (data + langid) I really like where this goes so far
  25. updated the hook in my previous post to support queries of the pages table itself (like templates_id, created_users_id and so on). edit: this solution is not the best, imho. It would be better to have one array with all fields and then split this array automatically (like this: if field part of pages table query this field directly else join field_xxx )
×
×
  • Create New...