You are here

TransformerFactory.php in Facebook Instant Articles 3.x

File

src/TransformerFactory.php
View source
<?php

namespace Drupal\fb_instant_articles;

use Drupal\Core\Config\ConfigFactoryInterface;
use Facebook\InstantArticles\Transformer\Logs\TransformerLog;
use Facebook\InstantArticles\Transformer\Transformer;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

/**
 * Factory class for creating Transformer objects.
 *
 * Using the factory will ensure that default transformer rules, and any added
 * by other module authors are used. Also handling for logs.
 */
class TransformerFactory {

  /**
   * Transformer rules manager service.
   *
   * @var \Drupal\fb_instant_articles\TransformerRulesManager
   */
  protected $transformerRulesManager;

  /**
   * Config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Log output from transformer instances when asked.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * TransformerFactory constructor.
   *
   * @param \Drupal\fb_instant_articles\TransformerRulesManager $transformer_rules_manager
   *   Transformer rules manager service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Config factory service.
   * @param \Psr\Log\LoggerInterface $logger
   *   Logger for transformer messages.
   */
  public function __construct(TransformerRulesManager $transformer_rules_manager, ConfigFactoryInterface $config_factory, LoggerInterface $logger) {
    $this->transformerRulesManager = $transformer_rules_manager;
    $this->configFactory = $config_factory;
    $this->logger = $logger;
    $this
      ->setTransformerLogLevel();
  }

  /**
   * Create a new instance of Transformer.
   *
   * @return \Facebook\InstantArticles\Transformer\Transformer
   *   A new Transformer instance loaded with the rules from the transformer
   *   rules manager.
   *
   * @throws \ReflectionException
   */
  public function getTransformer() : Transformer {
    $transformer = new Transformer();

    // Override the default timezone according to the site wide timezone.
    $config_data_default_timezone = $this->configFactory
      ->get('system.date')
      ->get('timezone.default');
    $default_time_zone = !empty($config_data_default_timezone) ? $config_data_default_timezone : @date_default_timezone_get();
    $transformer
      ->setDefaultDateTimeZone(new \DateTimeZone($default_time_zone));
    $this
      ->addRules($transformer);
    return $transformer;
  }

  /**
   * Flush the  logs for the given Transformer instance if any.
   *
   * @todo This is kind of conflating the responsibility of this class. Consider
   *   breaking it out into it's own service.
   *
   * @param \Facebook\InstantArticles\Transformer\Transformer $transformer
   *   A Transformer instance that may or may not have log output.
   */
  public function flushTransformerLogs(Transformer $transformer) {
    $level_map = [
      TransformerLog::DEBUG => LogLevel::DEBUG,
      TransformerLog::ERROR => LogLevel::ERROR,
      TransformerLog::INFO => LogLevel::INFO,
    ];
    if ($logs = $transformer
      ->getLogs()) {
      foreach ($logs as $log) {
        $this->logger
          ->log($level_map[$log
          ->getLevel()], $log
          ->getMessage());
      }
    }
  }

  /**
   * Set the transformer log level according to the configured logging level.
   */
  protected function setTransformerLogLevel() {
    if ($log_level = $this->configFactory
      ->get('fb_instant_articles.settings')
      ->get('transformer_logging_level')) {
      TransformerLog::setLevel($log_level);
    }
    else {
      TransformerLog::setLevel(TransformerLog::ERROR);
    }
  }

  /**
   * Adds rules to the given transformer from the transformer rules manager.
   *
   * @param \Facebook\InstantArticles\Transformer\Transformer $transformer
   *   A transformer instance to add rules to.
   *
   * @throws \ReflectionException
   *   When something goes wrong calling the static createFrom method on
   *   Transformer Rules objects.
   *
   * @see \Facebook\InstantArticles\Transformer\Transformer::loadRules()
   */
  protected function addRules(Transformer $transformer) {
    foreach ($this->transformerRulesManager
      ->getRules() as $rule) {
      $class = $rule['class'];
      $factory_method = NULL;
      try {
        $factory_method = new \ReflectionMethod($class, 'createFrom');
      } catch (\ReflectionException $e) {
        try {
          $factory_method = new \ReflectionMethod('Facebook\\InstantArticles\\Transformer\\Rules\\' . $class, 'createFrom');
        } catch (\ReflectionException $e) {

          // @todo This error message could be more descriptive.
          $this->logger
            ->error('Could not create transformer rule from rule configuration, skipping.');
        }
      }
      if ($factory_method) {
        $transformer
          ->addRule($factory_method
          ->invoke(NULL, $rule));
      }
    }
  }

}

Classes

Namesort descending Description
TransformerFactory Factory class for creating Transformer objects.