<?php
declare(strict_types=1);

namespace app\components\behaviors;

use app\helpers\RoleHelper;

use Yii;
use yii\behaviors\AttributeBehavior;
use yii\db\BaseActiveRecord;

/**
* Behavior
* @url https://www.yiiframework.com/doc/guide/2.0/en/concept-behaviors
* @url https://www.yiiframework.com/doc/api/2.0/yii-base-behavior
*
* Behaviors are instances of yii\base\Behavior, or of a child class. Behaviors, also known as mixins, allow 
* you to enhance the functionality of an existing component class without needing to change the class's inheritance. 
* Attaching a behavior to a component "injects" the behavior's methods and properties into the component, making those 
* methods and properties accessible as if they were defined in the component class itself. Moreover, a behavior can respond 
* to the events triggered by the component, which allows behaviors to also customize the normal code execution of the component.
*
* IP Behaviour
* @url https://github.com/ruskid/yii2-ip-behavior/blob/master/IpBehavior.php
*
*	public function behaviors() {
*		return [
*			'ip' => [
*				'class' => IpBehavior::className(),
*				'attributes' => [
*					ActiveRecord::EVENT_BEFORE_INSERT => ['created_ip', 'updated_ip'],
*					ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_ip',
*				],
*			]
*		];
*	}
*
* Or like this. where value can be a string or an anonymous function that will return a string:
*
*	public function behaviors() {
*		return [
*			'ip' => [
*				'class' => IpBehavior::className(),
*				'createdIpAttribute' => 'created_ip',
*				'updatedIpAttribute' => 'updated_ip',
*				'value' => '127.0.0.1',
*			]
*		];
*	}
*
* Extras:
* This will set user's IP address to the attribute of the model.
*
*	$user->setIp('updated_ip');
*/
class IpBehavior extends AttributeBehavior
{
	/**
	* @var string the attribute that will receive IP value on create.
	* Set to false if you do not want record it
	*/
	public $createdIpAttribute = 'created_ip';
	
	/**
	* @var string the attribute that will receive IP value on update.
	* Set to false if you do not want record it
	*/
	public $updatedIpAttribute = 'updated_ip';
	
	/**
	* @var callable|string
	* This can be either an anonymous function that returns the IP value or a string.
	* If not set, it will use the value of `\Yii::$app->request->userIp` to set the attributes.
	* NOTE! Null is returned if the user IP address cannot be detected.
	*/
	public $value;
	
	/**
	* Initializes the object.
	* @url https://www.yiiframework.com/doc/guide/2.0/en/concept-components
	* @url https://www.yiiframework.com/doc/api/2.0/yii-base-model#init()-detail
	*
	* This method is invoked at the end of the constructor after the object is initialized with the
	* given configuration.
	*/
	public function init()
	{
		/**
		* Call to parent constructor
		*
		* Always call the parent init method first to ensure any
		* initialization logic defined in the base class is executed first.
		*
		* It is important to invoke the parent init method first to 
		* ensure that the properly set up before you add any additional 
		* functionality in this subclass.
		*/
		parent::init();
		
		// ... initialization after configuration is applied...
		
		if (empty($this->attributes)) {
			
			$this->attributes = [
		 		BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdIpAttribute, $this->updatedIpAttribute],
		 		BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedIpAttribute,
		 	];
		 }
	}
	
	/**
	* @inheritdoc
	*/
	protected function getValue($event)
	{
		if (is_string($this->value)) {
		
			return $this->value;
		}
		else {
			return $this->value !== null ? call_user_func($this->value, $event) : RoleHelper::userIp();
		}
	}
	
	/**
	* Sets an IP address to the attribute.
	* @param string $attribute the name of the attribute to update.
	*
	*	$model->setIp('updated_ip');
	*/
	public function setIp($attribute)
	{
		$this->owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
	}
}


Is it possible to get this to work with react being the frontend?