Add an attribute with a decorator, but private?

Help for integrating the Laravel package
Forum rules
Always add your Laravel, Aimeos and PHP version as well as your environment (Linux/Mac/Win)
Spam and unrelated posts will be removed immediately!
kdim95
Advanced
Posts: 192
Joined: 26 Aug 2022, 12:17

Add an attribute with a decorator, but private?

Post by kdim95 » 23 May 2023, 13:06

Hello,

I'm attempting to add another attribute to the Review item, but have it private.
The attribute is supposed to store the user IP of the reviewer.

The problem is that the IP attribute is visible in the json response when searching for reviews with the jsonapi.
I attempted to add the " 'public' => false " key thinking that it would solve this problem, but it did not solve it.
private $attr = [
'ip' => [
'code' => 'ip',
'internalcode' => 'mrev."ip"',
'label' => 'Customer IP address',
'type' => 'string',
'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
'public' => false,
]
];
Apparently this is being handled in the Review Item itself in the toArray() method.

What is the proper way to create custom attributes which are private?

User avatar
aimeos
Administrator
Posts: 7858
Joined: 01 Jan 1970, 00:00

Re: Add an attribute with a decorator, but private?

Post by aimeos » 25 May 2023, 06:32

At the moment, the only way is to overwrite the toArray() method in your own review item:
https://github.com/aimeos/aimeos-core/b ... #L304-L324

How to overwrite items and managers:
https://aimeos.org/docs/latest/models/e ... custom-way
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

kdim95
Advanced
Posts: 192
Joined: 26 Aug 2022, 12:17

Re: Add an attribute with a decorator, but private?

Post by kdim95 » 25 May 2023, 08:27

I did it a bit differently before you responded. Is this solution safe to work with?

I created a Review Manager Decorator, a custom Review Manager and a custom Review Item.

In the custom Review Item, I use unset() to remove the ip if its private.

This way I don't have to override the database manager insert, update, search configs.

Review Manager Decorator ( add IP attribute ):

Code: Select all

<?php

namespace Aimeos\MShop\Review\Manager\Decorator;

class MyDecorator
    extends \Aimeos\MShop\Common\Manager\Decorator\Base
    implements \Aimeos\MShop\Common\Manager\Decorator\Iface
{
    private $attr = [
        'ip' => [
			'code' => 'ip',
			'internalcode' => 'mrev."ip"',
			'label' => 'Customer IP address',
			'type' => 'string',
			'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,
            'public' => false,
        ],
    ];

    public function getSaveAttributes() : array
    {
        return parent::getSaveAttributes() + $this->createAttributes( $this->attr );
    }
	
	public function getSearchAttributes( bool $sub = true ) : array
    {
        return parent::getSearchAttributes( $sub ) + $this->createAttributes( $this->attr );
    }
}
Custom Review Item ( implement getIp(), setIp(), fromArray() and toArray() methods ):

Code: Select all

<?php

namespace Aimeos\MShop\Review\Item;

class StandardCustom extends Standard
{
	public function getIp() : ?string
	{
		return (string) $this->get( 'ip', 1 );
	}

	public function setIp( ?string $value ) : \Aimeos\MShop\Common\Item\Iface
	{
		return $this->set( 'ip', $value );
	}

	public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
	{
		$item = parent::fromArray( $list, $private );

		foreach( $list as $key => $value )
		{
			switch( $key )
			{
				case 'ip': !$private ?: $item = $item->setIp( $value ); break;
				default: continue 2;
			}

			unset( $list[$key] );
		}

		return $item;
	}

	public function toArray( bool $private = false ) : array
	{
		$list = parent::toArray( $private );

		if( ! $private )
		{
			unset( $list['ip'] );
		}

		return $list;
	}
}
Custom Review Manager ( implement createItemBase() to return custom Review Item ):

Code: Select all

<?php

namespace Aimeos\MShop\Review\Manager;

class StandardCustom extends Standard
{
    // Return custom review item
	protected function createItemBase( array $values = [] ) : \Aimeos\MShop\Review\Item\Iface
	{
		return new \Aimeos\MShop\Review\Item\StandardCustom( $values );
	}
}

User avatar
aimeos
Administrator
Posts: 7858
Joined: 01 Jan 1970, 00:00

Re: Add an attribute with a decorator, but private?

Post by aimeos » 25 May 2023, 08:36

Yes, that's OK and the minimum code you need.
Professional support and custom implementation are available at Aimeos.com
If you like Aimeos, Image give us a star

Post Reply