Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Behavior/CustomFieldsHolder.php
<?php

namespace XF\Behavior;

use
XF\Mvc\Entity\Behavior;

use function
is_array, is_string;

class
CustomFieldsHolder extends Behavior
{
    protected function
getDefaultConfig()
    {
        return [
           
'column' => 'custom_fields',
           
'valueTable' => null,
           
'keyColumn' => null,
           
'checkForUpdates' => null,
           
'getAllowedFields' => null
       
];
    }

    protected function
verifyConfig()
    {
        if (!
$this->config['valueTable'])
        {
            throw new \
LogicException("The valueTable configuration must be specified");
        }

        if (!
$this->config['keyColumn'])
        {
           
$key = $this->entity->structure()->primaryKey;
            if (
is_string($key))
            {
               
$this->config['keyColumn'] = $key;
            }
            else
            {
                throw new \
LogicException("The keyColumn configuration could not be derived and must be specified");
            }
        }

        if (
$this->config['checkForUpdates'] && !is_callable($this->config['getAllowedFields']))
        {
            throw new \
LogicException("getAllowedFields must be specified to use checkForUpdates");
        }
    }

    public function
preSave()
    {
       
$entity = $this->entity;
       
$checkForUpdates = $this->config['checkForUpdates'];

        if (
$checkForUpdates)
        {
            if (
$entity->isUpdate() && $entity->isChanged($checkForUpdates))
            {
               
/** @var \XF\CustomField\Set $fieldSet */
               
$fieldSet = $entity->get($this->config['column']);
                if (!(
$fieldSet instanceof \XF\CustomField\Set))
                {
                    throw new \
LogicException("Primary column must return a XF\CustomField\Set object (via a getter)");
                }

               
$getAllowedFields = $this->config['getAllowedFields'];
               
$allowedFields = $getAllowedFields($entity);

                foreach (
$fieldSet->getFieldValues() AS $fieldId => $null)
                {
                    if (!isset(
$allowedFields[$fieldId]))
                    {
                       
$fieldSet->removeFieldValue($fieldId);
                    }
                }
            }
        }
    }

    public function
postSave()
    {
       
$column = $this->config['column'];
       
$entity = $this->entity;

        if (
$entity->isChanged($column))
        {
           
$newSet = $entity->getValue($column);
           
$oldSet = $entity->isUpdate() ? $entity->getExistingValue($column) : [];

            if (
$entity->isInsert() && !$newSet)
            {
               
// nothing to do
               
return;
            }

           
$removedKeys = [];
           
$replacements = [];

            foreach (
$oldSet AS $key => $oldValue)
            {
                if (!isset(
$newSet[$key]))
                {
                   
$removedKeys[] = $key;
                }
                else
                {
                   
$newValue = $newSet[$key];
                    if (
$oldValue !== $newValue)
                    {
                       
// updated value
                       
$replacements[$key] = $newValue;
                    }
                }
            }

            foreach (
$newSet AS $key => $newValue)
            {
                if (isset(
$oldSet[$key]))
                {
                   
// handled above
                   
continue;
                }

               
// new value
               
$replacements[$key] = $newValue;
            }

           
$db = $entity->db();
           
$keyColumn = $this->config['keyColumn'];
           
$id = $entity->getEntityId();

            if (
$removedKeys)
            {
               
$db->delete(
                   
$this->config['valueTable'],
                   
"`$keyColumn` = ? AND field_id IN (" . $db->quote($removedKeys) . ")",
                   
$id
               
);
            }

            if (
$replacements)
            {
               
$insert = [];
                foreach (
$replacements AS $key => $value)
                {
                   
$insert[] = [
                       
$keyColumn => $id,
                       
'field_id' => $key,
                       
'field_value' => is_array($value) ? serialize($value) : $value
                   
];
                }

               
$db->insertBulk($this->config['valueTable'], $insert, false, 'field_value = VALUES(field_value)');
            }
        }
    }

    public function
postDelete()
    {
       
$db = $this->entity->db();
       
$keyColumn = $this->config['keyColumn'];

       
$db->delete(
           
$this->config['valueTable'],
           
"`$keyColumn` = ?",
           
$this->entity->getEntityId()
        );
    }
}