Fuhrmann
Well-known member
Hey guys. I hope the last tutorial was not to hard.
FIRST PART HERE
SECOND PART HERE
In this tutorial we'll be making something more complex. We will be using more PHP code and go throug the XenForo's code.
So before we start, i really recomend you guys to use some IDE for programming in PHP. There is a tutorial made by Kier and you can see it HERE
So, your PHP EDITOR (or something) is ready? Let's go then.
Step 1 - Defining our mission
Remember in the previous tutorial that we put some new info in our content tab? We've used the Custom User Fields to make a field called "Favorite Band" and put in our content tab.
We also learn about conditionals and some other things.
Now, let's navigate throug the files of Xenforo so we can make what we want.
This tutorial will teach you how to put all likes that user gave to other users in his profile page, in our tab.
So all the tabs will make a group, like this:
Profile Page
---Profile Posts
---Recent Activity
---Postings
---Information
---Our Tab
This tutorial use some knowlogde of MVC structure, php code and other things.
Step 2 - How we will do that?
So, first of all, you have to know that not always we need to reinvent the wheel.
"I know, Fuhrmann, go to the point!".
Sure. What i am saying is maybe in some XenForo's files can exist a method that list all the user's likes that he gave. Dont you think? Yes. I always think this way. So the first thing i do, is looking for a method that already do what i want. So i dont need to make any calls to the database, i just have to use the right function.
In Xenforo structure (library/XenForo we have so many folders/files, see:

XenForo use the MVC structure:
Model: In this layer are defined rules of access and manipulation of data, which often stored in databases or files, but nothing indicates that serve accommodation only for persistent data. Can be used for data in volatile memory, eg RAM, although such use does not happen very often. All rules related to treatment, obtaining and validating data must be implemented in this layer.
View: This layer is responsible for generating the way the answer is displayed, web page, form, report, etc..
Controller: It is the layer responsible for responding to requests by the user. Whenever a user makes a request to the server layer is the first to be executed.
1. The user makes a request to the server.
2. The controller processes the user request.
3. The controller makes a call to the model, to retrieve or manipulate data.
4. The model returns the requested data will be passed to the view.
5. The view generates the presentation of data, eg an HTML page.
This explanation is just a resume. The purpose of the tutorial is not to get deeper in the MVC.
Well, lets see, in Model we have this:
...rules of access and manipulation of data...
So, this is what we want! A method that gonna call all user's likes that he gave with a query to the database. But, what doest that mean?
This mean something...
Look:
In the XenForo folder (library/XenForo) we have this structure:
--AdminSearchHandler
--AlertHandler
--AttachmentHandler
____OTHER FOLDERS____
--Importer
--Install
--LikeHandler
--Model
....
See? There is the model folder. All the model files are stored in there. So, thats a tip that our method should be in there. Go into the folder Model.
You will se a lot of more files and files. So confusing! But not to much. Think, we want a method that select all the user's likes. Let's look for some file called Like and see what we find.

Yes, there is a file called Like.php!
Open this file.
We see a bunch of methods and comments. That's good, will help us. So, looking for what we want, i found something:
But...no, wait! Oh, ********!
I think that's not what we want. See below, there is a example of the structure of the database table xf_liked_content that holds all the likes given:
like_idcontent_type = 1
content_id = post
like_user_id = 2
like_date= 1318342341
content_user_id = 1
like_user_id is the ID of the user who actually LIKED the content.
content_user_id is the ID of the user who actually RECEIVED the like.
We want to get all the likes were GIVEN by user_x. The method above, select all the likes of the user who received the likes. We want the givers.
(I just wanna make sure that's obvious other MANY ways to look files throug in XenForo. The way i teach, is the way i like, started. So, you can use your own way to find methods and other things inside the files of XenForo.)
Step 3 - the Model - Like
As we know, in the Model we "defined rules of access and manipulation of data, which often stored in databases or files". But if we want to create our own methods to manipulate data in XenForo? Customizable methods?
Well, then we have to extend the Model or create one for our add-on. In this case, we gonna create one.
Dont need to extend, because we wont use any parent method (Thanks to point me out ragtek!)
To do that, lets create the file that will be responsable for the model.
Remember the structure of folders and files we have so far? This:
library
-- newProfileTabs
----- Listener.php
Now let's create one more file, called newProfileModel.php, because we'll create a model for our addon with own method. I always follow a pattern of folders and filenames, so this is how i use and what you got if you follow my directions:
library
-- newProfileTabs
----- Model (new folder)
---------- newProfileModel.php (our new file!)
----- Listener.php
Open our new file (newProfileModel.php). We need to give it a class name. So, as always, we follow the directories structure. So our file newProfileModel.php will be:
We are extending to XenForo_Model because we are creating a Model. That way we can acess any other functions of the base class Model
We will know create our method to get the data from data base and return all we want: all the like that user gave.
So, our final version of file newProfileModel.php will be this:
I will not explain the SQL query, assuming that you already have a base of it.
So, there is our function. What this do?
- Select all fields from the xf_liked_content table WHERE the like_user_id field is equal what we pass throug the method.
- Also, select username field from xf_user table where the user_id field is equal to content_user_id field.
- Also select post.* for us to show the post of the user who received the like and some other fields.
Save, and let open. Now we will extend other file. The controlller.
FIRST PART HERE
SECOND PART HERE
In this tutorial we'll be making something more complex. We will be using more PHP code and go throug the XenForo's code.
So before we start, i really recomend you guys to use some IDE for programming in PHP. There is a tutorial made by Kier and you can see it HERE
So, your PHP EDITOR (or something) is ready? Let's go then.
Step 1 - Defining our mission
Remember in the previous tutorial that we put some new info in our content tab? We've used the Custom User Fields to make a field called "Favorite Band" and put in our content tab.
We also learn about conditionals and some other things.
Now, let's navigate throug the files of Xenforo so we can make what we want.
This tutorial will teach you how to put all likes that user gave to other users in his profile page, in our tab.
So all the tabs will make a group, like this:
Profile Page
---Profile Posts
---Recent Activity
---Postings
---Information
---Our Tab
This tutorial use some knowlogde of MVC structure, php code and other things.
Step 2 - How we will do that?
So, first of all, you have to know that not always we need to reinvent the wheel.
"I know, Fuhrmann, go to the point!".
Sure. What i am saying is maybe in some XenForo's files can exist a method that list all the user's likes that he gave. Dont you think? Yes. I always think this way. So the first thing i do, is looking for a method that already do what i want. So i dont need to make any calls to the database, i just have to use the right function.
In Xenforo structure (library/XenForo we have so many folders/files, see:

XenForo use the MVC structure:
Model: In this layer are defined rules of access and manipulation of data, which often stored in databases or files, but nothing indicates that serve accommodation only for persistent data. Can be used for data in volatile memory, eg RAM, although such use does not happen very often. All rules related to treatment, obtaining and validating data must be implemented in this layer.
View: This layer is responsible for generating the way the answer is displayed, web page, form, report, etc..
Controller: It is the layer responsible for responding to requests by the user. Whenever a user makes a request to the server layer is the first to be executed.
1. The user makes a request to the server.
2. The controller processes the user request.
3. The controller makes a call to the model, to retrieve or manipulate data.
4. The model returns the requested data will be passed to the view.
5. The view generates the presentation of data, eg an HTML page.
This explanation is just a resume. The purpose of the tutorial is not to get deeper in the MVC.
Well, lets see, in Model we have this:
...rules of access and manipulation of data...
So, this is what we want! A method that gonna call all user's likes that he gave with a query to the database. But, what doest that mean?
This mean something...
Look:
In the XenForo folder (library/XenForo) we have this structure:
--AdminSearchHandler
--AlertHandler
--AttachmentHandler
____OTHER FOLDERS____
--Importer
--Install
--LikeHandler
--Model
....
See? There is the model folder. All the model files are stored in there. So, thats a tip that our method should be in there. Go into the folder Model.
You will se a lot of more files and files. So confusing! But not to much. Think, we want a method that select all the user's likes. Let's look for some file called Like and see what we find.

Yes, there is a file called Like.php!
Open this file.
We see a bunch of methods and comments. That's good, will help us. So, looking for what we want, i found something:
PHP:
/**
* Gets likes based on the content user.
*
* @param integer $userId
* @param array $fetchOptions Fetch options. Supports limit only now.
*
* @return array Format: [like id] => info
*/
public function getLikesForContentUser($userId, array $fetchOptions = array())
{
$limitOptions = $this->prepareLimitFetchOptions($fetchOptions);
return $this->fetchAllKeyed($this->limitQueryResults(
'
SELECT liked_content.*,
user.*
FROM xf_liked_content AS liked_content
INNER JOIN xf_user AS user ON (user.user_id = liked_content.like_user_id)
WHERE liked_content.content_user_id = ?
ORDER BY liked_content.like_date DESC
', $limitOptions['limit'], $limitOptions['offset']
), 'like_id', $userId);
}
But...no, wait! Oh, ********!
I think that's not what we want. See below, there is a example of the structure of the database table xf_liked_content that holds all the likes given:
like_idcontent_type = 1
content_id = post
like_user_id = 2
like_date= 1318342341
content_user_id = 1
like_user_id is the ID of the user who actually LIKED the content.
content_user_id is the ID of the user who actually RECEIVED the like.
We want to get all the likes were GIVEN by user_x. The method above, select all the likes of the user who received the likes. We want the givers.
(I just wanna make sure that's obvious other MANY ways to look files throug in XenForo. The way i teach, is the way i like, started. So, you can use your own way to find methods and other things inside the files of XenForo.)
Step 3 - the Model - Like
As we know, in the Model we "defined rules of access and manipulation of data, which often stored in databases or files". But if we want to create our own methods to manipulate data in XenForo? Customizable methods?
Well, then we have to extend the Model or create one for our add-on. In this case, we gonna create one.
Dont need to extend, because we wont use any parent method (Thanks to point me out ragtek!)
To do that, lets create the file that will be responsable for the model.
Remember the structure of folders and files we have so far? This:
library
-- newProfileTabs
----- Listener.php
Now let's create one more file, called newProfileModel.php, because we'll create a model for our addon with own method. I always follow a pattern of folders and filenames, so this is how i use and what you got if you follow my directions:
library
-- newProfileTabs
----- Model (new folder)
---------- newProfileModel.php (our new file!)
----- Listener.php
Open our new file (newProfileModel.php). We need to give it a class name. So, as always, we follow the directories structure. So our file newProfileModel.php will be:
PHP:
<?php
class newProfileTabs_Model_newProfileModel extends XenForo_Model
{
}
?>
We are extending to XenForo_Model because we are creating a Model. That way we can acess any other functions of the base class Model
We will know create our method to get the data from data base and return all we want: all the like that user gave.
So, our final version of file newProfileModel.php will be this:
PHP:
<?php
class newProfileTabs_Model_newProfileModel extends XenForo_Model
{
public function getAllGivenLikesByUser ($userId, $howMuch)
{
$db = $this->_getDb();
//Query the database with what we wat
return $this->fetchAllKeyed('
SELECT
liked_content.*,
user.username as receive_username,
post.*
FROM xf_liked_content AS liked_content
INNER JOIN xf_user AS user ON (user.user_id = liked_content.content_user_id)
LEFT JOIN xf_post AS post ON (post.post_id = liked_content.content_id)
WHERE liked_content.like_user_id = ?
ORDER BY liked_content.like_date DESC
', 'like_id', $userId);
}
}
?>
I will not explain the SQL query, assuming that you already have a base of it.
So, there is our function. What this do?
- Select all fields from the xf_liked_content table WHERE the like_user_id field is equal what we pass throug the method.
- Also, select username field from xf_user table where the user_id field is equal to content_user_id field.
- Also select post.* for us to show the post of the user who received the like and some other fields.
Save, and let open. Now we will extend other file. The controlller.