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

redeclaration error for extended class

Jake Bunce

XenForo moderator
Staff member
#1
In my addon I want to add the same _postDispatch to multiple controllers. This would be my listener:

Code:
		if (in_array($class, array(
			'XenForo_ControllerPublic_Page',
			'XenForo_ControllerPublic_Forum',
			'XenForo_ControllerPublic_Category',
			'XenForo_ControllerPublic_LinkForum',
			'XenForo_ControllerPublic_Thread',
			'XenForo_ControllerPublic_Post'
		)))
		{
			$extend[] = 'NodesAsTabs_ControllerPublic_Generic';
		}
I encountered a problem where I get a redeclaration error if multiple of those controllers are used in a single execution. My solution was to simply duplicate my extended class for each controller. But ideally I would like to have just one generic extended class for all of them.

Can this redeclaration error be addressed internally? Or can anyone suggest another method to avoid having to duplicate my extended class?
 

infis

Well-known member
#2
Though the parent at them one, but is different classes. Accordingly at extending classes nevertheless it is necessary to write different handlers for all classes.
Probably, it turns out extend class Abstract and already it to use, but it is not assured.
 

digitalpoint

Well-known member
#3
While not an ideal solution, the best one I can think of (that would work without modifying XF source) would be what infis mentions... have all your code thrown into an abstract class, and then define 1 class for each controller type that really is nothing more than extending the abstract class.... you would end up with 6 classes + the abstraction, but the 6 classes would be just one line of code per.

Even if XenForo_Application checked for existing class declaration before creating the "virtual" classes, I'm not sure you would even WANT to stop it, because it would mean that any secondary controllers wouldn't get the functions you are trying to add.

I'm curious why you have multiple controller trying to initialize on a single request though... seems kind of odd, because well... they are the controller... if you have 2 of them, who's in control?
 

Jake Bunce

XenForo moderator
Staff member
#4
I'm curious why you have multiple controller trying to initialize on a single request though... seems kind of odd, because well... they are the controller... if you have 2 of them, who's in control?
That was my thinking which is why I started by trying to use one class to extend all six controllers. It worked fine for the most part, but I found that the inline post edit was using two controllers somehow. I had to debug the javascript to pull out a redeclaration error. The error was resolved by duplicating my extended class for each controller.
 

Jake Bunce

XenForo moderator
Staff member
#5
While not an ideal solution, the best one I can think of (that would work without modifying XF source) would be what infis mentions... have all your code thrown into an abstract class, and then define 1 class for each controller type that really is nothing more than extending the abstract class.... you would end up with 6 classes + the abstraction, but the 6 classes would be just one line of code per.
Yeah I thought about that. That is better than my current solution and I may end up going that route. But it would still be nice to have just one class.
 

digitalpoint

Well-known member
#6
Yeah I thought about that. That is better than my current solution and I may end up going that route. But it would still be nice to have just one class.
Yeah, just don't think it's possible with the way XenForo loads classes by loading them as virtual classes.

But honestly, if XenForo is initializing two different controllers for a single request, you might check with Mike or Kier and see if that's intended or a bug.
 

Jake Bunce

XenForo moderator
Staff member
#7
I can go back and try to reproduce it. Looking at the code I think it was caused by this:

XenForo_ControllerPublic_Post::actionSaveInline

Highlighted in red. You can see the Post controller rerouting to the Thread controller:

Code:
	public function actionSaveInline()
	{
		$this->_assertPostOnly();

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

		$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);

		$dw = XenForo_DataWriter::create('XenForo_DataWriter_DiscussionMessage_Post');
		$dw->setExistingData($postId);
		$dw->set('message',
			XenForo_Helper_String::autoLinkBbCode(
				$this->getHelper('Editor')->getMessageText('message', $this->_input)
			)
		);
		$dw->setExtraData(XenForo_DataWriter_DiscussionMessage_Post::DATA_FORUM, $forum);
		$dw->save();

		XenForo_Model_Log::logModeratorAction('post', $post, 'edit', array(), $thread);

		if ($this->_noRedirect())
		{
			$this->_request->setParam('thread_id', $thread['thread_id']);

			return $this->responseReroute('XenForo_ControllerPublic_Thread', 'show-posts');
		}
		else
		{
			return $this->responseRedirect(
				XenForo_ControllerResponse_Redirect::SUCCESS,
				XenForo_Link::buildPublicLink('posts', $post)
			);
		}
	}
 

digitalpoint

Well-known member
#8
Another thing I thought of... if you don't care about your function not being available in controller after the first one, you could use the class_exists () php function to check if it's been loaded already in your extend logic...

PHP:
class_exists('NodesAsTabs_ControllerPublic_Generic', false)
 

Jeremy

Well-known member
#9
Yeah, just don't think it's possible with the way XenForo loads classes by loading them as virtual classes.

But honestly, if XenForo is initializing two different controllers for a single request, you might check with Mike or Kier and see if that's intended or a bug.
It happens when attempting to extend on the BBCode formatters as well.
 

Mike

XenForo developer
Staff member
#10
You basically would have to name a different class for each class you want to extend. Doing the class_exists check isn't good (in terms of doing what you want), as the second call won't extend the controller.
 

guiltar

Well-known member
#12