Creating the add-on Smilie Count v1.0

AndyB

Well-known member
Description:

The Smilie Count add-on will limit the number of smilies allowed in a message. By default the add-on will limit five smilies per message.

To change the maximum number of smilies allowed in a message, edit the following Phrase text:

Code:
Please reduce the number of smilies to (5) or less.

Changing the number between the parentheses will result in a new maximum allowed smilies per message.

Requirements:

This add-on only works on XenForo v1.2 and above.
 
This tutorial will show the steps required to create this add-on:
  1. Create the directory structure
  2. Create the New Add-on
  3. Create the Listener.php file
  4. Create the Post.php file
  5. Create the Code Event Listener (Post)
  6. Create the Thread.php file
  7. Create the Code Event Listener (Thread)
  8. Create the Forum.php file
  9. Create the Code Event Listener (Forum)
  10. Create the Code Event Listener (Smilie)
  11. Create New Phrase
 
Last edited:
Create the directory structure:

library
--Andy
----SmilieCount
------ControllerPublic
--------Forum.php
--------Post.php
--------Thread.php
----Listener.php
----Model
------Smilie.php
 
Create the Listener.php file:

PHP:
<?php

class Andy_SmilieCount_Listener
{
	public static function Post($class, array &$extend)
	{
		$extend[] = 'Andy_SmilieCount_ControllerPublic_Post';
	}
	
	public static function Thread($class, array &$extend)
	{
		$extend[] = 'Andy_SmilieCount_ControllerPublic_Thread';
	}
	
	public static function Forum($class, array &$extend)
	{
		$extend[] = 'Andy_SmilieCount_ControllerPublic_Forum';
	}		
	
	public static function loadClassModel($class, array &$extend)
	{
		$extend[] = 'Andy_SmilieCount_Model_Smilie';
	}	
}

?>
 
Create the Post.php file:

library/Andy/SmilieCount/ControllerPublic/Post.php

PHP:
<?php

class Andy_SmilieCount_ControllerPublic_Post extends XFCP_Andy_SmilieCount_ControllerPublic_Post
{
	//########################################		
	// the original actionSave() function is located in library/Xenforo/ControllerPublic/Post.php
	// this actionSave() will run instead of the original unless we return parent::actionSave()
	//########################################
	
	public function actionSave()
	{		 
		//########################################
		// get data
		
		// this is fetching $smilietext from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie		
		
		// get smilie_text array
		$smilietext = $this->getModelFromCache('XenForo_Model_Smilie')->getSmilieText();
		
		// this is fetching $maxsmiliecount from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie	
		
		// get $maxsmiliecount array
		$maxsmiliecount = $this->getModelFromCache('XenForo_Model_Smilie')->getMaxSmilieCount();

		//########################################
		// get max smilie count
		
		// we use the phrase "please_reduce_the_number_of_smilies_to_or_less" to store the data
		// edit number between parentheses to adjust max smilie count
		
		foreach ($maxsmiliecount as $k => $v)
		{
			$phrase_text = $v['phrase_text'];
		}
		
		$pos1 = strpos($phrase_text, '(');
		$pos2 = strpos($phrase_text, ')'); 
		$pos_length = $pos2 - $pos1;
		$pos_length = $pos_length - 1;
		$pos1 = $pos1 + 1;
		$max_count = substr($phrase_text, $pos1, $pos_length);
		
		//########################################
		// default actionSave() code
		
		$this->_assertPostOnly();

		$postId = $this->_input->filterSingle('post_id', XenForo_Input::UINT);

		$ftpHelper = $this->getHelper('ForumThreadPost');
		list($post, $thread, $forum) = $ftpHelper->assertPostValidAndViewable($postId);

		$this->_assertCanEditPost($post, $thread, $forum);

		$input = $this->_input->filter(array(
			'attachment_hash' => XenForo_Input::STRING,

			'watch_thread_state' => XenForo_Input::UINT,
			'watch_thread' => XenForo_Input::UINT,
			'watch_thread_email' => XenForo_Input::UINT
		));
		$input['message'] = $this->getHelper('Editor')->getMessageText('message', $this->_input);
		$input['message'] = XenForo_Helper_String::autoLinkBbCode($input['message']); 		
		
		//########################################
		// count number of smilies in message
		
		$smilie_count = 0;	
		foreach ($smilietext as $k => $v)
		{
			$smilie_count += substr_count($input['message'], $v['smilie_text']);
		}			
		
		// show error message if $smilie_count exceeds limit
		if ($smilie_count > $max_count) 
		{
			return $this->responseError(new XenForo_Phrase('please_reduce_the_number_of_smilies_to_or_less'));
		} else {
			// run the original actionSave() function 
			return parent::actionSave();
		}
	}
}

?>
 
Create the Thread.php file:

library/Andy/SmilieCount/ControllerPublic/Thread.php

PHP:
<?php

class Andy_SmilieCount_ControllerPublic_Thread extends XFCP_Andy_SmilieCount_ControllerPublic_Thread
{
	//########################################		
	// the original actionAddReply() function is located in library/Xenforo/ControllerPublic/Thread.php
	// this actionAddReply() will run instead of the original unless we return parent::actionSave()
	//########################################
	
	public function actionAddReply()
	{		
		//########################################
		// get data
		
		// this is fetching $smilietext from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie		
		
		// get smilie_text array
		$smilietext = $this->getModelFromCache('XenForo_Model_Smilie')->getSmilieText();

		// this is fetching $maxsmiliecount from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie	
		
		// get $maxsmiliecount array
		$maxsmiliecount = $this->getModelFromCache('XenForo_Model_Smilie')->getMaxSmilieCount();

		//########################################
		// get max smilie count
		
		// we use the phrase "please_reduce_the_number_of_smilies_to_or_less" to store the data
		// edit number between parentheses to adjust max smilie count
		
		foreach ($maxsmiliecount as $k => $v)
		{
			$phrase_text = $v['phrase_text'];
		}
		
		$pos1 = strpos($phrase_text, '(');
		$pos2 = strpos($phrase_text, ')'); 
		$pos_length = $pos2 - $pos1;
		$pos_length = $pos_length - 1;
		$pos1 = $pos1 + 1;
		$max_count = substr($phrase_text, $pos1, $pos_length);
				
		//########################################
		// default actionAddReply() code
		
		$this->_assertPostOnly();

		if ($this->_input->inRequest('more_options'))
		{
			return $this->responseReroute(__CLASS__, 'reply');
		}

		$threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);

		$visitor = XenForo_Visitor::getInstance();

		$ftpHelper = $this->getHelper('ForumThreadPost');
		$threadFetchOptions = array('readUserId' => $visitor['user_id']);
		$forumFetchOptions = array('readUserId' => $visitor['user_id']);
		list($thread, $forum) = $ftpHelper->assertThreadValidAndViewable($threadId, $threadFetchOptions, $forumFetchOptions);

		$this->_assertCanReplyToThread($thread, $forum);

		if (!XenForo_Captcha_Abstract::validateDefault($this->_input))
		{
			return $this->responseCaptchaFailed();
		}

		$input = $this->_input->filter(array(
			'attachment_hash' => XenForo_Input::STRING,

			'watch_thread_state' => XenForo_Input::UINT,
			'watch_thread' => XenForo_Input::UINT,
			'watch_thread_email' => XenForo_Input::UINT,

			'_set' => array(XenForo_Input::UINT, 'array' => true),
			'discussion_open' => XenForo_Input::UINT,
			'sticky' => XenForo_Input::UINT,
		));
		$input['message'] = $this->getHelper('Editor')->getMessageText('message', $this->_input);
		$input['message'] = XenForo_Helper_String::autoLinkBbCode($input['message']);		
		
		//########################################
		// count number of smilies in message
		
		$smilie_count = 0;	
		foreach ($smilietext as $k => $v)
		{
			$smilie_count += substr_count($input['message'], $v['smilie_text']);
		}			

		// show error message if $smilie_count exceeds limit
		if ($smilie_count > $max_count) 
		{
			return $this->responseError(new XenForo_Phrase('please_reduce_the_number_of_smilies_to_or_less'));
		} else {
			// run the original actionAddReply() function 
			return parent::actionAddReply();
		}
	}
}

?>
 
Create the Forum.php file:

library/Andy/SmilieCount/ControllerPublic/Forum.php

PHP:
<?php

class Andy_SmilieCount_ControllerPublic_Forum extends XFCP_Andy_SmilieCount_ControllerPublic_Forum
{
	//########################################		
	// the original actionAddThread() function is located in library/Xenforo/ControllerPublic/Forum.php
	// this actionAddThread() will run instead of the original unless we return parent::actionAddThread()
	//########################################
	
	public function actionAddThread()
	{		
		//########################################
		// get data
		
		// this is fetching $smilietext from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie		
		
		// get smilie_text array
		$smilietext = $this->getModelFromCache('XenForo_Model_Smilie')->getSmilieText();
		
		// this is fetching $maxsmiliecount from XenForo_Model_Smilie 
		// the function getSmilieText() is initially not there
		// we extended XenForo_Model_Smilie with Andy_SmilieCount_Model_Smilie
		// all Andy_SmilieCount_Model_Smilie functions are now accessible from XenForo_Model_Smilie	
		
		// get $maxsmiliecount array
		$maxsmiliecount = $this->getModelFromCache('XenForo_Model_Smilie')->getMaxSmilieCount();

		//########################################
		// get max smilie count
		
		// we use the phrase "please_reduce_the_number_of_smilies_to_or_less" to store the data
		// edit number between parentheses to adjust max smilie count
		
		foreach ($maxsmiliecount as $k => $v)
		{
			$phrase_text = $v['phrase_text'];
		}
		
		$pos1 = strpos($phrase_text, '(');
		$pos2 = strpos($phrase_text, ')'); 
		$pos_length = $pos2 - $pos1;
		$pos_length = $pos_length - 1;
		$pos1 = $pos1 + 1;
		$max_count = substr($phrase_text, $pos1, $pos_length);		
		
		//########################################
		// default actionAddReply() code
		
		$this->_assertPostOnly();

		$forumId = $this->_input->filterSingle('node_id', XenForo_Input::UINT);
		$forumName = $this->_input->filterSingle('node_name', XenForo_Input::STRING);

		$ftpHelper = $this->getHelper('ForumThreadPost');
		$forum = $ftpHelper->assertForumValidAndViewable($forumId ? $forumId : $forumName);

		$forumId = $forum['node_id'];

		$this->_assertCanPostThreadInForum($forum);

		if (!XenForo_Captcha_Abstract::validateDefault($this->_input))
		{
			return $this->responseCaptchaFailed();
		}

		$visitor = XenForo_Visitor::getInstance();

		$input = $this->_input->filter(array(
			'title' => XenForo_Input::STRING,
			'prefix_id' => XenForo_Input::UINT,
			'attachment_hash' => XenForo_Input::STRING,

			'watch_thread_state' => XenForo_Input::UINT,
			'watch_thread' => XenForo_Input::UINT,
			'watch_thread_email' => XenForo_Input::UINT,

			'_set' => array(XenForo_Input::UINT, 'array' => true),
			'discussion_open' => XenForo_Input::UINT,
			'sticky' => XenForo_Input::UINT,

			'poll' => XenForo_Input::ARRAY_SIMPLE, // filtered below
		));
		$input['message'] = $this->getHelper('Editor')->getMessageText('message', $this->_input);
		$input['message'] = XenForo_Helper_String::autoLinkBbCode($input['message']);		
		
		//########################################
		// count number of smilies in message
		
		$smilie_count = 0;	
		foreach ($smilietext as $k => $v)
		{
			$smilie_count += substr_count($input['message'], $v['smilie_text']);
		}			

		// show error message if $smilie_count exceeds limit
		if ($smilie_count > $max_count) 
		{
			return $this->responseError(new XenForo_Phrase('please_reduce_the_number_of_smilies_to_or_less'));
		} else {
			// run the original actionAddThread() function 
			return parent::actionAddThread();
		}
	}
}

?>
 
Create the Smilie.php file:

library/Andy/SmilieCount/Model/Smilie.php

PHP:
<?php

class Andy_SmilieCount_Model_Smilie extends XFCP_Andy_SmilieCount_Model_Smilie
{
	public function getSmilieText()
	{
		return $this->_getDb()->fetchAll('
		SELECT smilie_text
		FROM xf_smilie');
	}
	
	public function getMaxSmilieCount()
	{
		return $this->_getDb()->fetchAll('
		SELECT phrase_text
		FROM xf_phrase
		WHERE title="please_reduce_the_number_of_smilies_to_or_less"');
	}	
}

?>
 
Top Bottom