362 lines
8.3 KiB
PHP
362 lines
8.3 KiB
PHP
<?php
|
|
/**
|
|
* Plugin.php
|
|
*
|
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
|
* @link https://beikeshop.com
|
|
* @author Edward Yang <yangjin@guangda.work>
|
|
* @created 2022-06-29 20:27:21
|
|
* @modified 2022-06-29 20:27:21
|
|
*/
|
|
|
|
namespace Beike\Plugin;
|
|
|
|
use Beike\Repositories\PluginRepo;
|
|
use Beike\Repositories\SettingRepo;
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Str;
|
|
|
|
class Plugin implements Arrayable, \ArrayAccess
|
|
{
|
|
public const TYPES = [
|
|
'payment', // 支付方式
|
|
'shipping', // 配送方式
|
|
'theme', // 主题模板
|
|
'feature', // 功能模块
|
|
'total', // 订单金额
|
|
'social', // 社交网络
|
|
'language', // 语言翻译
|
|
];
|
|
|
|
protected $type;
|
|
|
|
protected $path;
|
|
|
|
protected $name;
|
|
|
|
protected $description;
|
|
|
|
protected $packageInfo;
|
|
|
|
protected $dirName;
|
|
|
|
protected $installed;
|
|
|
|
protected $enabled;
|
|
|
|
protected $version;
|
|
|
|
protected $columns;
|
|
|
|
public function __construct(string $path, array $packageInfo)
|
|
{
|
|
$this->path = $path;
|
|
$this->packageInfo = $packageInfo;
|
|
}
|
|
|
|
public function __get($name)
|
|
{
|
|
return $this->packageInfoAttribute(Str::snake($name, '-'));
|
|
}
|
|
|
|
public function __isset($name)
|
|
{
|
|
return isset($this->{$name}) || $this->packageInfoAttribute(Str::snake($name, '-'));
|
|
}
|
|
|
|
public function packageInfoAttribute($name)
|
|
{
|
|
return Arr::get($this->packageInfo, $name);
|
|
}
|
|
|
|
/**
|
|
* Set plugin Type
|
|
*
|
|
* @throws \Exception
|
|
*/
|
|
public function setType(string $type): self
|
|
{
|
|
if (! in_array($type, self::TYPES)) {
|
|
throw new \Exception('Invalid plugin type, must be one of ' . implode(',', self::TYPES));
|
|
}
|
|
$this->type = $type;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setDirname(string $dirName): self
|
|
{
|
|
$this->dirName = $dirName;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setName(string|array $name): self
|
|
{
|
|
$this->name = $name;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setDescription(string|array $description): self
|
|
{
|
|
$this->description = $description;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setInstalled(bool $installed): self
|
|
{
|
|
$this->installed = $installed;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setEnabled(bool $enabled): self
|
|
{
|
|
$this->enabled = $enabled;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setVersion(string $version): self
|
|
{
|
|
$this->version = $version;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setColumns(): self
|
|
{
|
|
$columnsPath = $this->path . DIRECTORY_SEPARATOR . 'columns.php';
|
|
if (! file_exists($columnsPath)) {
|
|
return $this;
|
|
}
|
|
$this->columns = require_once $columnsPath;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 处理插件后台设置字段多语言 优先级: label > label_key
|
|
* 有label字段则直接返回, label_key 则翻译
|
|
*/
|
|
public function handleLabel()
|
|
{
|
|
$this->columns = collect($this->columns)->map(function ($item) {
|
|
$item = $this->transLabel($item);
|
|
if (isset($item['options'])) {
|
|
$item['options'] = collect($item['options'])->map(function ($option) {
|
|
return $this->transLabel($option);
|
|
})->toArray();
|
|
}
|
|
|
|
return $item;
|
|
})->toArray();
|
|
}
|
|
|
|
/**
|
|
* 翻译 label
|
|
* @param $item
|
|
* @return mixed
|
|
*/
|
|
private function transLabel($item)
|
|
{
|
|
$labelKey = $item['label_key'] ?? '';
|
|
$label = $item['label'] ?? '';
|
|
if (empty($label) && $labelKey) {
|
|
$languageKey = "{$this->dirName}::{$labelKey}";
|
|
$item['label'] = trans($languageKey);
|
|
}
|
|
|
|
$descriptionKey = $item['description_key'] ?? '';
|
|
$description = $item['description'] ?? '';
|
|
if (empty($description) && $descriptionKey) {
|
|
$languageKey = "{$this->dirName}::{$descriptionKey}";
|
|
$item['description'] = trans($languageKey);
|
|
}
|
|
|
|
return $item;
|
|
}
|
|
|
|
public function getName()
|
|
{
|
|
return $this->name;
|
|
}
|
|
|
|
public function getLocaleName(): string
|
|
{
|
|
$currentLocale = admin_locale();
|
|
|
|
if (is_array($this->name)) {
|
|
if ($this->name[$currentLocale] ?? '') {
|
|
return $this->name[$currentLocale];
|
|
}
|
|
|
|
return array_values($this->name)[0];
|
|
}
|
|
|
|
return (string) $this->name;
|
|
}
|
|
|
|
public function getDescription()
|
|
{
|
|
return $this->description;
|
|
}
|
|
|
|
public function getLocaleDescription(): string
|
|
{
|
|
$currentLocale = admin_locale();
|
|
|
|
if (is_array($this->description)) {
|
|
if ($this->description[$currentLocale] ?? '') {
|
|
return $this->description[$currentLocale];
|
|
}
|
|
|
|
return array_values($this->description)[0];
|
|
}
|
|
|
|
return (string) $this->description;
|
|
}
|
|
|
|
public function getType(): string
|
|
{
|
|
return $this->type;
|
|
}
|
|
|
|
public function getDirname(): string
|
|
{
|
|
return $this->dirName;
|
|
}
|
|
|
|
public function getPath(): string
|
|
{
|
|
return $this->path;
|
|
}
|
|
|
|
public function getVersion(): string
|
|
{
|
|
return $this->version;
|
|
}
|
|
|
|
public function getEditUrl(): string
|
|
{
|
|
return admin_route('plugins.edit', ['code' => $this->code]);
|
|
}
|
|
|
|
public function getStatus(): bool
|
|
{
|
|
return SettingRepo::getPluginStatus($this->code);
|
|
}
|
|
|
|
public function getInstalled(): bool
|
|
{
|
|
return PluginRepo::installed($this->code);
|
|
}
|
|
|
|
public function getEnabled(): bool
|
|
{
|
|
return $this->enabled;
|
|
}
|
|
|
|
public function getSetting($name = '')
|
|
{
|
|
if ($name) {
|
|
return plugin_setting("{$this->code}.{$name}");
|
|
}
|
|
|
|
return plugin_setting($this->code);
|
|
}
|
|
|
|
/**
|
|
* 获取插件对应的设置字段, 并获取已存储在DB的字段值
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getColumns(): array
|
|
{
|
|
$this->columns[] = SettingRepo::getPluginStatusColumn();
|
|
$existValues = SettingRepo::getPluginColumns($this->code);
|
|
foreach ($this->columns as $index => $column) {
|
|
$dbColumn = $existValues[$column['name']] ?? null;
|
|
$value = $dbColumn ? $dbColumn->value : null;
|
|
if ($column['name'] == 'status') {
|
|
$value = (int) $value;
|
|
}
|
|
$this->columns[$index]['value'] = $value;
|
|
}
|
|
|
|
return $this->columns;
|
|
}
|
|
|
|
/**
|
|
* 字段验证
|
|
* @param $requestData
|
|
* @return \Illuminate\Contracts\Validation\Validator
|
|
*/
|
|
public function validate($requestData): \Illuminate\Contracts\Validation\Validator
|
|
{
|
|
$rules = array_column($this->columns, 'rules', 'name');
|
|
|
|
return Validator::make($requestData, $rules);
|
|
}
|
|
|
|
/**
|
|
* 获取插件自定义编辑模板
|
|
* @return string
|
|
*/
|
|
public function getColumnView(): string
|
|
{
|
|
$viewFile = $this->getPath() . '/Views/admin/config.blade.php';
|
|
if (file_exists($viewFile)) {
|
|
return "{$this->dirName}::admin.config";
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* 获取插件启动文件路径
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getBootFile(): string
|
|
{
|
|
return $this->getPath() . '/Bootstrap.php';
|
|
}
|
|
|
|
public function toArray(): array
|
|
{
|
|
return (array) array_merge([
|
|
'name' => $this->name,
|
|
'version' => $this->getVersion(),
|
|
'path' => $this->path,
|
|
], $this->packageInfo);
|
|
}
|
|
|
|
public function offsetExists($key): bool
|
|
{
|
|
return Arr::has($this->packageInfo, $key);
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function offsetGet($key)
|
|
{
|
|
return $this->packageInfoAttribute($key);
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function offsetSet($key, $value)
|
|
{
|
|
return Arr::set($this->packageInfo, $key, $value);
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function offsetUnset($key)
|
|
{
|
|
unset($this->packageInfo[$key]);
|
|
}
|
|
}
|