mautic / app /bundles /LeadBundle /Entity /CustomFieldEntityTrait.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace Mautic\LeadBundle\Entity;
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
use Mautic\LeadBundle\Field\SchemaDefinition;
use Mautic\LeadBundle\Helper\CustomFieldHelper;
use Mautic\LeadBundle\Helper\CustomFieldValueHelper;
trait CustomFieldEntityTrait
{
/**
* Used by Mautic to populate the fields pulled from the DB.
*
* @var array
*/
protected $fields = [];
/**
* Just a place to store updated field values so we don't have to loop through them again comparing.
*
* @var array
*/
protected $updatedFields = [];
/**
* A place events can use to pass data around on the object to prevent issues like creating a contact and having it processed to be sent back
* to the origin of creation in a webhook.
*
* @var array
*/
protected $eventData = [];
/**
* @return bool
*/
public function __get($name)
{
return $this->getFieldValue(strtolower($name));
}
/**
* @return $this
*/
public function __set($name, $value)
{
return $this->addUpdatedField(strtolower($name), $value);
}
/**
* @param string $name
*
* @return mixed
*/
public function __call($name, $arguments)
{
$isSetter = str_starts_with($name, 'set');
$isGetter = str_starts_with($name, 'get');
if (($isSetter && array_key_exists(0, $arguments)) || $isGetter) {
$fieldRequested = mb_strtolower(mb_substr($name, 3));
$fields = $this->getProfileFields();
if (array_key_exists($fieldRequested, $fields)) {
return ($isSetter) ? $this->addUpdatedField($fieldRequested, $arguments[0]) : $this->getFieldValue($fieldRequested);
}
}
return parent::__call($name, $arguments);
}
public function setFields($fields): void
{
$this->fields = CustomFieldValueHelper::normalizeValues($fields);
}
/**
* @param bool $ungroup
*
* @return array
*/
public function getFields($ungroup = false)
{
if ($ungroup && isset($this->fields['core'])) {
$return = [];
foreach ($this->fields as $fields) {
$return += $fields;
}
return $return;
}
return $this->fields;
}
/**
* Add an updated field to persist to the DB and to note changes.
*
* @param string $oldValue
*
* @return $this
*/
public function addUpdatedField($alias, $value, $oldValue = null)
{
// Don't allow overriding ID
if ('id' === $alias) {
return $this;
}
$property = (defined('self::FIELD_ALIAS')) ? str_replace(self::FIELD_ALIAS, '', $alias) : $alias;
$field = $this->getField($alias);
$setter = 'set'.ucfirst($property);
if (null == $oldValue) {
$oldValue = $this->getFieldValue($alias);
} elseif ($field) {
$oldValue = CustomFieldHelper::fixValueType($field['type'], $oldValue);
}
if (property_exists($this, $property) && method_exists($this, $setter)) {
// Fixed custom field so use the setter but don't get caught in a loop such as a custom field called "notes"
// Set empty value as null
if ('' === $value) {
$value = null;
}
$this->$setter($value);
}
if (is_string($value)) {
$value = trim($value);
if ('' === $value) {
// Ensure value is null for consistency
$value = null;
if ('' === $oldValue) {
$oldValue = null;
}
}
} elseif (is_array($value)) {
// Flatten the array
$value = implode('|', $value);
}
if ($field) {
$value = CustomFieldHelper::fixValueType($field['type'], $value);
}
if ($oldValue !== $value && !(('' === $oldValue && null === $value) || (null === $oldValue && '' === $value))) {
$this->addChange('fields', [$alias => [$oldValue, $value]]);
$this->updatedFields[$alias] = $value;
}
return $this;
}
/**
* Get the array of updated fields.
*
* @return array
*/
public function getUpdatedFields()
{
return $this->updatedFields;
}
/**
* @param string $field
* @param string|null $group
*
* @return mixed
*/
public function getFieldValue($field, $group = null)
{
if (property_exists($this, $field)) {
$value = $this->{'get'.ucfirst($field)}();
if (null !== $value) {
return $value;
}
}
if (array_key_exists($field, $this->updatedFields)) {
return $this->updatedFields[$field];
}
if ($field = $this->getField($field, $group)) {
return CustomFieldHelper::fixValueType($field['type'], $field['value']);
}
return null;
}
/**
* Get field details.
*
* @param string $key
* @param string $group
*
* @return array|false
*/
public function getField($key, $group = null)
{
if ($group && isset($this->fields[$group][$key])) {
return $this->fields[$group][$key];
}
foreach ($this->fields as $groupFields) {
foreach ($groupFields as $name => $details) {
if ($name == $key) {
return $details;
}
}
}
return false;
}
/**
* Get profile values.
*
* @return array
*/
public function getProfileFields()
{
if (isset($this->fields['core'])) {
$fieldValues = [
'id' => $this->id,
];
foreach ($this->fields as $group => $fields) {
if ('all' === $group) {
continue;
}
foreach ($fields as $alias => $field) {
$fieldValues[$alias] = $field['value'];
}
}
return array_merge($fieldValues, $this->updatedFields);
} else {
// The fields are already flattened
return $this->fields;
}
}
public function hasFields(): bool
{
return !empty($this->fields);
}
public function getEventData($key)
{
return $this->eventData[$key] ?? null;
}
/**
* @return $this
*/
public function setEventData($key, $value)
{
$this->eventData[$key] = $value;
return $this;
}
protected static function loadFixedFieldMetadata(ClassMetadataBuilder $builder, array $fields, array $customFieldDefinitions)
{
foreach ($fields as $fieldProperty) {
$field = (defined('self::FIELD_ALIAS')) ? self::FIELD_ALIAS.$fieldProperty : $fieldProperty;
$type = 'text';
if (isset($customFieldDefinitions[$field]) && !empty($customFieldDefinitions[$field]['type'])) {
$type = $customFieldDefinitions[$field]['type'];
}
$builder->addNamedField(
$fieldProperty,
SchemaDefinition::getSchemaDefinition($field, $type, !empty($customFieldDefinitions[$field]['unique']))['type'],
$field,
true
);
}
}
}