monster_menus-9.0.x-dev/src/Entity/MMTreeExtendedSettingsTrait.php

src/Entity/MMTreeExtendedSettingsTrait.php
<?php

namespace Drupal\monster_menus\Entity;

use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Database;
use Drupal\monster_menus\Constants;

/**
 * Defines the extended settings trait for MMTree.
 *
 * @ingroup monster_menus
 */
trait MMTreeExtendedSettingsTrait {

  /**
   * @var array Extended settings array.
   */
  private $extendedSettings;

  /**
   * @var array
   *   Extended field definitions.
   */
  private static $extendedFields = [
    'flags' => ['mm_tree_flags', 'f', 'f.mmtid = t.mmtid', "GROUP_CONCAT(DISTINCT CONCAT_WS('|1', f.flag, f.data) SEPARATOR '|2')", 'expandRowFlags'],
    'archive' => ['mm_archive', 'a', 'a.main_mmtid = t.mmtid OR a.archive_mmtid = t.mmtid', ['main_mmtid', 'archive_mmtid', 'frequency', 'main_nodes']],
    'cascaded' => ['mm_cascaded_settings', 's', 's.mmtid = t.mmtid', "GROUP_CONCAT(DISTINCT CONCAT_WS('|1', s.name, s.data_type, s.multiple, s.array_key, s.data) SEPARATOR '|2')", 'expandRowCascaded'],
    'blocks' => ['mm_tree_block', 'b', 'b.mmtid = t.mmtid', ['MAX(bid)' => 'menu_start', 'max_depth', 'max_parents']],
    'vgroup' => ['mm_vgroup_query', 'v', 'v.vgid = g.vgid', ['MAX(field)' => 'qfield', 'qfrom']],
  ];

  /**
   * @var array
   *   Extended field keys.
   */
  private static $extendedFieldKeys = [
    'flags',
    'main_mmtid', 'archive_mmtid', 'frequency', 'main_nodes',
    'cascaded',
    'menu_start', 'max_depth', 'max_parents',
    'qfield', 'qfrom',
    'members',
    'perms',
    'large_group_form_token',
  ];

  /**
   * @var array
   *   Default extended settings.
   */
  private static $defaultSettings = [
    'cascaded' => [],
    'flags' => [],
    'max_depth' => -1,
    'max_parents' => -1,
    'members' => [],
    'menu_start' => Constants::MM_MENU_UNSET,
    'perms' => [
      Constants::MM_PERMS_WRITE => ['groups' => [], 'users' => []],
      Constants::MM_PERMS_SUB   => ['groups' => [], 'users' => []],
      Constants::MM_PERMS_APPLY => ['groups' => [], 'users' => []],
      Constants::MM_PERMS_READ  => ['groups' => [], 'users' => []],
    ],
    'qfield' => '',
    'qfrom' => '',
    'main_mmtid' => 0,
    'archive_mmtid' => 0,
    'frequency' => '',
    'main_nodes' => 0,
    'large_group_form_token' => '',
  ];

  /** @var Connection */
  private $database;

  /**
   * Expand 'flags' extended setting.
   *
   * @param string $field
   *   The field to be expanded.
   */
  private function expandRowFlags(&$field) {
    preg_match_all('/(.*?)\|1(.*?)(?:\|2|$)/', $field, $matches);
    $field = $matches[0] ? array_combine($matches[1], $matches[2]) : [];
  }

  /**
   * Expand 'cascaded' extended setting.
   *
   * @param string $field
   *   The field to be expanded.
   */
  private function expandRowCascaded(&$field) {
    $cascaded = [];
    if ($field) {
      foreach (explode('|2', $field) as $r) {
        $r = (object) array_combine(['name', 'data_type', 'multiple', 'array_key', 'data'], explode('|1', $r, 5));
        if ($r->data_type == 'int') {
          $r->data = (int) $r->data;
        }

        if ($r->multiple) {
          if (!isset($cascaded[$r->name]) || !is_array($cascaded[$r->name])) {
            $cascaded[$r->name] = [];
          }
          if ($r->array_key != '') {
            $cascaded[$r->name][$r->array_key] = $r->data;
          }
          else {
            $cascaded[$r->name][] = $r->data;
          }
        }
        else {
          $cascaded[$r->name] = $r->data;
        }
      }
    }
    $field = $cascaded;
  }

  /**
   * Get all extended settings.
   *
   * @return array
   *   The extended settings.
   */
  public function &getExtendedSettings() {
    if (!$this->id()) {
      $this->extendedSettings = static::$defaultSettings;
    }
    else if (!is_array($this->extendedSettings)) {
      $query = $this->getDatabase()
        ->select('mm_tree', 't');
      $query->condition('t.mmtid', $this->id());
      $query->leftJoin('mm_group', 'g', 'g.gid = t.mmtid');
      foreach (static::$extendedFields as $field => $data) {
        $query->leftJoin($data[0], $data[1], $data[2]);
        if (is_string($data[3])) {
          $query->addExpression($data[3], $field);
        }
        else if ($data[3]) {
          foreach ($data[3] as $key => $name) {
            if (is_string($key)) {
              $query->addExpression($key, $name);
            }
            else {
              $query->addExpression("MAX($name)", $name);
            }
          }
        }
      }
      $query->groupBy('t.mmtid');
      $row = $query->execute()->fetchAssoc();
      foreach (static::$extendedFields as $field => $data) {
        if (isset($data[4]) && method_exists($this, $data[4])) {
          $this->{$data[4]}($row[$field]);
        }
      }
      $row['perms'] = mm_content_get_perms($this->id(), TRUE, TRUE, FALSE, $this->getDatabase());
      $row['members'] = mm_content_get_uids_in_group($this->id(), NULL, TRUE, FALSE, FALSE, $this->getDatabase());
      $this->extendedSettings = $row + static::$defaultSettings;
    }
    return $this->extendedSettings;
  }

  /**
   * Save all extended settings. Note that if the entity is new, the remainder
   * of it must be saved first, so that it will have an ID before this function
   * is called.
   */
  public function saveExtendedSettings() {
    // If this is an import, the extendedSettings element is set. Copy it into
    // the main property.
    if ($settings = $this->get('extendedSettings')->value) {
      $this->extendedSettings = $settings;
    }
    if (is_array($this->extendedSettings) && ($mmtid = $this->id())) {
      $extended = $this->getExtendedSettings();
      $clear_old = !$this->isNew();
      $database = $this->getDatabase();
      mm_content_set_flags($mmtid, $extended['flags'], $clear_old, $database);
      mm_content_set_perms($mmtid, $extended['perms'], $this->isGroup(), $clear_old, $database);
      mm_content_set_cascaded_settings($mmtid, $extended['cascaded'], $clear_old, $database);
      if ($this->isGroup()) {
        mm_content_set_group_members($mmtid, NULL, $extended['qfield'], $extended['qfrom'], $extended['members'], $extended['large_group_form_token'], $database);
      }
      else {
        $database
          ->delete('mm_tree_block')
          ->condition('mmtid', $mmtid)
          ->execute();
        if ($extended['menu_start'] && $extended['menu_start'] != Constants::MM_MENU_UNSET || isset($extended['max_depth']) && $extended['max_depth'] >= 0 || isset($extended['max_parents']) && $extended['max_parents'] >= 0) {
          $database
            ->insert('mm_tree_block')
            ->fields([
              'mmtid' => $mmtid,
              'bid' => is_null($extended['menu_start']) ? Constants::MM_MENU_UNSET : $extended['menu_start'],
              'max_depth' => $extended['max_depth'],
              'max_parents' => $extended['max_parents'],
            ])
            ->execute();
        }

        $database->delete('mm_archive')
          ->condition('main_mmtid', $mmtid)
          ->execute();
        if ($extended['archive_mmtid']) {
          $this->database->insert('mm_archive')
            ->fields([
              'main_mmtid' => $mmtid,
              'archive_mmtid' => $extended['archive_mmtid'],
              'frequency' => $extended['frequency'],
              'main_nodes' => $extended['main_nodes'],
            ])
            ->execute();
          // Don't allow custom ordering
          mm_content_reset_custom_node_order($mmtid);
        }
      }
    }
  }

  /**
   * Sets all extended settings.
   *
   * @param array $settings
   *   Array containing extended settings.
   */
  public function setExtendedSettings(array $settings) {
    $this->extendedSettings = $settings;
  }

  /**
   * Delete all extended settings from the database, usually when the entity is
   * being deleted.
   */
  public function deleteExtendedSettings() {
    static::deleteMultipleExtendedSettings([$this->id()]);
  }

  /**
   * Delete the extended settings for multiple MMTree entities.
   *
   * @param array $mmtids
   *   The list of tree entries to delete.
   */
  public static function deleteMultipleExtendedSettings($mmtids) {
    $database = Database::getConnection();

    $database->delete('mm_tree_flags')
      ->condition('mmtid', $mmtids, 'IN')
      ->execute();
    $database->delete('mm_tree_block')
      ->condition('mmtid', $mmtids, 'IN')
      ->execute();
    $or = $database->condition('OR');
    $database->delete('mm_archive')
      ->condition($or
        ->condition('main_mmtid', $mmtids, 'IN')
        ->condition('archive_mmtid', $mmtids, 'IN')
      )
      ->execute();
    $database->delete('mm_cascaded_settings')
      ->condition('mmtid', $mmtids, 'IN')
      ->execute();

    // Remove virtual groups; mm_virtual_group is cleaned up automatically
    // in cron. It's far faster to use $database->query(), since DBTNG doesn't
    // allow JOIN.
    if ($database->databaseType() == 'mysql') {
      $database->query('DELETE vg FROM {mm_vgroup_query} vg INNER JOIN {mm_group} g ON g.vgid = vg.vgid WHERE g.gid IN(:mmtids[])', [':mmtids[]' => $mmtids]);
    }
    else {
      // DELETE FROM {mm_vgroup_query} WHERE
      //   (SELECT 1 FROM {mm_group} g WHERE g.vgid = {mm_vgroup_query}.vgid
      //     AND g.gid IN(:mmtids))
      $mm_group = $database->select('mm_group', 'g');
      $mm_group->addExpression(1);
      $mm_group->where('g.vgid = {mm_vgroup_query}.vgid')
        ->condition('g.gid', $mmtids, 'IN');
      $database->delete('mm_vgroup_query')
        ->condition($mm_group)
        ->execute();
    }
    // Remove group membership.
    $database->delete('mm_group')
      ->condition('gid', $mmtids, 'IN')
      ->execute();
  }

  /**
   * Gets the database connection.
   *
   * @return Connection
   */
  public function getDatabase() {
    if (empty($this->database)) {
      $this->database = Database::getConnection();
    }
    return $this->database;
  }

  /**
   * Sets the database connection.
   */
  public function setDatabase(Connection $new_database) {
    $this->database = $new_database;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc