GetPropertyValueRecursive: Bitrix method

      
<?php 
//  GetPropertyValueRecursive()
//  /dist/bitrix/modules/bizproc/classes/general/activity.php:425

    
private function GetPropertyValueRecursive($val$convertToType null)
    {
        
// array(2, 5, array("SequentialWorkflowActivity1", "DocumentApprovers"))
        // array("Document", "IBLOCK_ID")
        // array("Workflow", "id")
        // "Hello, {=SequentialWorkflowActivity1:DocumentApprovers}, {=Document:IBLOCK_ID}!"

        
$parsed = static::parseExpression($val);
        if (
$parsed)
        {
            
$result null;
            if (
$convertToType)
                
$parsed['modifiers'][] = $convertToType;
            
$this->GetRealParameterValue($parsed['object'], $parsed['field'], $result$parsed['modifiers']);
            return array(
1$result);
        }
        elseif (
is_array($val))
        {
            
$b true;
            
$r = array();

            
$keys array_keys($val);

            
$i 0;
            foreach (
$keys as $key)
            {
                if (
$key."!" != $i."!")
                {
                    
$b false;
                    break;
                }
                
$i++;
            }

            foreach (
$keys as $key)
            {
                list(
$t$a) = $this->GetPropertyValueRecursive($val[$key], $convertToType);
                if (
$b)
                {
                    if (
$t == && is_array($a))
                        
$r array_merge($r$a);
                    else
                        
$r[] = $a;
                }
                else
                {
                    
$r[$key] = $a;
                }
            }

            if (
count($r) == 2)
            {
                
$keys array_keys($r);
                if (
$keys[0] == && $keys[1] == && is_string($r[0]) && is_string($r[1]))
                {
                    
$result null;
                    
$modifiers $convertToType ? array($convertToType) : array();
                    if (
$this->GetRealParameterValue($r[0], $r[1], $result$modifiers))
                        return array(
1$result);
                }
            }
            return array(
2$r);
        }
        else
        {
            if (
is_string($val))
            {
                
$typeClass null;
                
$fieldTypeObject null;
                if (
$convertToType)
                {
                    
/** @var CBPDocumentService $documentService */
                    
$documentService $this->workflow->GetService("DocumentService");
                    
$documentType $this->GetDocumentType();

                    
$typesMap $documentService->getTypesMap($documentType);
                    
$convertToType strtolower($convertToType);
                    if (isset(
$typesMap[$convertToType]))
                    {
                        
$typeClass $typesMap[$convertToType];
                        
$fieldTypeObject $documentService->getFieldTypeObject(
                            
$documentType,
                            array(
'Type' => \Bitrix\Bizproc\FieldType::STRING)
                        );
                    }
                }

                
$calc = new CBPCalc($this);
                if (
preg_match(self::CalcPattern$val))
                {
                    
$r $calc->Calculate($val);
                    if (
$r !== null)
                    {
                        if (
$typeClass && $fieldTypeObject)
                        {
                            if (
is_array($r))
                                
$fieldTypeObject->setMultiple(true);
                            
$r $fieldTypeObject->convertValue($r$typeClass);
                        }
                        return array(
is_array($r)? 2$r);
                    }
                }

                
//parse inline calculator
                
$val preg_replace_callback(
                    static::
CalcInlinePattern,
                    function(
$matches) use ($calc)
                    {
                        
$r $calc->Calculate($matches[1]);
                        if (
is_array($r))
                            
$r implode(', 'CBPHelper::MakeArrayFlat($r));
                        return 
$r !== null$r.$matches[2] : $matches[0];
                    },
                    
$val
                
);

                
//parse properties
                
$val preg_replace_callback(
                    static::
ValueInlinePattern,
                    array(
$this"ParseStringParameter"),
                    
$val
                
);

                
//converting...
                
if ($typeClass && $fieldTypeObject)
                {
                    
$val $fieldTypeObject->convertValue($val$typeClass);
                }
            }

            return array(
2$val);
        }
    }