public function transform()

in src/Facebook/InstantArticles/Transformer/Transformer.php [281:381]


    public function transform($context, $node)
    {
        $is_first_run = false;
        if (Type::is($context, InstantArticle::getClassName()) && $context->getMetaProperty('op:generator:transformer') === null) {
            $context->addMetaProperty('op:generator:transformer', 'facebook-instant-articles-sdk-php');
            $context->addMetaProperty('op:generator:transformer:version', InstantArticle::CURRENT_VERSION);
            $is_first_run = true;
            $this->instantArticle = $context;
        }

        if (!$node) {
            $e = new \Exception();
            $this->addLog(
                TransformerLog::ERROR,
                'Transformer::transform($context, $node) requires $node'.
                ' to be a valid one. Check on the stacktrace if this is '.
                'some nested transform operation and fix the selector.',
                $e->getTraceAsString()
            );
            return $context;
        }
        $current_context = $context;
        if ($node->hasChildNodes()) {
            foreach ($node->childNodes as $child) {
                if (self::isProcessed($child)) {
                    continue;
                }
                $matched = false;

                // Get all classes and interfaces this context extends/implements
                $contextClassNames = self::getAllClassTypes($context->getClassName());

                // Look for rules applying to any of them as context
                $matchingContextRules = [];
                foreach ($contextClassNames as $contextClassName) {
                    if (isset($this->rules[$contextClassName])) {
                        // Use array union (+) instead of merge to preserve
                        // indexes (as they represent the order of insertion)
                        $matchingContextRules = $matchingContextRules + $this->rules[$contextClassName];
                    }
                }

                // Sort by insertion order
                ksort($matchingContextRules);

                // Process in reverse order
                $matchingContextRules = array_reverse($matchingContextRules);
                foreach ($matchingContextRules as $rule) {
                    // We know context was matched, now check if it matches the node
                    $className = $rule->getClassName();
                    if ($rule->matchesNode($child)) {
                        $this->addLog(
                            TransformerLog::DEBUG,
                            "MATCH -> Rule [$className] applied to node [$child->nodeName]"
                        );
                        $current_context = $rule->apply($this, $current_context, $child);
                        $matched = true;

                        // Just a single rule for each node, so move on
                        break;
                    }

                    $this->addLog(
                        TransformerLog::DEBUG,
                        "no match -> rule [$className] not matched to node [$child->nodeName]"
                    );
                }

                if (!$matched &&
                    !($child->nodeName === '#text' && trim($child->textContent) === '') &&
                    !($child->nodeName === '#comment') &&
                    !($child->nodeName === 'html' && Type::is($child, 'DOMDocumentType')) &&
                    !($child->nodeName === 'xml' && Type::is($child, 'DOMProcessingInstruction')) &&
                    !$this->suppress_warnings
                    ) {
                    $tag_content = $child->ownerDocument->saveXML($child);
                    $tag_trimmed = trim($tag_content);
                    if (!empty($tag_trimmed)) {
                        $className = $context->getClassName();
                        $this->addLog(
                            TransformerLog::ERROR,
                            "Content with no rules matching! Context[$className] and Node [$child->nodeName]"
                        );
                    } else {
                        $this->addLog(
                            TransformerLog::DEBUG,
                            "Empty content ignored."
                        );
                    }

                    $this->addWarning(new UnrecognizedElement($current_context, $child));
                }
            }
        }

        if ($is_first_run) {
            $context = $this->handleTransformationSettings($context);
        }

        return $context;
    }