View source
<?php
namespace Drupal\dynamic_layouts\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\dynamic_layouts\DynamicLayoutInterface;
use Drupal\dynamic_layouts\DynamicLayoutSettingsInterface;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\dynamic_layouts\DynamicLayoutConstants as Constants;
class DynamicLayout extends ConfigEntityBase implements DynamicLayoutInterface {
public $id;
public $label;
public $weight;
public $category;
public $regions;
public $default_column_class;
public $default_row_class;
public function getCategory() {
return $this->category;
}
public function getDefaultColumnClass() {
return $this->default_column_class;
}
public function setDefaultRowClass($default_row_class) {
$this->default_row_class = $default_row_class;
$rows = $this
->getRows();
if ($rows) {
foreach ($rows as $key => $row) {
$rows[$key][Constants::DEFAULT_ROW_CLASS] = $default_row_class;
}
}
$this->regions = serialize($rows);
}
public function setDefaultColumnClass($default_column_class) {
$this->default_column_class = $default_column_class;
$rows = $this
->getRows();
if ($rows) {
foreach ($rows as $row_key => $row) {
$columns = $row[Constants::COLUMNS];
foreach ($columns as $column_key => $column) {
$rows[$row_key][Constants::COLUMNS][$column_key][Constants::DEFAULT_COLUMN_CLASS] = $default_column_class;
}
}
}
$this->regions = serialize($rows);
}
public function getDefaultRowClass() {
return $this->default_row_class;
}
public function getRegions() {
return $this->regions;
}
public function setRowClasses($row_id, array $row_classes) {
$updated_row = $this
->getRowById($row_id);
$updated_row[Constants::CUSTOM_ROW_CLASSES] = $row_classes;
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key] = $updated_row;
}
}
$this->regions = serialize($rows);
}
public function setCustomColumnClasses($row_id, $column_id, array $column_classes) {
$updated_row = $this
->getRowById($row_id);
$updated_column = $this
->getColumnById($updated_row, $column_id);
$updated_column[Constants::CUSTOM_COLUMN_CLASSES] = $column_classes;
$columns = $updated_row[Constants::COLUMNS];
foreach ($columns as $key => $column) {
if ($column[Constants::COLUMN_ID] == $column_id) {
$columns[$key] = $updated_column;
}
}
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key][Constants::COLUMNS] = $columns;
}
}
$this->regions = serialize($rows);
}
public function setColumnName($row_id, $column_id, $column_name) {
$updated_row = $this
->getRowById($row_id);
$columns = $updated_row[Constants::COLUMNS];
$updated_column = $this
->getColumnById($updated_row, $column_id);
$updated_column[Constants::COLUMN_NAME] = $column_name;
if (!$column_name) {
$column_name = 'r' . $row_id . 'c' . $column_id;
}
$region_name = strtolower($column_name);
$region_name = preg_replace('/[^a-z0-9_]+/', '_', $region_name);
$region_name = preg_replace('/_+/', '_', $region_name);
$updated_column[Constants::REGION_NAME] = $region_name;
foreach ($columns as $key => $column) {
if ($column[Constants::COLUMN_ID] == $column_id) {
$columns[$key] = $updated_column;
}
}
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key][Constants::COLUMNS] = $columns;
}
}
$this->regions = serialize($rows);
}
public function setCustomColumnWidthNumber($row_id, $column_id, $custom_column_width_number) {
$updated_row = $this
->getRowById($row_id);
$updated_column = $this
->getColumnById($updated_row, $column_id);
$updated_column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER] = $custom_column_width_number;
$columns = $updated_row[Constants::COLUMNS];
foreach ($columns as $key => $column) {
if ($column[Constants::COLUMN_ID] == $column_id) {
$columns[$key] = $updated_column;
}
}
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key][Constants::COLUMNS] = $columns;
}
}
$this->regions = serialize($rows);
}
public function getRowClasses($row_id) {
$row = $this
->getRowById($row_id);
$row_classes = '';
if (is_array($row[Constants::CUSTOM_ROW_CLASSES])) {
$row_classes = implode(', ', $row[Constants::CUSTOM_ROW_CLASSES]);
}
return $row_classes;
}
public function getColumnClasses($row_id, $column_id) {
$row = $this
->getRowById($row_id);
$column_classes = '';
$column = $this
->getColumnById($row, $column_id);
if (!isset($column[Constants::CUSTOM_COLUMN_CLASSES])) {
return $column_classes;
}
if (!is_array($column[Constants::CUSTOM_COLUMN_CLASSES])) {
return $column_classes;
}
return implode(', ', $column[Constants::CUSTOM_COLUMN_CLASSES]);
}
public function getColumnName($row_id, $column_id) {
$row = $this
->getRowById($row_id);
$column = $this
->getColumnById($row, $column_id);
return $column[Constants::COLUMN_NAME];
}
public function getColumnWidthNumber($row_id, $column_id) {
$row = $this
->getRowById($row_id);
$column = $this
->getColumnById($row, $column_id);
$column_width_number = $column[Constants::COLUMN_WIDTH_NUMBER];
if (isset($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER])) {
$column_width_number = $column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER];
}
return $column_width_number;
}
public function deleteRow($row_id) {
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
unset($rows[$key]);
}
}
$this->regions = serialize($rows);
}
public function addRow() {
$rows = $this
->getRows();
$column_count = 1;
$last_column_class = '';
$column_width_prefix = '';
if ($settings = \Drupal::entityTypeManager()
->getStorage(Constants::DYNAMIC_LAYOUT_SETTINGS)
->load(Constants::SETTINGS)) {
$column_classes = array_keys($settings
->getFrontendColumnClasses());
$last_column_class = end($column_classes);
$column_width_prefix = $settings
->getColumnPrefix();
}
$row_id = uniqid();
$columns = [];
for ($i = 1; $i <= $column_count; $i++) {
$column_id = uniqid();
$edit_column = $this
->getEditColumnLink($this
->id(), $row_id, $column_id);
$delete_column = $this
->getDeleteColumnLink($this
->id(), $row_id, $column_id);
$columns[] = [
Constants::EDIT_COLUMN => $edit_column,
Constants::DELETE_COLUMN => $delete_column,
Constants::COLUMN_ID => $column_id,
Constants::COLUMN_WIDTH_NUMBER => $last_column_class,
Constants::COLUMN_WIDTH_PREFIX => $column_width_prefix,
Constants::DEFAULT_COLUMN_CLASS => $this->default_column_class,
Constants::CUSTOM_COLUMN_CLASSES => [],
Constants::COLUMN_NAME => '',
Constants::REGION_NAME => 'r' . $row_id . 'c' . $column_id,
Constants::ADMIN_COLUMN_CLASSES => [
Constants::DYNAMIC_LAYOUT_COLUMN,
],
];
}
$rows[] = [
Constants::ROW_ID => $row_id,
'admin_row_classes' => [
'dynamic-layout-row',
],
Constants::DEFAULT_ROW_CLASS => $this->default_row_class,
Constants::CUSTOM_ROW_CLASSES => [],
Constants::COLUMNS => $columns,
];
$this->regions = serialize($rows);
}
public function addStartingRows($general_settings) {
$rows_count = 1;
if (isset($general_settings['start_rows_count'])) {
$rows_count = $general_settings['start_rows_count'];
}
$starting_default_column_class = '';
if (isset($general_settings[Constants::DEFAULT_COLUMN_CLASS]) && $general_settings[Constants::DEFAULT_COLUMN_CLASS]) {
$starting_default_column_class = \trim($general_settings[Constants::DEFAULT_COLUMN_CLASS]);
$this->default_column_class = $starting_default_column_class;
}
$starting_default_row_class = '';
if (isset($general_settings[Constants::DEFAULT_ROW_CLASS]) && $general_settings[Constants::DEFAULT_ROW_CLASS]) {
$starting_default_row_class = \trim($general_settings[Constants::DEFAULT_ROW_CLASS]);
$this->default_row_class = $starting_default_row_class;
}
$last_column_class = '';
$column_width_prefix = '';
if ($settings = \Drupal::entityTypeManager()
->getStorage(Constants::DYNAMIC_LAYOUT_SETTINGS)
->load(Constants::SETTINGS)) {
$column_width_prefix = $settings
->getColumnPrefix();
$column_classes = array_keys($settings
->getFrontendColumnClasses());
$last_column_class = end($column_classes);
}
$rows = [];
for ($i = 1; $i <= $rows_count; $i++) {
$row_id = uniqid();
$column_id = uniqid();
$columns = [];
$edit_column = $this
->getEditColumnLink($this
->id(), $row_id, $column_id);
$delete_column = $this
->getDeleteColumnLink($this
->id(), $row_id, $column_id);
$columns[] = [
Constants::EDIT_COLUMN => $edit_column,
Constants::DELETE_COLUMN => $delete_column,
Constants::COLUMN_ID => $column_id,
Constants::COLUMN_WIDTH_NUMBER => $last_column_class,
Constants::COLUMN_WIDTH_PREFIX => $column_width_prefix,
Constants::DEFAULT_COLUMN_CLASS => $starting_default_column_class,
Constants::CUSTOM_COLUMN_CLASSES => [],
Constants::COLUMN_NAME => '',
Constants::REGION_NAME => 'r' . $row_id . 'c' . $column_id,
Constants::ADMIN_COLUMN_CLASSES => [
Constants::DYNAMIC_LAYOUT_COLUMN,
],
];
$rows[] = [
Constants::ROW_ID => $row_id,
Constants::DEFAULT_ROW_CLASS => $starting_default_row_class,
'admin_row_classes' => [
'dynamic-layout-row',
],
Constants::CUSTOM_ROW_CLASSES => [],
Constants::COLUMNS => $columns,
];
}
$this->regions = serialize($rows);
$this
->save();
}
private function getDeleteColumnLink($entity_id, $row_id, $column_id) {
$delete_column_url = Url::fromRoute('dynamic_layouts.delete_column', [
Constants::COLUMN_ID => $column_id,
'dynamic_layout_id' => $entity_id,
Constants::ROW_ID => $row_id,
]);
$title = t('Delete column');
$link_options = [
'attributes' => [
'class' => [
'delete-link',
'btn',
'use-ajax',
],
'title' => $title,
],
];
$delete_column_url
->setOptions($link_options);
$delete_column_link = Link::fromTextAndUrl($title, $delete_column_url);
$delete_column = $delete_column_link
->toRenderable();
return render($delete_column);
}
private function getEditColumnLink($entity_id, $row_id, $column_id) {
$edit_column_url = Url::fromRoute('dynamic_layouts.edit_column_modal_form', [
Constants::COLUMN_ID => $column_id,
'entity_id' => $entity_id,
Constants::ROW_ID => $row_id,
]);
$title = t('Edit column');
$link_options = [
'attributes' => [
'class' => [
'edit-link',
'btn',
'use-ajax',
],
'title' => $title,
],
];
$edit_column_url
->setOptions($link_options);
$edit_column_link = Link::fromTextAndUrl($title, $edit_column_url);
$edit_column = $edit_column_link
->toRenderable();
return render($edit_column);
}
public function getRowLink($row_id, $route, $text, array $options = []) {
$link = Link::createFromRoute($text, $route, [
'dynamic_layout_id' => $this
->id(),
Constants::ROW_ID => $row_id,
], $options);
$renderLink = $link
->toRenderable();
return render($renderLink);
}
public function deleteColumn($row_id, $column_id) {
$updated_row = $this
->getRowById($row_id);
$columns = $updated_row[Constants::COLUMNS];
$calculated_column_width_number = NULL;
if ($settings = \Drupal::entityTypeManager()
->getStorage(Constants::DYNAMIC_LAYOUT_SETTINGS)
->load(Constants::SETTINGS)) {
$calculated_column_width_number = $this
->calculateColumnWidth($columns, $settings, 'deleted');
}
foreach ($columns as $key => $column) {
if ($column[Constants::COLUMN_ID] == $column_id) {
unset($columns[$key]);
continue;
}
if ($calculated_column_width_number && !isset($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER])) {
$columns[$key][Constants::COLUMN_WIDTH_NUMBER] = $calculated_column_width_number;
}
}
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key][Constants::COLUMNS] = $columns;
}
}
$this->regions = serialize($rows);
}
public function addColumn($row_id) {
$updated_row = $this
->getRowById($row_id);
$columns = $updated_row[Constants::COLUMNS];
$column_id = uniqid();
$column_width_number = '';
$edit_column = $this
->getEditColumnLink($this
->id(), $row_id, $column_id);
$delete_column = $this
->getDeleteColumnLink($this
->id(), $row_id, $column_id);
$column_width_prefix = '';
if ($settings = \Drupal::entityTypeManager()
->getStorage(Constants::DYNAMIC_LAYOUT_SETTINGS)
->load(Constants::SETTINGS)) {
$column_classes = $settings
->getFrontendColumnClasses();
$column_width_number = end($column_classes);
$column_width_prefix = $settings
->getColumnPrefix();
if ($calculated_column_width_number = $this
->calculateColumnWidth($columns, $settings, 'added')) {
$column_width_number = $calculated_column_width_number;
foreach ($columns as $key => $column) {
if (!isset($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER])) {
$columns[$key][Constants::COLUMN_WIDTH_NUMBER] = $calculated_column_width_number;
}
}
}
}
$columns[] = [
Constants::EDIT_COLUMN => $edit_column,
Constants::DELETE_COLUMN => $delete_column,
Constants::COLUMN_ID => $column_id,
Constants::COLUMN_WIDTH_NUMBER => $column_width_number,
Constants::COLUMN_WIDTH_PREFIX => $column_width_prefix,
Constants::DEFAULT_COLUMN_CLASS => $this->default_column_class,
Constants::CUSTOM_COLUMN_CLASSES => [],
Constants::COLUMN_NAME => '',
Constants::REGION_NAME => 'r' . $row_id . 'c' . $column_id,
Constants::ADMIN_COLUMN_CLASSES => [
Constants::DYNAMIC_LAYOUT_COLUMN,
],
];
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
if ($row[Constants::ROW_ID] == $row_id) {
$rows[$key][Constants::COLUMNS] = $columns;
}
}
$this->regions = serialize($rows);
}
private function calculateColumnWidth($columns, DynamicLayoutSettingsInterface $settings, $action) {
if (!$settings) {
return NULL;
}
if (!$columns) {
return NULL;
}
$column_counter = 0;
foreach ($columns as $column) {
if (!isset($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER])) {
$column_counter++;
}
}
$column_count = $column_counter + 1;
if ($action == 'deleted') {
$column_count = $column_counter - 1;
}
$grid_column_count = \intval($settings
->getGridColumnCount());
return \round($grid_column_count / $column_count);
}
public function getRows() {
return unserialize($this->regions);
}
public function getLayoutRegions() {
$rows = $this
->getRows();
$layout_regions = [];
$row_count = 1;
foreach ($rows as $row) {
if (!isset($row[Constants::ROW_ID]) || !isset($row[Constants::COLUMNS])) {
continue;
}
$column_count = 1;
foreach ($row[Constants::COLUMNS] as $column) {
$region_name = t('Row @row_count - Column @column_count', [
'@row_count' => $row_count,
'@column_count' => $column_count,
]);
$region_machine_name = 'r' . $row[Constants::ROW_ID] . 'c' . $column[Constants::COLUMN_ID];
if (isset($column[Constants::COLUMN_NAME]) && $column[Constants::COLUMN_NAME]) {
$region_name = $column[Constants::COLUMN_NAME];
$region_machine_name = strtolower($region_name);
$region_machine_name = preg_replace('/[^a-z0-9_]+/', '_', $region_machine_name);
$region_machine_name = preg_replace('/_+/', '_', $region_machine_name);
if (isset($column[Constants::REGION_NAME]) && $column[Constants::REGION_NAME]) {
$region_machine_name = $column[Constants::REGION_NAME];
}
}
$layout_regions[$region_machine_name] = [
'label' => $region_name,
];
$column_count++;
}
$row_count++;
}
return $layout_regions;
}
private function getRowById($row_id) {
$rows = $this
->getRows();
$row_by_number = [];
foreach ($rows as $row) {
if ($row[Constants::ROW_ID] === $row_id) {
$row_by_number = $row;
}
}
return $row_by_number;
}
private function getColumnById($row, $column_id) {
$column_by_id = [];
foreach ($row[Constants::COLUMNS] as $column) {
if ($column[Constants::COLUMN_ID] === $column_id) {
$column_by_id = $column;
}
}
return $column_by_id;
}
public function getIconMap() {
$icon_map = [];
$rows = $this
->getRows();
foreach ($rows as $key => $row) {
$icon_map[$key] = [];
if (isset($row[Constants::COLUMNS]) && !empty(Constants::COLUMNS)) {
$columns = $row[Constants::COLUMNS];
foreach ($columns as $column) {
$column_width_number = $column[Constants::COLUMN_WIDTH_NUMBER];
if (isset($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER]) && !empty($column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER])) {
$column_width_number = $column[Constants::CUSTOM_COLUMN_WIDTH_NUMBER];
}
for ($i = 1; $i <= $column_width_number; $i++) {
$icon_map[$key][] = $column[Constants::COLUMN_ID];
}
}
}
}
return array_values($icon_map);
}
}