Page 1 of 2

Notifications

Posted: Sat Aug 30, 2014 8:58 am
by david63
Is there a guide anywhere on how to use notifications in extensions?

Re: Notifications

Posted: Sat Aug 30, 2014 9:18 am
by rxu
There's no such a guide. There's a topic which may direct to this viewtopic.php?f=461&t=2252326

Recently I've created a kind of that guide but it's in Russian, will take some time to translate.

Re: Notifications

Posted: Sat Aug 30, 2014 1:20 pm
by rxu
Here's a brief guide to give an initial direction about creating notifications in extensions. I don't claim to its absolute correctness as I'm just describing steps I followed myself to make it work somehow.
Please feel free to point to any dumb stuff and correct errors if any.
Here we are.

To create a notification for your own extensions, you can basically do the following.
  • In services.yml, add new notification service name. As of phpBB 3.1.0-RC4, the name should follow formatting scheme: <vendor>.<extension>.notification.type.my_cool_notification. In eralier versions, <vendor>.<extension>. wasn't required.
    Notification service definition should include special tag:

    Code: Select all

            tags:
                - { name: notification.type }
    
    Example:

    Code: Select all

        vendor.extname.notification.type.my_cool_notification:
            class: vendor\extname\notification\my_cool_notification
            scope: prototype # scope MUST be prototype for this to work!
            arguments:
                - @user_loader
                - @dbal.conn
                - @cache.driver
                - @user
                - @auth
                - @config
                - %core.root_path%
                - %core.php_ext%
                - %tables.notification_types%
                - %tables.notifications%
                - %tables.user_notifications%
            tags:
                - { name: notification.type }
    
  • Create notification file with corresponding class definition. Notification files should be located in /ext/<vendor>/<ext_name>/notification/ folder.
    In this example, notification file is named as my_cool_notification.php. The class defined in it is extending the base notification type class - \phpbb\notification\type\base. Example:

    Code: Select all

    class my_cool_notification extends \phpbb\notification\type\base
    {
    
    The class is including properties and methods required to create notification:
    1. Function returning notification type name, in this example it's 'my_cool_notification' - after the file and class names:

      Code: Select all

      	public function get_type()
      	{
      		return 'my_cool_notification';
      	}
      
      
    2. Property defining the language variable key which should present the notification text: protected $language_key.

      Code: Select all

      protected $language_key = 'MY_NOTIFICATION_TEXT';
      and the language entry for example

      Code: Select all

      'MY_NOTIFICATION_TEXT'		=> '<strong>Impression</strong> from %1$s user about the post:',
    3. Property (array) defining where to put your notification option to edit in UCP->Board preferences->Edit notifications options: public static $notification_option. Possible keys are 'id', 'lang', 'group'.
      2 latter keys should be enough:
      'group' - group of notifications options setting to put your notification setting option. Represents an options group language entry key, for example:

      Code: Select all

      'group'	=> 'NOTIFICATION_GROUP_MISCELLANEOUS',
      which value is (can be found at UCP page mentioned above):

      Code: Select all

      'NOTIFICATION_GROUP_MISCELLANEOUS'					=> 'Miscellaneous Notifications',
      'lang' - the name of your notification option setting, like

      Code: Select all

      'lang'	=> 'MY_NOTIFICATION_TYPE_OPTION',
      which for example can be

      Code: Select all

      'MY_NOTIFICATION_TYPE_OPTION'	=> 'Someone is impressed with your post',
      Final result:

      Code: Select all

      	public static $notification_option = array(
      		'lang'	=> 'MY_NOTIFICATION_TYPE_OPTION',
      		'group'	=> 'NOTIFICATION_GROUP_MISCELLANEOUS',
      	);
      
    4. Function to define conditions of notification availability. Can be what do you want to be with result of bool (true/false). To make it available permanently:

      Code: Select all

      	public function is_available()
      	{
      		return true;
      	}
      
    5. Function returning id of notification related node which is item_id. It will be written into the item_id field of NOTIFICATIONS_TABLE in database. Please note that it's impossible to send more than 1 notification of this type per user for the same item_id. Example (using of post_id as an item_id):

      Code: Select all

      	/**
      	* Get the id of the item
      	*
      	* @param array $my_notification_data The data from the post
      	*/
      	public static function get_item_id($my_notification_data)
      	{
      		return (int) $my_notification_data['post_id'];
      	}
      
      
      In this example, post_id is chosen to represent item_id. In common case, it can be any integer identificator of the element making sense in relation to the notification.
    6. Function returning id of the item_id parent element: item_parent_id. For the post_id such an element would be topic_id. Example:

      Code: Select all

      	/**
      	* Get the id of the parent
      	*
      	* @param array $my_notification_data The data from the topic
      	*/
      	public static function get_item_parent_id($my_notification_data)
      	{
      		return (int) $my_notification_data['topic_id'];
      	}
      
      
    7. Function to select an array of user ids to send notification (will be passed to the function check_user_notification_options() to get users notification types data). Example:

      Code: Select all

      	/**
      	* Find the users who want to receive notifications
      	*
      	* @param array $my_notification_data The data from the post
      	* @param array $options Options for finding users for notification
      	*
      	* @return array
      	*/
      	public function find_users_for_notification($my_notification_data, $options = array())
      	{
      		$options = array_merge(array(
      			'ignore_users'		=> array(),
      		), $options);
      
      		$users = array((int) $my_notification_data['poster_id']);
      
      		return $this->check_user_notification_options($users, $options);
      	}
      
      Here you can set any required conditions to select the list of users to send notification depending on the actual context. For example, you can select the list from database etc.
    8. Function to get user avatar. Example:

      Code: Select all

      	/**
      	* Get the user's avatar
      	*/
      	public function get_avatar()
      	{
      		return $this->user_loader->get_avatar($this->get_data('user_id'));
      	}
      
      Here, get_data() method was used to get user_id. Please note that this method is designed to get the data previously saved for the database via function create_insert_array() (see below). Thus, you have to save user_id via the mentioned method first.
    9. Function creating notification title using $language_key property mentioned above. Example:

      Code: Select all

      	/**
      	* Get the HTML formatted title of this notification
      	*
      	* @return string
      	*/
      	public function get_title()
      	{
      		$username = $this->user_loader->get_username($this->get_data('user_id'), 'no_profile');
      
      		return $this->user->lang($this->language_key, $username);
      	}
      
    10. Function to load information about users which can be used to create notification: function users_to_query(). The list of users ids (user_id) returned will be passed to user_loader object to load information about users for notification class.
    11. Function to create URL for the item notification is about. Example:

      Code: Select all

      	/**
      	* Get the url to this item
      	*
      	* @return string URL
      	*/
      	public function get_url()
      	{
      		return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->item_id}#p{$this->item_id}");
      	}
      
    12. Function returning the URL above to create a link, f.e. to follow by the click on notification. Example:

      Code: Select all

      	public function get_redirect_url()
      	{
      		return $this->get_url();
      	}
      
    13. Function to set email text file template for notification. The file name should be prefixed with @<vendor>_<extname>/. Email files should be located in /ext/<vendor>/<ext_name>/language/<iso>/email/ folder. Example:

      Code: Select all

      	/**
      	* Get email template
      	*
      	* @return string|bool
      	*/
      	public function get_email_template()
      	{
      		return '@imtheauthor_myextname/my_notification_email';
      	}
      
    14. Function returning the text below the notification title (the reference of the notification). It can be the subject of the post, the title of the topic notification is about and so on. Example:

      Code: Select all

      	/**
      	* Get the HTML formatted reference of the notification
      	*
      	* @return string
      	*/
      	public function get_reference()
      	{
      		return $this->user->lang(
      			'NOTIFICATION_REFERENCE',
      			censor_text($this->get_data('post_subject'))
      		);
      	}
      
    15. Function to assign email template variables. Example:

      Code: Select all

      	/**
      	* Get email template variables
      	*
      	* @return array
      	*/
      	public function get_email_template_variables()
      	{
      		$user_data = $this->user_loader->get_user($this->get_data('poster_id'));
      
      		return array(
      				'NOTIFICATION_SUBJECT'	=> htmlspecialchars_decode($this->get-title()),
      				'USERNAME'		=> htmlspecialchars_decode($this->user->data['username']),
      				'U_LINK'	=> generate_board_url() . '/viewtopic.' . $this->php_ext . "?p={$this->item_id}#p{$this->item_id}",
      		);
      	}
      
    16. Function to prepare (serialize) notification data to save in the database. This data can be derived via get_data(). Example:

      Code: Select all

      	/**
      	* Function for preparing the data for insertion in an SQL query
      	* (The service handles insertion)
      	*
      	* @param array $my_notification_data Data from insert_thanks
      	* @param array $pre_create_data Data from pre_create_insert_array()
      	*
      	* @return array Array of data ready to be inserted into the database
      	*/
      	public function create_insert_array($my_notification_data, $pre_create_data = array())
      	{
      		$this->set_data('user_id', $my_notification_data['user_id']);
      		$this->set_data('post_id', $my_notification_data['post_id']);
      		$this->set_data('post_subject', $my_notification_data['post_subject']);
      
      		return parent::create_insert_array($my_notification_data, $pre_create_data);
      	}
      
    17. Property (array) containing data required to pass to notification, including data to write into the database. The array should be passed as a parameter to the function add_notifications(). In this concrete example this is $my_notification_data. Example:

      Code: Select all

      					$my_notification_data = array(
      						'user_id'	=> (int) $this->user->data['user_id'],
      						'post_id'	=> $post_id,
      						'poster_id'	=> $poster_id,
      						'topic_id'	=> (int) $row['topic_id'],
      						'forum_id'	=> (int) $row['forum_id'],
      						'time'	=> time(),
      						'username'	=> $this->user->data['username'],
      						'post_subject'	=> $row['post_subject'],
      					);
      
  • Now you can add notification handling this action in external notification-manager-aware file. Example:

    Code: Select all

    					$my_notification_data = array(
    						'user_id'	=> (int) $this->user->data['user_id'],
    						'post_id'	=> $post_id,
    						'poster_id'	=> $poster_id,
    						'topic_id'	=> (int) $row['topic_id'],
    						'forum_id'	=> (int) $row['forum_id'],
    						'time'	=> time(),
    						'username'	=> $this->user->data['username'],
    						'post_subject'	=> $row['post_subject'],
    					);
    
    					$this->notification_manager->add_notifications(array(
    						'my_cool_notification',
    					), $my_notification_data);
    
    To make your extension (say, event listener) notification-manager-aware, inject corresponding dependency into its class constructor.
    In services.yml:

    Code: Select all

                - @notification_manager
    In class constructor arguments list (the argument variable can be named as you want):

    Code: Select all

    \phpbb\notification\manager $notification_manager
    and then in constructor body (the class property can be named as you want):

    Code: Select all

    $this->notification_manager = $notification_manager;
  • IMPORTANT:
    You have to extend the base extension class using the ext.php to enable, disable and purge notifications during those steps, otherwise you'll break out the board.
    Please follow what was done in the phpbb/boardrules extension's ext.php file as a guide.

Re: Notifications

Posted: Sat Aug 30, 2014 2:01 pm
by david63
Thanks for that - I will try it out later

Re: Notifications

Posted: Sun Aug 31, 2014 7:28 am
by VSE
You left out the most important part... you have to extend the base extension class using the ext.php to enable, disable and purge notifications during those steps, otherwise you'll break the heck out of somebody's board.

just follow what was done in the phpbb/boardrules extension's ext.php file as a guide.

Re: Notifications

Posted: Sun Aug 31, 2014 7:54 am
by rxu
Thanks a lot. I didn't even bother with that as the main goal was to create extension notifications and make it workable.
Added ext.php stuff to the guide post above.

Re: Notifications

Posted: Mon Feb 23, 2015 3:11 pm
by LeonHagendijk
First of all, sorry for necroposting in this topic...
I'm searching all over the Forums for a simple, step-by-step how-to for creating new Notifications from extensions, when I stumbled upon this topic, most of all the how-to by rxu above.

Does this how-to still apply? And if yes, is it a wise idea to post these instructions to wiki.phpbb.com under the Extension category?
Perhaps with a little more documentation what each notification function does (i.e. when is is_available() being called? When posting the notification, or can I use this function to be able to check if a notification still needs a follow-up?*)

*: i.e. a notification for a post which should be approved, can be sent to all moderators. Will I be able to use is_available() to check if the post still needs approval?

[edit] New link for ext.php quoted in abovementioned posts: https://github.com/phpbb-extensions/boa ... er/ext.php

Re: Notifications

Posted: Sat May 16, 2015 11:11 am
by javiexin
Thanks for the tutorial, very needed (for this and a number of other areas in PHPBB 3.1).

One question/concern:
rxu wrote:
  1. Function returning notification type name, in this example it's 'my_cool_notification' - after the file and class names:

    Code: Select all

    	public function get_type()
    	{
    		return 'my_cool_notification';
    	}
    
    
Shouldn't this have a fully qualified type name?, such as:

Code: Select all

	public function get_type()
	{
		return 'vendorname.extensionname.notification.type.my_cool_notification';
	}
At least this is what I have seen in other examples...
Again, many thanks.
-javiexin

Re: Notifications

Posted: Sat May 16, 2015 12:14 pm
by david63
javiexin wrote:Shouldn't this have a fully qualified type name?
I'm not sure if this changed along the way or that there are two ways of doing it - one for core files and one for extensions.

Re: Notifications

Posted: Sat May 16, 2015 1:21 pm
by rxu
javiexin
Yes you're rught, that part of the tutorial should be updated.

Re: Notifications

Posted: Sat May 16, 2015 1:23 pm
by javiexin
Even for core files, the notification is qualified, only whithout vendor/extension, but with 'notification.type' in it:

Code: Select all

    public function get_type()
    {
        return 'notification.type.topic';
    }

Re: Notifications

Posted: Sat May 16, 2015 1:24 pm
by javiexin
rxu wrote:Yes you're rught, that part of the tutorial should be updated.
Thanks a lot rxu.
As I said, very needed and very useful!
-javiexin

Re: Notifications

Posted: Wed Jul 20, 2016 3:19 pm
by Aurelienazerty
Hi,

I've few questions about notification.

I made 2 notifications Aurelienazerty.PhotoNotifications.notification.type.commentaire and Aurelienazerty.PhotoNotifications.notification.type.like
I made change in ext.php in enable_step, disable_step, purge_step
I made a migration class with

Code: Select all

static public function depends_on()
	{
		return array(
			'\phpbb\db\migration\data\v310\dev',
			'\phpbb\db\migration\data\v310\notifications_use_full_name'
		);
	}
and

Code: Select all

public function update_data()
	{
		return array(
			array('custom', array(array($this, 'update_notifications_name'))),
		);
	}
	
	public function update_notifications_name()
	{
		$sql_ary = array();
		$sql_ary[] = array(
			'notification_type_name'	=> 'Aurelienazerty.PhotoNotifications.notification.type.commentaire',
			'notification_type_enabled'	=> 1,
		);
		$sql_ary[] = array(
			'notification_type_name'	=> 'Aurelienazerty.PhotoNotifications.notification.type.like',
			'notification_type_enabled'	=> 1,
		);
		
		foreach ($sql_ary as $sql)
		{
			$notification_type_name = explode('type.', $sql['notification_type_name']);
			$sql_update = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . '
				SET ' . $this->db->sql_build_array('UPDATE', $sql) . "
				WHERE notification_type_name = '" . $notification_type_name[1] . "'";
			$this->db->sql_query($sql_update);
			$sql_update = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
				SET item_type = '" . $this->db->sql_escape($sql['notification_type_name']) . "'
				WHERE item_type = '" . $notification_type_name[1] . "'";
			$this->db->sql_query($sql_update);
		}
	}
But I don't found where I put instructions for adding the 2 notification in phpbb_notification_types table.

Can you help me ?

Re: Notifications

Posted: Wed Jul 20, 2016 3:21 pm
by david63
Are you aware that notifications are changing in 3.2?

Re: Notifications

Posted: Wed Jul 20, 2016 10:04 pm
by Aurelienazerty
I forgot that, so it's not good thing to make an extension for the moment...