<?php
namespace Module\Vendor\QuickRun\CustomField;
use Illuminate\Support\Facades\Cache;
use ModStart\Core\Dao\ModelManageUtil;
use ModStart\Core\Dao\ModelUtil;
use ModStart\Core\Exception\BizException;
use ModStart\Core\Util\SerializeUtil;
use ModStart\Detail\Detail;
use ModStart\Form\Form;
use ModStart\Grid\Grid;
use ModStart\Grid\GridFilter;
class CustomFieldUtil
{
public static function clearCache($tableField)
{
Cache::forget('QuickRunCustomField:' . $tableField . ':fields');
}
public static function deleteField($table, $field)
{
ModelManageUtil::ddlFieldDrop($table, $field['name']);
}
public static function addField($table, $field)
{
$fieldType = self::convertField($field);
ModelManageUtil::ddlFieldAdd($table, $field['name'], $fieldType);
}
public static function editField($table, $oldField, $newField)
{
$oldFieldType = self::convertField($oldField);
$newFieldType = self::convertField($newField);
if ($oldFieldType != $newFieldType || $oldField['name'] != $newField['name']) {
if ($oldField['name'] == $newField['name']) {
ModelManageUtil::ddlFieldModify($table, $newField['name'], $newFieldType);
} else {
ModelManageUtil::ddlFieldChange($table, $oldField['name'], $newField['name'], $newFieldType);
}
}
}
private static function convertField($field)
{
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
case CustomFieldType::TEXTAREA:
case CustomFieldType::RADIO:
case CustomFieldType::SELECT:
case CustomFieldType::CHECKBOX:
case CustomFieldType::IMAGE:
case CustomFieldType::IMAGES:
case CustomFieldType::FILE:
return "VARCHAR($field[maxLength])";
case CustomFieldType::DATE:
return "DATE";
case CustomFieldType::DATETIME:
return "DATETIME";
case CustomFieldType::RICH_TEXT:
return "TEXT";
}
return null;
}
private static function fields($config)
{
return Cache::rememberForever('QuickRunCustomField:' . $config['tableField'] . ':fields', function () use ($config) {
$fields = ModelUtil::all($config['tableField'], [], [
'name', 'title', 'fieldType', 'fieldData', 'maxLength', 'enable', 'isRequired', 'isSearch', 'isList', 'placeholder'
], ['sort', 'asc']);
ModelUtil::decodeRecordsJson($fields, 'fieldData');
return $fields;
});
}
public static function fieldsEnabled($config)
{
return array_values(array_filter(self::fields($config), function ($o) {
return $o['enable'];
}));
}
public static function buildCRUDField($config, $hasField)
{
if ($hasField instanceof Grid) {
self::buildGridField($config, $hasField);
} else if ($hasField instanceof Form) {
self::buildFormField($config, $hasField);
} else if ($hasField instanceof Detail) {
self::buildDetailField($config, $hasField);
}
}
public static function buildGridField($config, Grid $grid)
{
$fields = self::fieldsEnabled($config);
foreach ($fields as $field) {
if ($field['isList']) {
$options = [];
if (!empty($field['fieldData']['options'])) {
$options = array_build($field['fieldData']['options'], function ($k, $v) {
return [$v, $v];
});
}
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
$f = $grid->text($field['name'], $field['title']);
break;
case CustomFieldType::TEXTAREA:
$f = $grid->textarea($field['name'], $field['title']);
break;
case CustomFieldType::RADIO:
$f = $grid->radio($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::SELECT:
$f = $grid->select($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::CHECKBOX:
$f = $grid->checkbox($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::IMAGE:
$f = $grid->image($field['name'], $field['title']);
break;
case CustomFieldType::IMAGES:
$f = $grid->images($field['name'], $field['title']);
break;
case CustomFieldType::FILE:
$f = $grid->file($field['name'], $field['title']);
break;
case CustomFieldType::DATE:
$f = $grid->date($field['name'], $field['title']);
break;
case CustomFieldType::DATETIME:
$f = $grid->datetime($field['name'], $field['title']);
break;
case CustomFieldType::RICH_TEXT:
$f = $grid->richHtml($field['name'], $field['title']);
break;
default:
BizException::throws('未知字段类型' . SerializeUtil::jsonEncode($field, JSON_UNESCAPED_UNICODE));
}
$f->placeholder($field['placeholder']);
if ($field['isRequired']) {
$f->required();
}
}
}
}
public static function buildGridFilter($config, GridFilter $filter)
{
$fields = self::fieldsEnabled($config);
foreach ($fields as $field) {
if ($field['isSearch']) {
$options = [];
if (!empty($field['fieldData']['options'])) {
$options = array_build($field['fieldData']['options'], function ($k, $v) {
return [$v, $v];
});
}
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
case CustomFieldType::TEXTAREA:
$filter->like($field['name'], $field['title']);
break;
case CustomFieldType::RADIO:
case CustomFieldType::SELECT:
$filter->eq($field['name'], $field['title'])->select($options);
break;
case CustomFieldType::DATE:
$filter->range($field['name'], $field['title'])->date();
break;
case CustomFieldType::DATETIME:
$filter->range($field['name'], $field['title'])->datetime();
break;
}
}
}
}
public static function buildFormField($config, Form $form)
{
$fields = self::fieldsEnabled($config);
foreach ($fields as $field) {
$options = [];
if (!empty($field['fieldData']['options'])) {
$options = array_build($field['fieldData']['options'], function ($k, $v) {
return [$v, $v];
});
}
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
$f = $form->text($field['name'], $field['title']);
break;
case CustomFieldType::TEXTAREA:
$f = $form->textarea($field['name'], $field['title']);
break;
case CustomFieldType::RADIO:
$f = $form->radio($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::SELECT:
$f = $form->select($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::CHECKBOX:
$f = $form->checkbox($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::IMAGE:
$f = $form->image($field['name'], $field['title']);
break;
case CustomFieldType::IMAGES:
$f = $form->images($field['name'], $field['title']);
break;
case CustomFieldType::FILE:
$f = $form->file($field['name'], $field['title']);
break;
case CustomFieldType::DATE:
$f = $form->date($field['name'], $field['title']);
break;
case CustomFieldType::DATETIME:
$f = $form->datetime($field['name'], $field['title']);
break;
case CustomFieldType::RICH_TEXT:
$f = $form->richHtml($field['name'], $field['title']);
break;
default:
BizException::throws('未知字段类型' . SerializeUtil::jsonEncode($field, JSON_UNESCAPED_UNICODE));
}
$f->placeholder($field['placeholder']);
if ($field['isRequired']) {
$f->required();
}
}
}
public static function buildDetailField($config, Detail $detail)
{
$fields = self::fieldsEnabled($config);
foreach ($fields as $field) {
$options = [];
if (!empty($field['fieldData']['options'])) {
$options = array_build($field['fieldData']['options'], function ($k, $v) {
return [$v, $v];
});
}
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
$f = $detail->text($field['name'], $field['title']);
break;
case CustomFieldType::TEXTAREA:
$f = $detail->textarea($field['name'], $field['title']);
break;
case CustomFieldType::RADIO:
$f = $detail->radio($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::SELECT:
$f = $detail->select($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::CHECKBOX:
$f = $detail->checkbox($field['name'], $field['title'])->options($options);
break;
case CustomFieldType::IMAGE:
$f = $detail->image($field['name'], $field['title']);
break;
case CustomFieldType::IMAGES:
$f = $detail->images($field['name'], $field['title']);
break;
case CustomFieldType::FILE:
$f = $detail->file($field['name'], $field['title']);
break;
case CustomFieldType::DATE:
$f = $detail->date($field['name'], $field['title']);
break;
case CustomFieldType::DATETIME:
$f = $detail->datetime($field['name'], $field['title']);
break;
case CustomFieldType::RICH_TEXT:
$f = $detail->richHtml($field['name'], $field['title']);
break;
default:
BizException::throws('未知字段类型' . SerializeUtil::jsonEncode($field, JSON_UNESCAPED_UNICODE));
}
$f->placeholder($field['placeholder']);
if ($field['isRequired']) {
$f->required();
}
}
}
private static function processRecord($fields, $record)
{
if (empty($record)) {
return $record;
}
foreach ($fields as $field) {
if (!isset($record[$field['name']])) {
continue;
}
switch ($field['fieldType']) {
case CustomFieldType::CHECKBOX:
case CustomFieldType::IMAGES:
$record[$field['name']] = @json_decode($record[$field['name']], true);
if (empty($record[$field['name']])) {
$record[$field['name']] = [];
}
break;
}
}
return $record;
}
public static function buildRecord($config, $record)
{
$fields = self::fields($config);
return self::processRecord($fields, $record);
}
public static function buildRecords($config, $records)
{
$fields = self::fields($config);
foreach ($records as $k => $record) {
$records[$k] = self::processRecord($fields, $record);
}
return $records;
}
public static function renderValue($field, $record)
{
if (!isset($record[$field['name']])) {
return '';
}
$value = $record[$field['name']];
switch ($field['fieldType']) {
case CustomFieldType::TEXT:
case CustomFieldType::TEXTAREA:
case CustomFieldType::RADIO:
case CustomFieldType::SELECT:
case CustomFieldType::DATE:
case CustomFieldType::DATETIME:
return htmlspecialchars($value);
case CustomFieldType::CHECKBOX:
return htmlspecialchars(join(',', $value));
case CustomFieldType::IMAGE:
return '<div><img src="' . htmlspecialchars($value) . '" style="max-width:100%;" /></div>';
case CustomFieldType::IMAGES:
$html = [];
foreach ($value as $v) {
$html[] = '<div><img src="' . htmlspecialchars($v) . '" style="max-width:100%;" /></div>';
}
return join('', $html);
case CustomFieldType::FILE:
return "<a href='" . htmlspecialchars($value) . "' target='_blank'>" . htmlspecialchars($value) . "</a>";
case CustomFieldType::RICH_TEXT:
return "<div class='ub-html'>" . $value . "</div>";
}
}
}