redeclaration error for extended class

Jake Bunce

Well-known member
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?
 
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.
 
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?
 
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.
 
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.
 
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.
 
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:

Rich (BB 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)
			);
		}
	}
 
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)
 
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.
 
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.
 
Top Bottom