View source  
  <?php
namespace Drupal\yoast_seo;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\views\Views;
use Drupal\Component\Utility\Html;
use Symfony\Component\Yaml\Yaml;
class YoastSeoManager {
  
  protected $moduleHandler;
  
  public static $jsTargets = [
    'wrapper_target_id' => 'yoast-wrapper',
    'snippet_target_id' => 'yoast-snippet',
    'output_target_id' => 'yoast-output',
    'overall_score_target_id' => 'yoast-overall-score',
  ];
  
  public function __construct(ModuleHandlerInterface $module_handler) {
    $this->moduleHandler = $module_handler;
    $this->yoast_seo_field_manager = \Drupal::service('yoast_seo.field_manager');
    
    foreach (self::$jsTargets as $js_target_name => $js_target_id) {
      if (!preg_match('/^js/', $js_target_id)) {
        self::$jsTargets[$js_target_name] = Html::getUniqueId($js_target_id);
      }
    }
  }
  
  public function attachYoastSeoFields($entity_type, $bundle) {
    
    $metatag_field = array(
      'field_name' => 'field_meta_tags',
      'field_label' => 'Meta tags',
      'storage_type' => 'metatag',
      'translatable' => TRUE,
    );
    $this->yoast_seo_field_manager
      ->attachField($entity_type, $bundle, $metatag_field);
    
    $yoast_fields = [
      'field_yoast_seo' => array(
        'field_name' => 'field_yoast_seo',
        'field_label' => 'Real-time SEO',
        'storage_type' => 'yoast_seo',
        'translatable' => TRUE,
      ),
    ];
    foreach ($yoast_fields as $field) {
      $this->yoast_seo_field_manager
        ->attachField($entity_type, $bundle, $field);
    }
  }
  
  public function detachYoastSeoFields($entity_type, $bundle) {
    
    $yoast_fields = [
      'field_yoast_seo',
    ];
    foreach ($yoast_fields as $field_name) {
      $this->yoast_seo_field_manager
        ->detachField($entity_type, $bundle, $field_name);
    }
  }
  
  public function getAvailableBundles($entity_type = 'node') {
    $options = array();
    
    $bundles = \Drupal::service('entity_type.bundle.info')
      ->getBundleInfo($entity_type);
    foreach ($bundles as $bundle_id => $bundle_metadata) {
      $options[$bundle_id] = $bundle_metadata['label'];
    }
    return $options;
  }
  
  public function getEnabledBundles($entity_type = 'node') {
    $enabled_bundles = array();
    $yoast_seo_field_manager = \Drupal::service('yoast_seo.field_manager');
    
    $bundles = $this
      ->getAvailableBundles($entity_type);
    
    foreach ($bundles as $bundle_id => $bundle_label) {
      if ($yoast_seo_field_manager
        ->isAttached($entity_type, $bundle_id, 'field_yoast_seo')) {
        $enabled_bundles[] = $bundle_id;
      }
    }
    return $enabled_bundles;
  }
  
  public function attachFieldHandlerToContentView() {
    $content_view = Views::getView('content');
    if ($content_view) {
      $display_id = 'page_1';
      $handlers = $content_view
        ->getHandlers('field', $display_id);
      if (!isset($handlers['field_yoast_seo'])) {
        $content_view
          ->addHandler($display_id, 'field', 'node__field_yoast_seo', 'field_yoast_seo', [
          'type' => 'yoastseo_formatter',
        ], 'field_yoast_seo');
        $content_view
          ->save();
      }
    }
  }
  
  public function detachFieldHandlerFromContentView() {
    $content_view = Views::getView('content');
    if ($content_view) {
      $display_id = 'page_1';
      $handlers = $content_view
        ->getHandlers('field', $display_id);
      if (isset($handlers['field_yoast_seo'])) {
        $content_view
          ->removeHandler($display_id, 'field', 'field_yoast_seo');
        $content_view
          ->save();
      }
    }
  }
  
  public function setTargetsConfiguration(&$elt) {
    foreach (self::$jsTargets as $js_target_name => $js_target_id) {
      $elt['#attached']['drupalSettings']['yoast_seo']['targets'][$js_target_name] = $js_target_id;
    }
    return $elt;
  }
  
  public function setGeneralConfiguration(&$elt) {
    
    $language = \Drupal::languageManager()
      ->getCurrentLanguage()
      ->getId();
    $elt['#attached']['drupalSettings']['yoast_seo']['language'] = $language;
    
    $elt['#attached']['drupalSettings']['yoast_seo']['analyzer'] = TRUE;
    $elt['#attached']['drupalSettings']['yoast_seo']['snippet_preview'] = TRUE;
    
    global $base_root;
    $elt['#attached']['drupalSettings']['yoast_seo']['base_root'] = $base_root;
    
    $elt['#attached']['drupalSettings']['yoast_seo']['cookie_data_key'] = 'yoastseo.metatags';
    return $elt;
  }
  
  public function setScoreToStatusRulesConfiguration(&$elt) {
    $score_to_status_rules = $this
      ->getScoreToStatusRules();
    
    $elt['#attached']['drupalSettings']['yoast_seo']['score_status'] = $score_to_status_rules;
    return $elt;
  }
  
  public function getConfiguration() {
    $conf = Yaml::parse(file_get_contents(drupal_get_path('module', 'yoast_seo') . '/config/yoast_seo.yml'));
    return $conf;
  }
  
  public function getScoreToStatusRules() {
    $score_to_status_rules = $this
      ->getConfiguration()['score_to_status_rules'];
    ksort($score_to_status_rules);
    return $score_to_status_rules;
  }
  
  public function getSnippetEditorMarkup() {
    
    $snippet_tpl = [
      '#theme' => 'yoast_snippet',
      '#wrapper_target_id' => self::$jsTargets['wrapper_target_id'],
      '#snippet_target_id' => self::$jsTargets['snippet_target_id'],
      '#output_target_id' => self::$jsTargets['output_target_id'],
    ];
    return \Drupal::service('renderer')
      ->renderRoot($snippet_tpl);
  }
  
  public function getOverallScoreMarkup($score = 0) {
    $template = 'overall_score';
    $yoast_seo_manager = \Drupal::service('yoast_seo.manager');
    
    $overall_score_tpl = [
      '#theme' => $template,
      '#overall_score_target_id' => self::$jsTargets['overall_score_target_id'],
      '#overall_score' => $this
        ->getScoreStatus($score),
    ];
    return \Drupal::service('renderer')
      ->renderRoot($overall_score_tpl);
  }
  
  public function getScoreStatus($score) {
    $rules = $this
      ->getScoreToStatusRules();
    $default = $rules['default'];
    unset($rules['default']);
    foreach ($rules as $status => $status_rules) {
      $min_max_isset = isset($status_rules['min']) && isset($status_rules['max']);
      if (isset($status_rules['equal']) && $status_rules['equal'] == $score) {
        return $status;
      }
      elseif ($min_max_isset && $score > $status_rules['min'] && $score <= $status_rules['max']) {
        return $status;
      }
    }
    return $default;
  }
}