Jump to content
  • Status: Moved to Github

I have a custom application that extends the Item::buildCreateForm() function with this kind of code:

	/**
	 * Build form to create
	 *
	 * @param Model|NULL $container Container (e.g. forum), if appropriate
	 * @param Item|NULL $item Content item, e.g. if editing
	 * @return    Form
	 * @throws Exception
	 */
	protected static function buildCreateForm( Model|null $container=NULL, Item|null $item=NULL ): Form
	{
		# Parent call
		$form = parent::buildCreateForm( $container, $item );
		
		# Add custom headers: [ header title => insert after field ]
		foreach( [ 
			'header_1'	=> 'title',
			'header_2'	=> 'field_3',
			'header_3'	=> 'field_8',
			'header_4'	=> 'field_12'
			] as $header => $field )
		{
			$form->addHeader( static::$formLangPrefix . $header, static::$formLangPrefix . $field );
		}
		
		return $form;
	}

With this code, there should be 4 headers in the form output, but it always shows a single header because of a bug with the addHeader() function:

	/**
	 * Add Header
	 *
	 * @param string $lang		Language key
	 * @param string|null $after		The key of element to insert after
	 * @param string|null $tab		The tab to insert onto
	 * @return	void
	 */
	public function addHeader( string $lang, string $after=NULL, string $tab=NULL ) : void
	{
		/* Place the input into the correct position */
		$this->_insert( Theme::i()->getTemplate( 'forms', 'core' )->header( $lang, "{$this->id}_header_{$lang}" ), NULL, $tab, $after );
	}

The problem is that the second parameter, $elementKey, is always NULL, and causes an issue inside the _insert() function:

	/**
	 * Actually place the element in the correct position
	 *
	 * @param	mixed			$element	Thing we are adding (could be a form input, message, etc.)
	 * @param string|null $elementKey	The key of the element
	 * @param string|null $tab		The tab to insert this thing into
	 * @param string|null $after		The key of the element we want to insert this thing after
	 * @return	void
	 */
	protected function _insert( mixed $element, string $elementKey=NULL, string $tab=NULL, string $after=NULL ) : void
	{
		$tab = $tab ?: $this->currentTab;
		
		if ( $after )
		{
			$elements = array();
			foreach ( $this->elements[ $tab ] as $key => $_element )
			{
				$elements[ $key ] = $_element;
				if ( $key === $after )
				{
					$elements[ $elementKey ] = $element;
				}
			}
			$this->elements[ $tab ] = $elements;
		}
		elseif( $elementKey )
		{
			$this->elements[ $tab ][ $elementKey ] = $element;
		}
		else
		{
			$this->elements[ $tab ][] = $element;
		}
	}

Specifically, this is the problematic code:


				if ( $key === $after )
				{
					$elements[ $elementKey ] = $element;
				}

Because $elementKey is NULL, the code always overwrites the same array key, and the form ends up with a single header instead of 4.

===

The same issue can also happen with these other functions that also pass the $elementKey always with a NULL value:

  • addSeparator

  • addMessage

  • addHtml

  • addDummy

I have the same issue in a similar v4 application. If you could apply the fix to both versions, that would be great. 🙃

For now, as a temporary workaround, I'll overwrite the whole function and add the headers differently.

User Feedback

Recommended Comments

There are no comments to display.