Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
novicell/dds_global_content / src / GlobalContentStorage.php
Size: Mime:
<?php

namespace Drupal\dds_global_content;

use Drupal\Component\Transliteration\TransliterationInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\Select;
use Drupal\Core\Database\StatementInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Class GlobalContentStorage
 *
 * @package Drupal\dds_global_content
 */
class GlobalContentStorage {

  use StringTranslationTrait;

  /**
   * @var \Drupal\Core\Database\Connection
   */
  private $connection;

  /**
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  private $logger;

  /**
   * @var \Drupal\Component\Transliteration\TransliterationInterface
   */
  private $transliteration;

  /**
   * GlobalContentStorage constructor.
   *
   * @param \Drupal\Core\Database\Connection $connection
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactory
   * @param \Drupal\Component\Transliteration\TransliterationInterface $transliteration
   */
  public function __construct(Connection $connection, LoggerChannelFactoryInterface $loggerChannelFactory, TransliterationInterface $transliteration) {
    $this->connection = $connection;
    $this->logger = $loggerChannelFactory->get('global_content');
    $this->transliteration = $transliteration;
  }

  /**
   * @param $values
   *
   * @return \Drupal\dds_global_content\GlobalContent
   */
  public function createGlobalContent($values) {
    return new GlobalContent($values);
  }

  /**
   * @param \Drupal\dds_global_content\GlobalContent $global_content
   *
   * @return \Drupal\Core\Database\StatementInterface|int|null
   */
  private function doSaveGlobalContentBase(GlobalContent $global_content) {
    $values = [
      'machine_name' => $global_content->getMachineName(),
      'type' => $global_content->getType(),
      'title' => (!empty($global_content->getTitle())) ? $global_content->getTitle() : $global_content->getMachineName(),
      'description' => $global_content->getDescription(),
      'category' => $global_content->getCategory(),
      'group_id' => $global_content->getGroupID(),
      'group_name' => $global_content->getGroupName(),
      'subgroup_name' => $global_content->getSubgroupName(),
      'weight' => $global_content->getWeight(),
      'options' => serialize($global_content->getOptions()),
    ];

    return $this->dbSave('global_content', $values, $global_content->isNew());
  }

  /**
   * @param \Drupal\dds_global_content\GlobalContent $global_content
   *
   * @return bool|\Drupal\Core\Database\StatementInterface|int|null
   */
  private function doSaveGlobalContentData(GlobalContent $global_content) {
    $values = [
      'machine_name' => $global_content->getMachineName(),
      'data' => ($global_content->isNew()) ? serialize($global_content->getDefault()) : serialize($global_content->getData()),
      'langcode' => $global_content->getLangcode(),
    ];

    // Remove data if empty
    if (empty($values['data'])) {
      unset($values['data']);
    }

    // If multilingual default values is defined loop through them and save the
    // values in it's own row.
    if ($global_content->isNew() && is_array($global_content->getDefault())) {
      $languages = \Drupal::languageManager()->getNativeLanguages();
      foreach ($global_content->getDefault() as $langcode => $data) {
        if (!$global_content->isTranslatable()) {
          $langcode = LanguageInterface::LANGCODE_NOT_APPLICABLE;
        }
        if (array_key_exists($langcode, $languages) || $langcode == LanguageInterface::LANGCODE_NOT_APPLICABLE || $langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
          $values['langcode'] = $langcode;
          $values['data'] = serialize($data);
          $this->dbSave('global_content_data', $values, $global_content->isNew());
        }
      }
      return TRUE;
    }
    else {
      return $this->dbSave('global_content_data', $values, !$this->languageExists($global_content->getMachineName(), $global_content->getLangcode()));
    }
  }

  /**
   * @param \Drupal\dds_global_content\GlobalContent $global_content
   */
  private function doSaveGlobalContentStatistics(GlobalContent $global_content) {
    $locations = $global_content->getLocations();
    foreach ($locations as $location) {
      $values = [
        'machine_name' => $global_content->getMachineName(),
        'location_url' => $location,
        'location_selector' => '',
        'langcode' => $global_content->getLangcode(),
      ];

      $this->dbSave('global_content_statistic', $values, TRUE);
    }
  }

  /**
   * @param \Drupal\dds_global_content\GlobalContent $global_content
   */
  public function save(GlobalContent $global_content) {
    if ($global_content->isNew()) {
      $result = $this->doSaveGlobalContentBase($global_content);
      //$this->doSaveGlobalContentLabel($global_content);
    }
    $this->doSaveGlobalContentData($global_content);
    //$this->doSaveGlobalContentLabel($global_content);
    //$this->doSaveGlobalContentStatistics($global_content);
  }

  /**
   * @param \Drupal\dds_global_content\GlobalContent $global_content
   */
  public function rebuild(GlobalContent $global_content) {
    $result = $this->doSaveGlobalContentBase($global_content);
    if ($global_content->isNew()) {
      $this->doSaveGlobalContentData($global_content);
    }
  }

  /**
   * @param string $machine_name
   * @param null $langcode
   *
   * @return mixed
   */
  public function load($machine_name, $langcode = NULL) {
    $items = $this->loadMultiple([$machine_name], $langcode);
    if (is_array($items)) {
      return reset($items);
    }

    return NULL;
  }

  /**
   * @param array $machine_names
   * @param null $langcode
   *
   * @return array|bool
   */
  public function loadMultiple(array $machine_names = [], $langcode = NULL) {
    if (empty($machine_names)) {
      $machine_names = $this->getMachineNames();
    }
    if (empty($langcode)) {
      $langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
    }
    $langcode_list = [
      $langcode,
      LanguageInterface::LANGCODE_NOT_APPLICABLE,
      \Drupal::languageManager()->getDefaultLanguage()->getId(),
      LanguageInterface::LANGCODE_NOT_SPECIFIED,
      NULL
    ];
    if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED || $langcode == LanguageInterface::LANGCODE_NOT_APPLICABLE) {
      array_pop($langcode_list);
    }

    $results = [];
    $missing = $machine_names;
    foreach ($langcode_list as $current_langcode) {
      if (!empty($missing)) {
        $query = $this->connection->select('global_content', 'c');
        $query->innerJoin('global_content_data', 'd', 'c.machine_name = d.machine_name');
        $query->fields('d')
          ->fields('c')
          ->condition('c.machine_name', $missing, 'IN');
        if (!empty($current_langcode)) {
          $query->condition('d.langcode', $current_langcode);
        }

        try {
          $rows = $query->execute();
          while ($values = $rows->fetchAssoc()) {
            $values['isNew'] = FALSE;
            $machine_name = $values['machine_name'];
            $results[$machine_name] = $values;
            if (($key = array_search($machine_name, $missing)) !== FALSE) {
              unset($missing[$key]);
            }
          }
        } catch (\Exception $e) {
          return FALSE;
        }
      }
    }
    if (!empty($missing)) {
      $query = $this->connection->select('global_content', 'c');
      $query->fields('c')
        ->condition('c.machine_name', $missing, 'IN');

      try {
        $rows = $query->execute();
        while ($values = $rows->fetchAssoc()) {
          $values['isNew'] = FALSE;
          $machine_name = $values['machine_name'];
          $results[$machine_name] = $values;
          if (($key = array_search($machine_name, $missing)) !== FALSE) {
            unset($missing[$key]);
          }
        }
      } catch (\Exception $e) {
        return FALSE;
      }
    }
    return $results;
  }

  /**
   * @param $table
   * @param $values
   * @param bool $isNew
   *
   * @return \Drupal\Core\Database\StatementInterface|int|null
   */
  private function dbSave($table, $values, $isNew = TRUE) {
    if (!empty($values)) {
      try {
        if ($values['machine_name'] && !$isNew) {
          // Make sure we don't overwrite values with empty ones.
          $values = array_filter($values, function ($value) {
            return $value !== '';
          });

          if (!empty($values)) {
            $update = $this->connection->update($table)
              ->fields($values)
              ->condition('machine_name', $values['machine_name']);

            if (isset($values['langcode'])) {
              $update->condition('langcode', $values['langcode']);
            }

            $update->execute();
          }
        }
        else {
          return $this->connection->insert($table)->fields($values)->execute();
        }
      } catch (\Exception $exception) {
        error_log($exception->getMessage());
        $this->logger->error($exception->getMessage());
      }
    }
    return NULL;
  }

  /**
   * @param string $group_id
   *
   * @return array
   */
  public function getMachineNames($group_id = '') {
    if (empty($group_id)) {
      return $this->connection->select('global_content')
        ->fields('global_content', ['machine_name'])
        ->orderBy('machine_name')
        ->execute()
        ->fetchCol();
    }
    else {
      return $this->connection->select('global_content')
        ->fields('global_content', ['machine_name'])
        ->condition('group_id', $group_id)
        ->orderBy('machine_name', 'DESC')
        ->orderBy('subgroup_name', 'DESC')
        ->execute()
        ->fetchCol();
    }
  }

  /**
   * @return array
   */
  public function getGroups() {
    return $this->connection->select('global_content')
      ->fields('global_content', ['group_id', 'group_name'])
      ->groupBy('group_id')
      ->orderBy('group_name')
      ->execute()
      ->fetchAllKeyed();
  }

  /**
   * @return string
   */
  public function getGroupName($group_id) {
    return $this->connection->select('global_content')
      ->fields('global_content', ['group_name'])
      ->condition('group_id', $group_id)
      ->execute()
      ->fetchField();
  }

  /**
   * @return array
   *   An indexed array, or an empty array if there is no categories.
   */
  public function getCategories() {
    $query = $this->connection->select('global_content', 'cl');
    $query->fields('cl', ['category'])
      ->groupBy('category')
      ->orderBy('category');
    $result = $query->execute()->fetchCol();
    return $result;
  }

  /**
   * @param $machine_name
   * @param $langcode
   *
   * @return bool
   */
  public function languageExists($machine_name, $langcode) {
    $query = $this->connection->select('global_content_data', 'd');
    $query->condition('d.machine_name', $machine_name)
      ->condition('d.langcode', $langcode);

    $query->addExpression('1');
    $query->range(0, 1);

    try {
      return (bool) $query->execute()->fetchField();
    } catch (\Exception $e) {
      return FALSE;
    }
  }

  /**
   * @param $machine_name
   *
   * @return array|bool
   */
  public function getTranslations($machine_name) {
    $query = $this->connection->select('global_content_data', 'd')
      ->fields('d', ['langcode']);
    $query->condition('d.machine_name', $machine_name);
    try {
      return $query->execute()->fetchCol();
    } catch (\Exception $e) {
      return FALSE;
    }
  }

  /**
   * @param string $machine_name
   *
   * @return bool
   */
  public function delete($machine_name) {
    $this->connection->delete('global_content')
      ->condition('machine_name', $machine_name)
      ->execute();
    $this->connection->delete('global_content_data')
      ->condition('machine_name', $machine_name)
      ->execute();
    $this->connection->delete('global_content_statistic')
      ->condition('machine_name', $machine_name)
      ->execute();
    return TRUE;
  }

  /**
   * @param string $machine_name
   * @param string $langcode
   *
   * @return int
   */
  public function deleteTranslation($machine_name, $langcode) {
    return $this->connection->delete('global_content_data')
      ->condition('machine_name', $machine_name)
      ->condition('langcode', $langcode)
      ->execute();
  }

  /**
   * @param array $params
   * @param int $limit
   *
   * @return GlobalContent[]
   */
  public function searchGlobalContent($params = [], $limit = 0) {
    $category = $params['category'] ?? '';
    $type = $params['type'] ?? '';
    $searchResults = [];
    /** @var Select $query */
    $query = $this->connection->select('global_content', 'gc');
    $query->distinct();
    $query->fields('gc', ['category', 'group_name', 'group_id']);
    if (!empty($category)) {
      $query->condition('gc.category', $category);
    }
    if (!empty($type)) {
      $query->condition('gc.type', $type);
    }
    if ($limit != 0) {
      $query = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')
        ->limit($limit);
    }
    $query
      ->orderBy('gc.category', 'DESC')
      ->orderBy('gc.group_name', 'DESC');
    $result = $query->execute();
    while ($row = $result->fetchAssoc()) {
      $category = $this->t($row['category'])->__toString();
      $group = $this->t($row['group_name'])->__toString();
      if (!isset($searchResults[$category])) {
        $searchResults[$category] = [];
      }
      if (!isset($searchResults[$category][$group])) {
        $searchResults[$category][$group] = [];
        $content = GlobalContent::loadGroup($row['group_id']);
        foreach ($content as $globalContent) {
          $subgroup = empty($globalContent->getSubgroupName()) ? '0' : $this->t($globalContent->getSubgroupName())->__toString();
          if (!isset($searchResults[$category][$group][$subgroup])) {
            $searchResults[$category][$group][$subgroup] = [];
          }
          $searchResults[$category][$group][$subgroup][] = $globalContent;
        }
      }
    }
    return $searchResults;
  }

  /**
   * @param $machine_name
   * @param $langcode
   *
   * @return array
   */
  public function getLocations($machine_name, $langcode) {
    $query = $this->connection->select('global_content_statistic', 'c');
    $query->fields('c', ['location_url']);
    $query->condition('c.machine_name', $machine_name)
      ->condition('c.langcode', $langcode);

    $results = $query->execute()->fetchAll();
    $locations = [];
    foreach ($results as $result) {
      $locations[] = $result->location_url;
    }
    return $locations;
  }


  public function getTitles() {
    $texts = [];
    /** @var StatementInterface $result */
    $result = $this->connection->select('global_content')->fields('global_content', ['machine_name','title', 'group_name'])->orderBy('group_name', 'title')->execute();
    while ($text = $result->fetchAssoc()) {
      $texts[$text['machine_name']] = t($text['group_name']) . ' - ' . t($text['title']);
    }
    return $texts;
  }

}