Check if exists Name, HttpEquiv and Property in HeadMeta

Hello I have a situation in HeadMeta where I would like to test if a meta tag exists and then insert a value the same, for example:

layout.phtml:

$this->headMeta()->setName('description', 'description website default');

product.phtml:

$this->headMeta()->setName('description', 'description product');

I would like something like:

layout.phtml:

if (! $this->headMeta()->existsName('description')) {
    $this->headMeta()->setName('description', 'description website default');
}

This is because product.phtml is processed before layout.phtml therefore the “description” meta tag of product.phtml is replaced by that of layout.phtml.

Is there already a way to do this?

Quick Tip

You should activate the IDE auto-completion in your templates. Add the following lines to your .phtml files:

<?php
/**
 * @var Laminas\View\Renderer\PhpRenderer $this
 */
?>

Then the existing methods are displayed.

I thought about proposing a modification in HeadMeta:

    /**
     * Retrieve object instance; optionally add meta tag
     *
     * @param  string $content
     * @param  string $keyValue
     * @param  string $keyType
     * @param  array  $modifiers
     * @param  string $placement
     * @return HeadMeta
     */
    public function __invoke(
        $content = null,
        $keyValue = null,
        $keyType = 'name',
        $modifiers = [],
        $placement = Placeholder\Container\AbstractContainer::APPEND
    ) {
        if ((null !== $content) && (null !== $keyValue)) {
            $item   = $this->createData($keyType, $keyValue, $content, $modifiers);
            $action = strtolower($placement);
            switch ($action) {
                case 'append':
                case 'prepend':
                case 'set':
				case 'exists':
                    $this->$action($item);
                    break;
                default:
                    $this->append($item);
                    break;
            }
        }

        return $this;
    }

    /**
     * Overload method access
     *
     * @param  string $method
     * @param  array  $args
     * @throws Exception\BadMethodCallException
     * @return HeadMeta
     */
    public function __call($method, $args)
    {
        if (preg_match(
            '/^(?P<action>set|(pre|ap)pend|offsetSet|exists)(?P<type>Name|HttpEquiv|Property|Itemprop)$/',
            $method,
            $matches
        )) {
            $action = $matches['action'];
            $type   = $this->normalizeType($matches['type']);
            $argc   = count($args);
            $index  = null;
			
			if ('exists' == $action ) {
				$item  = $this->createData($type, $args[0], '', []);
				return $this->exists($item);
			}
			
            if ('offsetSet' == $action ) {
                if (0 < $argc) {
                    $index = array_shift($args);
                    --$argc;
                }
            }

            if (2 > $argc) {
                throw new Exception\BadMethodCallException(
                    'Too few arguments provided; requires key value, and content'
                );
            }

            if (3 > $argc) {
                $args[] = [];
            }

            $item  = $this->createData($type, $args[0], $args[1], $args[2]);

            if ('offsetSet' == $action) {
                return $this->offsetSet($index, $item);
            }

            $this->$action($item);

            return $this;
        }

        return parent::__call($method, $args);
    }

    /**
     * Exists
     *
     * @param  stdClass $value
     * @throws Exception\InvalidArgumentException
     * @return View\Helper\Placeholder\Container\AbstractContainer
     */
    public function exists($value)
    {
        if (! $this->isValid($value)) {
            throw new Exception\InvalidArgumentException('Invalid value passed to checks exists');
        }

        $container = $this->getContainer();
        foreach ($container->getArrayCopy() as $index => $item) {
            if ($item->type == $value->type && $item->{$item->type} == $value->{$value->type}) {
                return true;
            }
        }

        return false;
    }

In this way we started to have the “exists” method, this can be extended to other similar classes like HeadScript, HeadStyle and HeadLink.