Jump to content
Sign in to follow this  
FuturShoc

Building a module - Stuck on getting users

Recommended Posts

HI, guys.  Could use some help.

I've got the basic module working from the HelloWorld example. My goal is to notify all users of a specific role when a specific subset of pages is updated.

So, I'm using the SAVE hook. That's firing just fine on save, but I'm having trouble getting all users of a specific role after that.

This works fine, but, of course, gives me a lot of other data I don't need.

wire('users')

When I try to do this:

wire('users')->find("roles=rfp-user")

... my install throws an Internal Server error and breaks the module.

What am I doing wrong?

Share this post


Link to post
Share on other sites

Hey FuturShoc, 

Please see this thread and post.

 The reason it's not working in the above case is because the selector in question is not a database querying selector, just an in-memory one validating that the page matches the selector.

Also, when you are developing you should add:

$config->debug = true;

in your /site/config.php. It makes debugging a lot easier. Or copy $config->debugIf to your /site/config.php.

Share this post


Link to post
Share on other sites

Yes, enabling debugging has improved the feedback I'm getting, yes. Thanks for that reminder.

So, I think I understand the issue with my original attempt. However, I don't understand where to go from here to get data back from ProcessWire as I could easily do inside a template via the API.

How must the module context be different in order to get the same sort of results?

Share this post


Link to post
Share on other sites

An internal server error: usually means, a problem with the server. Does ProcessWire throw an exception?

Share this post


Link to post
Share on other sites

I doubt that wire('users')->find("roles=rfp-user") will work at all. Roles is a PageArray, thus you have to search it as usual.

// searching a sigle role, 1234 ID of the role
wire('users')->find("roles=1234, include=all") 
ps, I'm not sure about the include all, you have to try it yourself.

Share this post


Link to post
Share on other sites

It works just fine lads... :-)

$us = wire('users')->find('roles=editor');
echo count($us);//returns 2
foreach ($us as $u) {
  echo $u->name . '<br>';
}

...But haven't tested in the same context as FuturShoc (hooking)....

What I don't get is the internal server error...

@FuturShoc, if you can show us some code and the exact error you are getting....

Edited by kongondo
  • Like 1

Share this post


Link to post
Share on other sites

Here is my full code at the moment and the error I'm getting:

 

<?php

/**
 * ProcessWire 'Hello world' demonstration module
 *
 * Demonstrates the Module interface and how to add hooks.
 * 
 * See README file for further links regarding module development.
 * 
 * ProcessWire 2.x 
 * Copyright (C) 2014 by Ryan Cramer 
 * Licensed under GNU/GPL v2, see LICENSE.TXT
 * 
 * http://processwire.com
 *
 */

class Notifybyrole extends WireData implements Module {

	/**
	 * getModuleInfo is a module required by all modules to tell ProcessWire about them
	 *
	 * @return array
	 *
	 */
	public static function getModuleInfo() {

		return array(

			// The module'ss title, typically a little more descriptive than the class name
			'title' => 'Notify by role', 

			// version number 
			'version' => 1, 

			// summary is brief description of what this module is
			'summary' => 'Notify site members whose role is ???',
			
			// Optional URL to more information about the module
			'href' => 'http://inthooz.com',

			// singular=true: indicates that only one instance of the module is allowed.
			// This is usually what you want for modules that attach hooks. 
			'singular' => true, 

			// autoload=true: indicates the module should be started with ProcessWire.
			// This is necessary for any modules that attach runtime hooks, otherwise those
			// hooks won't get attached unless some other code calls the module on it's own.
			// Note that autoload modules are almost always also 'singular' (seen above).
			'autoload' => true, 
		
			// Optional font-awesome icon name, minus the 'fa-' part
			'icon' => 'smile-o', 
			);
	}

	/**
	 * Initialize the module
	 *
	 * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
	 * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. 
	 *
	 */
	public function init() {

		$this->pages->addHookAfter('save', $this, 'notifyByRole'); 

	}

	/**
	 * Example1 hooks into the pages->save method and displays a notice every time a page is saved
	 *
	 */
	public function notifyByRole($event) {
		$page = $event->arguments[0]; 

		$us = wire('users')->find('roles=superuser');
		echo count($us);//returns 2
		foreach ($us as $u) {
		  echo $u->name . '<br>';
		}
		$this->message("Hello World! You saved {$page->path}, {$page->parent->path}.");

	}

	
}

post-863-0-36717200-1444662275_thumb.png

Share this post


Link to post
Share on other sites

I get the same sort of error when I revise the user code to this. My "superuser" role is ID 38.

$us = wire('users')->find("roles=38, include=all");
		echo count($us);//returns 2
		foreach ($us as $u) {
		  echo $u->name . '<br>';
		}

Share this post


Link to post
Share on other sites

Your class name 'Notifybyrole' is clashing with the method named 'notifyByRole'. In PHP, function and class names are case-insensitive. So, PHP is getting confused because it considers them the same thing in your case. Try changing the method name to e.g. 'notifyByRolex' and the error goes away....

Edit:

Having said that, I am not sure how you intend to notify users that a page has been saved. Are you referring to logged-in users? Or will you be sending them an email? That determines what sort of code you need in the hook method.

And Btw, that was a 'Fatal error' not an 'internal server error'...The difference is important :-)

Edited by kongondo

Share this post


Link to post
Share on other sites

@FuturShoc, the code I posted above was an example to test the selector, not something you would use in your Hook method :-)
 
If you want the notification to be shown within the page save and only for supersusers, you could do something like this:

public function notifyByRole2($event) {
   $page = $event->arguments[0];
   if($this->user->hasRole('superuser')) $this->message("Hello World! You saved {$page->path}, {$page->parent->path}.");

}

Or if you wanted to notify those who don't have that role:

public function notifyByRole2($event) {
   $page = $event->arguments[0];
   if(!$this->user->hasRole('superuser')) $this->message("Hello World! You saved {$page->path}, {$page->parent->path}.");

}
Edited by kongondo
  • Like 1

Share this post


Link to post
Share on other sites

What Martijn said. ^-^

Just to expound...constructors are run before the other stuff. Since your notifyByRole declares that is accepts one argument/parameter called $event, PHP (now treating the method as a constructor due to the identical names with the class) looks for and doesn't get the variable $event. Either way, renaming your method resolves your problem. I've tested your code and it works fine..

Thanks Martijn :-)

Edited by kongondo
  • Like 1

Share this post


Link to post
Share on other sites

Thanks, guys, for your help and taking the time. It is very much appreciated. Here's what I've learned:

1. kongondo, you were right, of course, about my module's class name and the method names inside of it. I revised my method name to "notifyNow()" instead and the associated hook and those errors cleared up.

2. As a result, it seems, my wire('users')->find() call seems to now be working as I felt it should all along. My theory is that the errors with the class/method naming was preventing ProcessWire from doing the necessary bootstrapping to make that call work. Doe that sound right?

3. My goal is to notify users via email. I'm just using $this->message( ) to do interim debugging.


Thank you all again!

  • Like 1

Share this post


Link to post
Share on other sites

...My theory is that the errors with the class/method naming was preventing ProcessWire from doing the necessary bootstrapping to make that call work. Doe that sound right?

What caused this is what Martijn posted above and my attempt to expound on it. The 'identical' names made PHP assume your method was a constructor....etc...as stated above :-)

Happy coding! :-)

Share this post


Link to post
Share on other sites

There was a typo in my explanation. Corrected that in case it confused you...

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...