• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Fixed  Replace the explicit call to Thread Model in XenForo_Model_Post

Shadab

Well-known member
#1
File /library/XenForo/Model/Post.php

1. In the canDeletePost() method (line 575), the Thread Model is fetched directly from the cache, instead of being called via _getThreadModel(). Which makes it hard for an inheriting class to easily change the model being returned by overriding _getThreadModel.
PHP:
return $this->getModelFromCache('XenForo_Model_Thread')->canDeleteThread(
	$thread, $forum, $deleteType, $errorPhraseKey, $nodePermissions, $viewingUser
);
All other calls to the Thread model in this class are made via _getThreadModel; this one is an exception.

2. Same with the User Model, in canViewIps() method (line 740).
PHP:
return $this->getModelFromCache('XenForo_Model_User')->canViewIps($errorPhraseKey, $viewingUser);
 

Mike

XenForo developer
Staff member
#2
The _getXModel aren't/weren't really expected targets for overriding. The getModelFromCache method pulls from XenForo_Model::create(), which calls load_class_model; that was the expected modification point.

I'm sort of curious what you're trying to do, and why load_class_model isn't the ideal way to do the override.

The main reason the _getXModel functions exist is for code completion in IDEs (that are smart enough to read the PHP doc return type).
 

Shadab

Well-known member
#3
Oops. Sorry I didn't explain clearly. I'm not trying to extend (XFCP) the Post model itself. I've created a new content-type, for which I'm using the Post model as a base class. There are more than 20 methods which I wouldn't need to implement in my model, since they would be simply inherited.

PHP:
class Shadab_Model_CustomPost extends XenForo_Model_Post
{
	/*
	 * Now I wouldn't need to implement any "permission check" methods.
	 * Thanks to the overriden _getThreadModel, the function calls
	 * will be correctly delegated to my custom model.
	 *
	 * Basically any method not containing an SQL query can be cleanly reused.
	 */

	protected function _getThreadModel()
	{
		return $this->getModelFromCache('Shadab_Model_CustomThread');
	}
}

class Shadab_Model_CustomThread extends XenForo_Model
{

}
Now if a method in the base class (in our case, canDeletePost) doesn't utilize _getXModel to fetch the model, I then have to copy that entire method to my child class and change the hardcoded value from "XenForo_Model_Thread" to "Shadab_Model_CustomThread" to make it work.
 

Mike

XenForo developer
Staff member
#4
I've changed this particular example, though I don't think it's strictly a safe thing to rely on.