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;
}