Ovi Posted June 22, 2013 Share Posted June 22, 2013 Hello everyone. My problem today: i have a custom module built by Antti Peisa which hooks into the comments module that comes with PW and adds a ratings field. Antti did an awesome job with it, except i'm not able to sort pages by their average rating. that happens because the average rating is not stored into any db field, it's just calculated at runtime, on request. since Antti unfortunately doesn't have any time to help me with this beyond a quick pointer, i'm posting here. please see the bottom of this post for Antti's comment ratings module. My attempted solution: build a module that stores the average rating for a comments field in another field, as an integer or float: i built the module lke this class PageAverageRating extends WireData implements Module { public static function getModuleInfo() { return array( // bla bla, removed for brevity ); } public function init() { $this->addHookAfter(CommentRatings::processRatingInput, $this, 'copyAverageRating'); } public function copyAverageRating($event) { $page = $event->arguments[0]; // we're interested in product pages only if($page->template->name != 'product') return; // copy the average rating into another field, if there is a rating if(count($page->product_comments) > 0) { $page->average_rating = $page->product_comments->averageRating; } else { $page->average_rating = 0; } } } i obviously had to hook it to the moment a comment gets added. Didn't really know how to do that. Antti said:try making CommentFormWithRatings::processRatingInput hookable (by adding ___) so i turned processRatingInput into ___processRatingInput to make it hookable - i doesn't seem to have worked, see below Where i'm stuck: when i run the module above with the hook: $this->addHookAfter(CommentRatings::processRatingInput, $this, 'copyAverageRating'); i get an error saying: Error: Undefined class constant 'processRatingInput' (line 16 of ..../public_html/site/modules/PageAverageRating.module) Other things i've tried: Since this should be a method and not a property, i tried: $this->addHookAfter(CommentRatings::processRatingInput(), $this, 'copyAverageRating'); i get an error saying: Error: Undefined class method 'processRatingInput' (line 16 of ..../public_html/site/modules/PageAverageRating.module) Also i've tried hooking into the CommentFormWithRatings class which extends the CommentForm class and actually contains the processRatingInput() method: $this->addHookAfter(CommentFormWithRatings::processRatingInput, $this, 'copyAverageRating'); Error: Class 'CommentFormWithRatings' not found (line 16 of ..../public_html/site/modules/PageAverageRating.module) I'm attaching the module that Antti built here - it's going to be public anyway. CommentFormWithRatings.php CommentRatings.module Can anybody please help me out ? I feel like the village idiot for not managing to figure this out. How do i make this hook work? Big thanks! Link to comment Share on other sites More sharing options...
horst Posted June 22, 2013 Share Posted June 22, 2013 Ovi, not much time, but when Anttis code isn't a module and "class CommentFormWithRatings extends CommentForm" why do you doesn't extend Anttis class? class OvisCommentFormWithSorting extends CommentFormWithRatings and then you have there a public function processRatingInput() { that call parent::processRatingInput(); and then do your stuff ? So, completely untested, but its like I understand the OOP System from PHP 5x, what is relative new to me, so- maybe I'm wrong. Link to comment Share on other sites More sharing options...
Soma Posted June 22, 2013 Share Posted June 22, 2013 Put the method in the hook in "". Link to comment Share on other sites More sharing options...
teppo Posted June 22, 2013 Share Posted June 22, 2013 Try adding quotes and hooking into CommentFormWithRatings: $this->addHookAfter("CommentFormWithRatings::processRatingInput", $this, 'copyAverageRating'); Edit: speed bonus goes to Soma. Link to comment Share on other sites More sharing options...
Ovi Posted June 23, 2013 Author Share Posted June 23, 2013 Thanks, can't believe i missed that. But the problem's still here, it just that the error's gone. i tried all i could think of but i'm certain now that $this->addHookAfter("CommentRatings::processRatingInput", $this, 'copyAverageRating'); is not triggering like it should. So my module's not working. (even though i have ___processRatingInput() in Antti's code) Basically i need a hook that would execute the copyAverageRating function each time a comment is added. There's no hook in PW for when a comment is added, as far as i know. @horst Thanks for the suggestion, but it's a little hard for me to do since i don't understand Antti's module. If i did, i would have written it myself Everything's a confusing mess for me and each time i try to follow the code i get lost. Besides, all i need is to "do something" after a comment has been added. It looks like a module might be the simplest solution to that, if i can get a working hook, that is. Halp? Link to comment Share on other sites More sharing options...
teppo Posted June 23, 2013 Share Posted June 23, 2013 @Ovi: did you try what I've suggested above, ie. hooking into "CommentFormWithRatings::processRatingInput"? That actually worked for me (at least to the point that a die() statement placed in copyAverageRating() was getting executed), so I'm pretty sure it should work for you too Any chance that your method is getting executed but it doesn't work properly? Try doing something very obvious (like a die("foo")) in your copyAverageRating() and see if that gets executed. Whether it does or doesn't, you'll have narrowed the problem quite a bit already. Another thing you could try is doing something similar in init() method of your module. Try putting a die() statement there; if your page still gets rendered, whole module isn't getting executed properly. (You've omitted module settings, but just to make sure: that module is set as "autoload", right?) 1 Link to comment Share on other sites More sharing options...
Ovi Posted June 24, 2013 Author Share Posted June 24, 2013 public function init() { die("foo"); $this->addHookAfter("CommentFormWithRatings::processRatingInput", $this, 'copyAverageRating'); } displays foo when viewing any page, so the module loads properly. public function copyAverageRating($event) { die("foo"); $page = $event->arguments[0]; // we're interested in product pages only if($page->template->name != 'product') return; // copy the average rating into a field called average_rating $page->average_rating = $page->product_comments->averageRating; } The above does nothing when adding a comment. die() never gets called. I double checked all my naming, i don't know where the issue is. Any idea where to look next? Link to comment Share on other sites More sharing options...
Soma Posted June 24, 2013 Share Posted June 24, 2013 This must work, only thing would be if your module isn't autoload. Link to comment Share on other sites More sharing options...
Ovi Posted June 24, 2013 Author Share Posted June 24, 2013 This must work, only thing would be if your module isn't autoload. It is definitely autoload: public static function getModuleInfo() { return array( 'title' => 'Copy average rating into hidden field', 'version' => 100, 'summary' => 'Copies the average rating to another field', 'singular' => true, 'autoload' => true, ); } Link to comment Share on other sites More sharing options...
Soma Posted June 24, 2013 Share Posted June 24, 2013 No idea, but it works for me. I use same code as yours, can you post your complete module? Link to comment Share on other sites More sharing options...
Ovi Posted June 24, 2013 Author Share Posted June 24, 2013 No idea, but it works for me. I use same code as yours, can you post your complete module? sure: <?php class PageAverageRating extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Copy average rating into hidden field', 'version' => 100, 'summary' => 'Copies the average rating to another field', 'singular' => true, 'autoload' => true, ); } public function init() { die("foo"); $this->addHookAfter("CommentFormWithRatings::processRatingInput", $this, 'copyAverageRating'); } public function copyAverageRating($event) { die("foo"); $page = $event->arguments[0]; // we're interested in product pages only if($page->template->name != 'product') return; // copy the average rating into a field called average_rating $page->average_rating = $page->product_comments->averageRating; } } Link to comment Share on other sites More sharing options...
Soma Posted June 24, 2013 Share Posted June 24, 2013 I just took your code and tested (removed the die() in the init) and it works the "foo" gets displayed after submitting. No idea what problem you got, but there's nothing special about it really. Does the comments and rating work at all for you? Caching? Link to comment Share on other sites More sharing options...
Ovi Posted June 24, 2013 Author Share Posted June 24, 2013 I have cache set to 0 on the product template. not using any other caching method. The comments module and the ratings module are working fine. I can add comments and ratings and the they get displayed properly. Everything is perfect except this hook won't work. I'm really starting to think we've stumbled onto some weird PW bug here. But maybe i'm jumping to conclusions... Link to comment Share on other sites More sharing options...
Soma Posted June 24, 2013 Share Posted June 24, 2013 Have you at some point added the autoload true when the module was already installed? There's no bug as far as I know as PW wouldn't work at all with all those hooks used in core. Link to comment Share on other sites More sharing options...
Ovi Posted June 24, 2013 Author Share Posted June 24, 2013 Nope i had autoload in the first time i installed the module. Link to comment Share on other sites More sharing options...
Soma Posted June 24, 2013 Share Posted June 24, 2013 Well the class you hook on is a little special in that it's extending CommentForm, but since it works for all of us except for you. What PW version do you use and PHP version? Can you try hooking page render? $this->addHookAfter("Page::render", $this, 'copyAverageRating'); Works? Link to comment Share on other sites More sharing options...
Ovi Posted June 25, 2013 Author Share Posted June 25, 2013 Yep that works, if i use that hook the function gets called. I'm using PHP 5.3.23 and PW 2.3.0 Link to comment Share on other sites More sharing options...
ryan Posted June 28, 2013 Share Posted June 28, 2013 Currently I can't see any reason why this wouldn't work. But a few things you might try: 1. Clear your opcode (APC?) cache. I do this whenever I encounter something odd that doesn't add up. 2. Clear your modules cache. You can do this by clicking "check for new modules" on the Modules tab. 3. Check your Comments field settings. Is it set to redirect after post? Try disabling that option, temporarily, to see if it makes any difference. 4. While I'm not aware of any issues related to this in PW 2.3.0, maybe try switching to the dev branch (2.3.1) just to change things up. Also: Uninstall your module. Then click "check for new modules", then re-install it. I'm wondering if it maybe started out as NOT autoload, and that setting got cached in the DB. PW doesn't load all the module settings at runtime, as it caches some of them, especially autoload status. Link to comment Share on other sites More sharing options...
Ovi Posted July 1, 2013 Author Share Posted July 1, 2013 Thanks for the suggestions Ryan, but none of them helped, unfortunately. 1. i do not use opcode cache on that server 2. i cleared the modules cache - no dice 3. the comment field was never set to redirect 4. I'm afraid to upgrade to 2.3.1 straight off the bat for fear of creating more bugs, i have to create a copy of the site on another account and try it there. Will let you know how it goes. 5. i uninstalled and reinstalled the module - no improvement. Not to whine, but I'm really getting to the end of my rope here, i have to turn in the site soon and this is holding things up terribly. Any help would be appreciated, although i'm beginning to think this can't be fixed for my site. Link to comment Share on other sites More sharing options...
Soma Posted July 1, 2013 Share Posted July 1, 2013 If you can give me access to the installation, I can take a look. 1 Link to comment Share on other sites More sharing options...
ryan Posted July 3, 2013 Share Posted July 3, 2013 We might have to look further, like what's going on in the template file. But one problem that I can spot in taking a closer look at the code is that the definition of your processRatingInput() method in CommentFormWithRatings.php has no arguments sent to it, but your hook function is assuming arguments[0] is a $page, when in fact it would be null. This doesn't indicate why the hook isn't getting called but it seems like you would get a PHP error in your hook function. I would fix that just in case it is causing the strange behavior or hiding some other error. Link to comment Share on other sites More sharing options...
Soma Posted July 4, 2013 Share Posted July 4, 2013 Hello? Are you still here? 3 Link to comment Share on other sites More sharing options...
Ovi Posted July 8, 2013 Author Share Posted July 8, 2013 Hello guys, I apologize for not responding for a while, i was ( still am ) in a middle of a nightmare situation with one of my older clients and his MODx site, i barely had time to sleep. So happy i moved away from MODx, wish i'd found PW earlier. Your offer is very generous Soma, of course i'll give you access! I will PM you right now with the login details for the site and also the FTP to it. Thanks so much, Ovi PS: the fact that you haven't given up on me and my problem yet shows what an awesome community this is. Best one i've seen so far. 3 Link to comment Share on other sites More sharing options...
Soma Posted July 8, 2013 Share Posted July 8, 2013 Hello Ovi Thanks for the info. I could connect and checked it out. I haven't done anything and it works. I only clicked "Check for new modules" once. The hook is getting executed and the output is shown in the review box after I submit the comment. Not sure what's about it, maybe you didn't look close enough but it's working as it should. I tested on this product /adaptasun-sea-and-tropics-spf-30/. Now I first looked also at what modules are installed, and the only strange thing is that you have 2 FieldtypeComments module, the one in core and one by Apeisa in site/modules ... ? Can they coexist like this? Well if it works, but I'm not sure if it would cause troubles or isn't needed. At least the core one can be deinstalled? Well so far, happy hacking. 3 Link to comment Share on other sites More sharing options...
Ovi Posted July 8, 2013 Author Share Posted July 8, 2013 Wow, I don't know what's went on there. i'm seeing the same thing now. I'm sorry for all the trouble i put you through, it definitely wasn't working for me before - the full page was getting displayed. I'll move on to seeing why the field isn't getting populated. Will keep you posted. Thanks so much! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now