vukbgit/simplex

v3.15.37 2024-09-19 09:18 UTC

This package is auto-updated.

Last update: 2024-09-19 09:20:32 UTC


README

一个针对Web开发者的工具

目录

简介

Simplex是一个用于开发PHP/HTML/CSS Web应用程序的工具。简而言之,它设置了一个便捷的环境,以便您只需编写特定于项目业务逻辑的代码文件:PHP(类和一些配置文件)、HTML(Twig模板)和CSS或SCSS

Simplex的目标是提供

  • PHP Web应用程序的结构,它是在
    • 简单性
    • 最新标准和实践(据我所知)之间的一种折衷
  • 快速简便地开始开发应用程序代码的方式

为此,Simplex依赖于

  • Composer包(通过Packagist包)
    • Simplex自身是一个Composer包,它
      • 负责安装所需的库(至少是最小功能)
      • 创建应用程序的基本起始结构,其中包含一些几乎可以立即使用的草稿文件,但可以根据需要删除、修改和集成
    • 其他选定的Composer包被集成以创建应用程序的核心引擎
  • NPM用于JavaScript和CSS包
  • Bootstrap作为CSS框架
  • Fontello用于图标

关于本文件的说明:我将尽力使说明清晰,并记录所有细节,以便理解和使用Simplex,为未来的我、任何可能的同事以及任何其他感兴趣的人带来好处

需求

  • Linux操作系统上的服务器(主要在Debian 10/11上进行了测试)
  • Web服务器:Simplex始终使用Apache 2.4+,.htaccess文件用于基本路由;我认为它也可以使用Nginx,但从未进行过测试
  • PHP 8.2+,启用了PHP的gettext和bcmath扩展
  • Web空间的ssh访问:在共享托管上使用Composer(以及Npm和Sass)很困难,您必须在本地开发并提交,但我真的建议您找到可以提供ssh访问的提供商;一旦我尝试了租用的ssh shell的强大和舒适,我就租用了自己的虚拟机,再也没有回到共享托管...
  • Composer别名(全局或局部)为composer命令
  • 前端包管理器:Simplex建议全局安装npm
  • Sass(我目前使用的是1.56.1版本,由dart2js 2.18.4编译):用于编译带有变量、混合和其他许多有用功能以及自定义bootstrap的css

术语

  • root:Simplex安装的顶级文件夹,通常是站点Web空间可访问部分的顶级文件夹
  • application:针对特定项目/域定制的Simplex安装
  • private:应用程序中隐藏在浏览器之外的区域
  • public:应用程序对浏览器开放的区域
  • share:应用程序中存储第三方库和文件的区域,主要针对Packagist PHP库的private/share,以及针对npm前端包的public/share/node_modules
  • environment:当前请求被处理的环境,Simplex假设“开发”和“生产”的值,但可以在每个安装的基础上定义其他变体
  • area:应用程序的一部分,匹配具有共同属性、要求和行为的路由集,例如“后端”、“前端”、“Cron”,每个路由都必须设置一个'area'参数,其格式应为一个slug
  • subject:在一个ERP区域中,主题是由以下系统名称构成的
    • 控制器
    • 控制器处理的路线集
    • 对应这些路线的动作集
    • 对应这些动作的控制器方法
    • 每个动作操作的模式
  • action:与路由关联的具体逻辑,例如“list”或“save-form”,每个路由都必须设置一个'actor'参数,其格式应为一个slug

约定

  • 以下解释文件和路径以斜体形式给出
  • 对于每个文件,总是给出从root开始的路径,不包含前导斜杠

预安装 - 升级任务

在从头安装或从2.x版本升级之前

  • 下载ini配置文件草稿

  • 将其保存到Web空间外部的根文件夹,命名为config.ini

  • 编辑并设置至少必须的值,按照注释进行

  • 将PATH_TO_INI_CONFIG环境变量永久设置为文件的绝对路径,将文件添加到系统用户的.bashrc文件中(通常是home/user-name/.bashrc

      export PATH_TO_INI_CONFIG=absolute/path/to/config.ini
    
  • 如果在执行安装/升级的同个控制台中登录,请注销以使$PATH_TO_INI_CONFIG可用于脚本

安装

在根文件夹中创建一个composer.json

{
  "type": "project",
  "name": "vuk/simplex",
  "description": "Simplex app",
  "license": "MIT",
  "require": {
    "vukbgit/simplex": "^3.0"
  },
  "config": {
    "vendor-dir": "private/share/packagist",
    "bin-dir": "./"
  },
  "autoload": {
    "psr-4": {
      "Simplex\\Local\\": "private/local/simplex"
    }
  },
  "scripts": {
    "post-create-project-cmd": [
      "SlowProg\\CopyFile\\ScriptHandler::copy"
    ],
    "pre-update-cmd": [
      "Simplex\\Refactor::preRefactoring"
    ],
    "post-update-cmd": [
      "Simplex\\Refactor::postRefactoring"
    ]
  },
  "extra": {
    "copy-file": {
      "private/share/packagist/vukbgit/simplex/installation/": "."
    }
  }
}

注意:对于版本约束(^3.0),请检查GitHub仓库上的最后一个标签或packagist上的非开发版本号。

在根文件夹中通过命令行运行Composer项目

    composer create-project

Simplex将

  • 安装自己和其他必需的Composer库
  • 将一些文件复制到根目录
  • 在根目录中创建一些shell脚本的符号链接(Composer vendor binaries
  • 使用一些草稿文件为本地应用程序构建文件夹结构

有关详细信息,请参阅下面的文件夹和文件结构

升级

从2.x版本开始

  • 遵循安装前 - 升级任务

  • 将“scripts”数组中的后更新重构脚本添加到composer.json中

    "post-update-cmd": [
      "Simplex\\Refactor::postRefactoring"
    ]
    
  • 运行composer upgrade命令

  • 查看输出,寻找需要采取行动的消息

  • 最后检查保存到private/local/log的重构日志

  • 将预更新重构脚本添加到composer.json中的“scripts”数组

    "pre-update-cmd": [
      "Simplex\\Refactor::preRefactoring"
    ]
    
  • 如有必要,将private/local/simplex/log/添加到.gitignore中

从3.x版本小于3.13的版本

  • 注意当前版本,即./composer.sh show vukbgit/simplex

  • 更新composer包:./composer.sh update

  • 调用refactor.php进行预阶段,使用旧版本,例如:php8.2 private/share/packagist/vukbgit/simplex/bin/refactor.php pre 3.4.0

  • 调用refactor.php进行后阶段,例如:php8.2 private/share/packagist/vukbgit/simplex/bin/refactor.php post

  • 查看输出和日志,寻找需要采取行动的消息

  • 将预更新和后更新重构脚本添加到composer.json中的“scripts”数组

    "pre-update-cmd": [
      "Simplex\\Refactor::preRefactoring"
    ],
    "post-update-cmd": [
      "Simplex\\Refactor::postRefactoring"
    ]
    
  • 如有必要,将private/local/simplex/log/添加到.gitignore中

安装后任务

  • config.ini:
    • 应该已经就位(见预安装 - 升级作业),配置最小化(否则什么都不起作用...)
    • 使用此文件存储任何尽可能保密的本地信息,如数据库凭据、密码、秘密API密钥等。
    • simplex bash脚本都包含private/share/packagist/vukbgit/simplex/bin/bootstrap.sh,该脚本需要包含config.ini,因此路径(绝对或相对于顶级调用的脚本)必须提供为
      • PATH_TO_INI_CONFIG环境变量,您可以将它导出为export PATH_TO_INI_CONFIG=path/to/config.ini
        • 在ssh会话中临时设置
        • 永久设置到home/user-name/.bashrc(或等效的,您应该在安装之前完成)
      • 或将-in选项传递给调用的脚本,后跟ini配置文件的绝对/相对路径,例如:simplex-script.sh -i path/to/config.ini
  • /.htaccess:
    • 设置默认重定向,例如 /backend 重定向到 /backend/sign-in-form;在任何情况下,您要么为纯域名请求定义一个路由,要么将域名请求重定向到默认路由(例如:RewriteRule ^/?$ /my-default-route [R,L]);有关路由定义,请参见下文
  • index.php:将$pathToIniConfig设置为ini配置文件的绝对或相对路径
  • 安装public
    • 文件public\share\package.json包含一些NPM包,用于
    • 如有需要,请编辑文件以包含/排除包
    • 安装包:Simplex 通过脚本 private/share/packagist/vukbgit/simplex/bin/npm.sh 预设使用 npm,该脚本通过符号链接链接到根目录
      • ./npm.sh install
    • 包安装于 \public\share\node_modules
  • 本地 配置:文件 private\local\simplex\config\constants.php 定义了一些 PHP 常量,大部分与路径有关,除非你计划更改 Simplex 所依赖的文件系统结构,否则不需要修改它们;本地应用(技术电子邮件、品牌名称等)的信息被组织在脚本顶部的 LOCAL 块中
  • 语言:
    • 文件 private\local\simplex\config\languages.json 定义了使用的语言,默认包含英语和意大利语的定义,根据需要添加更多;语言选择方式如下
      • 如果当前路由包含一个 'lang' 参数(通常是多语言网站的路径的一部分),则使用该语言
      • 否则,使用 private\local\simplex\config\languages.json 中定义的第一个语言,因此如果你只需要一种语言,可以将它的定义放在第一个位置
  • 设置应用 模板:在 private/local/templates/application.twig 中提供了一个用于整个应用的 Twig 模板
    • 它包含一个用于显示由 https://www.favicon-generator.org 生成的 favicon 的 Twig 宏,如果你想使用它,请访问网站,生成图标图像,上传它们(例如到 public/local/corporate/favicon),并将路径作为 favicon() 宏的参数设置
  • 设置 路由
    • 如上所述在 .htaccess 部分,当浏览器指向 your-domain.ltd 时有两个选项
      • 定义了一个空路由
      • .htacces 将对纯域名的请求重定向到默认路由
    • 路由设置在 route.php 文件中,这些文件存储在 config 文件夹中
    • 如上所述的 术语 部分,Simplex 逻辑是将应用划分为逻辑区域,对应于文件夹;Simplex 随附一个 private/local/simplex/Backend 文件夹作为构建应用后端的草案,其中包含一个 config/routes.php 文件,其中定义了 3 个用于登录操作的路由(显示登录表单、执行登录验证和注销)
    • 后端文件夹可以重命名为其他名称以适应应用逻辑,但必须进行一些调整(routes.php 中的区域变量值和 templates/backend.twig 文件名)
    • 还有一个 private/local/simplex/SubjectGroup 文件夹,它是开发主题的草案
  • 将 SASS 文件编译为 CSS
    • Simplex 鼓励将 SASS 源文件(.scss)编译为 CSS 文件(.css)。

    • private/local/simplex/config/sass.config 包含 SASS 到 CSS 文件的映射,每个配对都标记为一个 id(见文件中的说明)

    • sass.sh 是指向用于编译 CSS 文件的 shell 脚本的符号链接,它用于根目录

        ./sass.sh id-of-sass-file-to-be-compiled
      
    • Simplex 需要编译至少这些文件

      • 应用(private/local/simplex/sass/application.scss):整个应用的样式(包含在 private/local/simplex/templates/application.twig 中)
        • 它包括
          • share/vukbgit/simplex/src/sass/simplex.scss Simplex 样式,不能(不应...)自定义
          • private/local/simplex/sass/variable.scss 其中包含整个应用的 SASS 变量,可以/应该被自定义和扩展
        • 编译方式:./sass.sh app
      • Bootstrap:不同的应用区域可能需要不同的 Bootstrap 组件,因此没有预定义的 SCSS,但有几个草案
        • 最小化(_private/local/simplex/sass/bootstrap.scss):./sass.sh bs
        • 后端(_private/local/simplex/Backend/sass/bootstrap.scss):Simplex 后端模板所需的所有组件:./sass.sh bsb

区域设置

  • 每个路由都必须关联到一个区域(见 "术语" 部分)
  • 一个区域至少需要一些配置文件,可能还需要一个模板和一个 CSS 文件
  • Simplex 提供了两个起始区域,Backend 和 Frontend,可以进行调整和使用,或者作为其他区域的草案

后端 / ERP

Simplex 配套 ERP 命名空间草案,并使用它来构建后端和 ERP 应用程序。在此,我们假设区域名称为 "Backend",但可以更改为任何其他名称,您只需相应地重命名 Backend 文件夹并替换 "backend" 字词(注意字母大小写)。除了上面讨论的常用操作之外,以下是如何配置提供的 Backend 区域的步骤

  • .htaccess:设置 /backend 路由的重定向到 /backend/sign-in-form
  • 检查并设置 变量private/local/simplex/Backend/config/variables.php 中,至少需要 $successfulSignInRoute(默认为 backend/dashboard),其他默认值应该可以直接使用
  • private/local/simplex/Backend/config/routes.php 中设置 身份验证 方法
    • htpasswd:默认启用

      • 指向一个必须手动设置的 htpasswd 文件,cd 到目标文件夹(默认为 private/local/simplex/Backend/config

          htpasswd -c .htpasswd your-username
        
      • 在此文件中定义的每个用户都必须在 private/local/simplex/Backend/config/users-roles.php 中赋予一个角色

    • 数据库:默认注释,使用表或视图,指定字段名称和条件(如存储用户是否活跃的布尔字段)

  • logoPath 设置到 private/local/simplex/Backend/templates/sign-in-form.twig 中,以指向要显示在登录表单中的标志图像
  • logoPath 设置到 private/local/simplex/Backend/templates/backend.twig 中,以指向要显示在页眉中的标志图像,navbar 的高度默认为 48px,可以在 private/local/simplex/sass/variables.scss 中进行调整
  • 自定义区域样式(private/local/simplex/Backend/sass/backend.scss),它仅包括 ERP 风格和相关变量(private/local/simplex/Backend/sass/variables.scss
  • 编译 SASS 文件
    • 登录:./sass.sh si
    • 后端:./sass.sh be
  • 设置由 $successfulSignInRoute 路由调用的 主题(见下面的 "主题设置")
  • 要集成 jodit 上传器
    • 在根目录中运行 ./composer.sh create-project --no-dev jodit/connector public/share/jodit

    • 向任何富文本输入添加(由 displayRichTextEditor 宏构建)的配置,以显示与上传相关的 Jodit 按钮(例如图像)和上传路径

              ...
              options: {
                buttons: 'bold, italic, underline, strikethrough | ul, ol | cut, copy, paste | indent, outdent, left, right, center, justify | link | image | undo, redo | source,fullsize, preview | about',
                uploader: {
                  url: '/public/share/jodit/index.php?action=fileUpload',
                }
              }
              ...
      
    • public/share/jodit/Application.php 中,从 checkAuthentication 方法中删除异常,并添加可能的身份验证逻辑

    • public/share/jodit/default.config.php 复制为 public/share/jodit/config.php

    • 在公共路径中创建一个上传图像的文件夹,例如 public/local/simplex/richTextUploads

    • 如果使用 cvs 系统

      • 在提交中包含 jodit,编辑 public/share/jodit/.gitignore.php

              composer.lock
              .idea/
        
              tests/_data/
              tests/_output/
              tests/_support/
              tests/acceptance/
              tests/files/
        
      • 从提交中排除文件夹,例如 Git

        • 创建一个 public/local/simplex/richTextUploads/.gitignore 文件

        • 将内容粘贴到文件中

              # Ignore everything in this directory
              *
              !.gitignore
          
    • 编辑 public/share/jodit/config.php

      • 设置源文件夹,例如

              $basePath = '/public/local/simplex/';
              $richTextUploadFolder = $basePath . 'Foo/richTextUploads';
        
              $config = [
                  'sources' => [
                    'default' => [
                      'root' => $_SERVER['DOCUMENT_ROOT'] . $richTextUploadFolder,
                      'baseurl' => ((isset($_SERVER['HTTPS']) and $_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $richTextUploadFolder . '/',
                      'extensions' => [
                        'jpg',
                        'png',
                      ]
                    ],
                  ],
              ]
        
        • 编辑其他选项,如访问控制

这是后端文件夹结构

  • private/local/simplex
    • Backend
      • config
        • constants.php:
          • AREA_NAVIGATION_PATH:包含导航菜单定义的文件的路径,默认为 private/local/simplex/Backend/config/navigation.php
        • di-container.php:DI 容器定义,附带仅包含身份验证控制器定义的软件包,通常不需要在此处修改或添加定义,除非您有一个需要在整个区域中使用的类
        • navigation.php:导航菜单定义,返回一个包含一个或多个菜单定义的数组,这些菜单定义将在区域的页面上共享,请参阅文件以获取格式详细信息
        • premissions-roles:权限密钥和区域用户角色之间的映射(如身份验证系统中定义),只有在您想限制某些操作对某些角色的访问时才需要
        • route.php:与特定主题无关的区域路由定义,附带默认登录表单、登录和注销路由;包含一些指向与身份验证相关的文件的硬编码路径,通常不需要更改
        • users-roles:用户名与角色的映射,与身份验证系统(以及用户检索数据)解耦,尽可能灵活
        • 变量:区域级别变量(例如,带斜杠的区域名称和用于区域路由的默认身份验证对象),包含在特定的文件di-container.php和routes.php中
      • scss:
        • bootstrap.scss:要包含在Bootstrap区域样式表中的Bootstrap 4组件,预设用于最小标准功能(菜单、表单、表格等),需要时进行自定义和重新编译
      • 模板:登录表单和区域共享模板,主要用于存储翻译和标志路径,可以进行自定义
    • SubjectGroup:可以将主题命名空间组织到层级,当有超过十个主题时很有用
      • Subject:sdubjec级别文件,关于主题的每种类型的文件都应该存储在其文件夹中
        • config:
          • crudl.php:CRUDL功能的定义,例如用于从保存表单中获取字段值的输入过滤器,或是否使用字段来过滤显示的表格记录
          • di-container.php:DI容器定义,仅包含控制器和模型定义,对于标准主题应该足够
          • model-php:模型配置(表、视图、主键)
          • navigation.php:与主题操作关联的导航定义,包含默认的CRUDL操作(列表、插入、更新和删除),对于标准主题应该足够
          • routes.php:与主题操作关联的路由定义,包含一个覆盖默认CRUDL操作(列表、插入、更新和删除)的定义,以及任何由带斜杠的操作键和可选主键值标识的操作,对于标准主题应该足够
          • 变量:主题级别变量(例如,主题命名空间和带斜杠的主题名称)
        • 模板:与主题相关的模板,塑造主题UI并提供翻译
          • crudl-form.twig:使用在private/share/packagist/vukbgit/simplex/src/templates/form/macros.twig中定义的宏或直接编写HTML代码来创建主题插入、更新和删除表单的HTML
          • list.twig:主题记录列表的模板,默认为表格,需要设置表头和单元格
          • subject.twig:包含主题标签
        • Controller.php:基础主题控制器类,扩展Simplex\Erp\ControllerAbstract,必须设置正确的命名空间,但已继承所有CRUDL操作所需的方法,可以扩展以进行额外操作(使用PSR1斜杠操作名称形式命名的受保护方法)
        • Model.php:基础主题模型类,扩展Simplex\Model\ModelAbstract,必须设置正确的命名空间,但已继承所有CRUDL操作所需的方法,可以扩展以进行额外操作(使用PSR1斜杠操作名称形式命名的受保护方法)
    • bin:shell脚本,可以将它们作为软链接链接到Web根目录
      • composer.sh:用于使用与系统默认PHP版本不同的composer
    • config:应用程序配置文件
      • constants.php:必须在应用程序品牌标签和技术电子邮件(用于异常显示)中设置,其他值主要是路径,通常不需要更改
      • db.php:数据库账户设置(从config.ini获取数据)
      • languages.json:应用程序可用的语言,第一个用作默认值,包含意大利语(我的大多数应用程序的默认值)和英语,需要时进行自定义
      • sass.config:由web根目录的sass.sh bash脚本使用,以加速SASS文件的编译,包含一些可用的常用路径,请参阅文件以获取有关格式的详细信息
    • sql:此文件夹可能包含有用的文本文件,包含SQL命令和片段
      • views.sql:数据库视图定义,我通常在这里保留它们,因为我认为它们更适合编辑
    • sass:应用程序级别的SASS文件
      • application.scss:应用于整个应用程序的规则
      • bootstrap-variables.scss:用于覆盖Bootstrap变量,包含在bootstrap.scss中Bootstrap自己的变量文件之前
      • bootstrap.css:此文件可用于编译应用级别的bootstrap文件,如果不需要区域级别的文件
      • functions.scss:SASS函数
      • variables.scss:特定应用的SASS变量,例如颜色或某些特定的ERP设置(导航栏尺寸)
    • 模板:
      • application.twig:可直接使用的顶级应用模板
  • 公共
    • local:浏览器可访问的应用文件文件夹,至少会包含编译后的CSS文件,以及可能的大量应用资源
    • 共享
      • package.json:默认NPM包
      • npm.sh:链接到web根目录,用于处理npm命令
    • .htaccess:Apache配置文件,允许访问真实文件(CSS、JavaScript、图片等),并将所有其他请求重定向到index.php

主题设置

以下步骤展示了如何设置ERP主题,即一个涉及数据库模型和相关CRUD UI的主题,因为后端主题的主要部分应该是这样的;也可以在后台使用其他类型的主题(例如仪表板),在这种情况下请参阅下文的客户端解释

  • 设置主题 数据库架构:除了主表外,为了处理国际化文件上传,Simplex依赖于两个辅助表,以下是可能的主题架构的完整概述
    • 存放与语言无关的数据,至少包含主键;它应该以模型键命名,通常为蛇形小写,即使可以是任何名称,只要它在config/crudl.php中设置即可

    • 国际化:Simplex旨在实现本地化,因此应该为任何语言相关信息创建一个表,命名为main-table-name_locales(带有强制性的_locales后缀),其结构如下(命名约定必须严格遵守,以便Simplex正确处理数据保存)

      • 一个名为this-table-name_id的主键(整数自增)(带有强制性的_id后缀)
      • 一个language_code(字符2)字段,用于存储在config/languages.json中用作键的语言代码(ISO-639-1代码)
      • 一个针对主表主键的外键字段,具有CASCADE删除设置
      • 任何自定义字段(文本或varchar),根据主题需要提供本地化信息
    • 如果主题需要文件上传,则定义一个名为main-table-name_uploads的表(带有强制性的_uploads后缀)

      • 这是表结构
        • 一个主键(整数自增)名为this-table-name_id
        • 一个针对主表主键的外键字段,具有CASCADE删除设置
        • 一个名为upload_key的字段(varchar 64应该足够),用于存储上传记录的类型(用于“uploads”数组中的“field”键的“field”)
        • 一个名为file_name的字段(varchar 256),用于存储上传记录的类型(用于“uploads”数组中的“field”键的“field”)
      • 需要手动将上传信息添加到视图中(见下文)
    • 视图

      • 应创建一个基本视图并将其设置到config/model.php
      • 如果存在上传,视图应通过上传表连接
        • 对于在config/model.php中定义的每个上传字段,将添加一个左连接到上传表的主键和upload_key字段(字段键的值)
        • 使用上传键的名称提取file_name字段的值;如果字段允许多次上传,则分组值,按主键排序(以便可以通过拖动文件在GUI中设置顺序)并用管道连接:,GROUP_CONCAT(DISTINCT join-table.file_name ORDER BY join-table.primary-key SEPARATOR '|') AS upload-key
        • 在UI中允许多次上传的字段上按主键分组
      • 在本地化主题的情况下,必须有一个名为 main-table-name_locales 的本地化视图:它必须通过地区连接主表并公开主键字段,language_code 字段(当然,除了本地化信息之外)
      • 示例
        • 表 "foo" 定义为

            CREATE TABLE `foo` (
                `foo_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
                `non_localized_string` varchar(48) NOT NULL,
                `date` date,
                PRIMARY KEY (`foo_id`)
            )
          
        • 将上传定义到主题 config/model.php

            ...
            'uploads' => [
                'pdf_file' => [
                    'raw' => (object) []
                ],
                'single_image' => [
                    'thumb' => (object) [
                        'handler' => ['\Simplex\Local\SUBJECT\NAMESPACE\Controller','resizeImage'],
                        'parameters' => [100,100]
                    ],
                    'full' => (object) [
                        'handler' => ['\Simplex\Local\SUBJECT\NAMESPACE\Controller','resizeImage'],
                        'parameters' => [800,600]
                    ]
                ],
                'multiple_image' => [
                    'thumb' => (object) [
                        'handler' => ['\Simplex\Local\SUBJECT\NAMESPACE\Controller','resizeImage'],
                        'parameters' => [100,100]
                    ],
                    'full' => (object) [
                        'handler' => ['\Simplex\Local\SUBJECT\NAMESPACE\Controller','resizeImage'],
                        'parameters' => [800,600]
                    ]
                ]
            ],
            ...
          
        • 上传表

            CREATE TABLE `foo_uploads` (
            `foo_uploads_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `foo_id` int(10) unsigned NOT NULL,
            `upload_key` varchar(64) NOT NULL,
            `file_name` varchar(256) NOT NULL,
            PRIMARY KEY (`foo_uploads_id`),
            KEY `foo_id` (`foo_id`),
            CONSTRAINT `foo_uploads_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`foo_id`) ON DELETE CASCADE
            ) 
          
        • 基本视图

            CREATE VIEW v_foo AS SELECT
            f.*
            ,fusi.file_name AS single_image
            ,GROUP_CONCAT(DISTINCT fumi.file_name ORDER BY fumi.foo_uploads_id SEPARATOR '|') AS multiple_image
            FROM foo AS f
            LEFT JOIN foo_uploads AS fusi
            ON f.foo_id = fusi.foo_id
            AND fusi.upload_key = 'single_image'
            LEFT JOIN foo_uploads AS fumi
            ON f.foo_id = fumi.foo_id
            AND fumi.upload_key = 'multiple_image'
            GROUP BY f.foo_id
          
        • 国际化表

            CREATE TABLE `foo_locales` (
            `foo_locales_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `language_code` char(2) NOT NULL,
            `foo_id` int(10) unsigned NOT NULL,
            `title` varchar(256) NOT NULL,
            `content` text NOT NULL,
            PRIMARY KEY (`foo_locales_id`),
            KEY `foo_id` (`foo_id`),
            CONSTRAINT `foo_locales_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`foo_id`) ON DELETE CASCADE
            )
          
        • 国际化视图

            CREATE VIEW v_foo_locales AS SELECT
            f.*
            ,fl.language_code
            ,fl.title
            ,fl.content
            FROM v_foo AS f
            LEFT JOIN foo_locales AS fl
            ON f.foo_id = fl.foo_id
          
    • Simplex 随附一个方便的 private/local/simplex/docs/views.sql 文本文件,其中可以编写视图定义;通常数据库管理器 SQL 编辑器不太方便,将视图定义存储在纯 SQL/文本文件中,通过具有语法高亮和复制粘贴到 db 应用程序的编辑器进行编辑可以是一个解决方案,同时也提供了备份

  • 每个主题文件都包含在一个以主题命名的文件夹中
  • 考虑主题在应用程序架构中的位置
    • 它可以在应用程序范围内使用,因此其文件夹应位于 private/local/simplex
    • 它只能在特定区域内部使用,因此它应位于 private/local/simplex/area-name
    • 它可以与其他主题共享一些业务逻辑,因此它应位于 private/local/simplex/[area-name]/subjects-group-name;如果应用程序使用多个主题,我通常会尝试将它们分组
  • 使用 private/local/simplex/SubjectGroup/Subject 文件夹作为草案,复制它们并自定义文件;或者更好的方法是使用已配置的主题文件夹并仅编辑以下以 粗体斜体 格式化的文件。在主题文件夹中工作
    • config/variables.php:设置主题命名空间和 slug 形式,命名空间必须反映主题文件夹的位置(例如,Simplex\Local\Backend\Subject-Group-Name\Subject-Name
    • config/model.php:设置主题模型定义
    • config/routes.draft.php 重命名为 config/routes.php,默认配置的动态路由应至少覆盖基本 CRUD 操作(列表、插入表单、插入操作、更新表单、更新操作、删除表单、删除操作)
    • config/di-container.draft.php 重命名为 config/di-container.php
    • 编辑 Controller.phpModel.php 并将命名空间更改为与 config/routes.variables.php 中使用的值相同
    • 编辑 config/crudl.php 并进行设置
      • 表本地化(本地化属性,布尔值),模型表是否使用辅助表进行本地化(参见上面的 "设置数据库架构")
      • 要用于检索通过保存表单传递的字段值的表字段筛选器
    • config/navigation.php 包含用于显示基本 CRUD 操作的 UI 导航规则,它可以自定义以删除其中的一些或添加更多操作,有关权限逻辑,请参见下面的 主题权限
  • templates/labels.twig 中设置主题 template labels,至少需要一个主题标签,但字段标签用于列表和保存表单模板
  • 编辑 templates/list.twig 以设置记录表中显示的字段,有一个表头块用于标题和一个记录循环用于表单元格中的字段值
  • 编辑 templates/crudl-form.twig 以设置插入/更新和删除表中显示的字段;可以将任何有效 HTML 插入到 modelInputs 块中,但 /private/share/packagist/vukbgit/simplex/src/templates/form/macros.twig 中定义了一组有用的 Twig 宏,默认情况下已包含在内;使用以 'group' 结尾的宏可以构建一个包含标签的完整 Bootstrap 字段表单
  • private/local/simplex/Backend/config/permissions-roles.php 中设置主题 subject permission:默认情况下,在 private/local/simplex/Backend/config/navigation.php 中,用户必须具有 manage-SUBJECT-KEY 权限才能使用全局(列表和插入)和记录操作(更新和删除),因此必须添加 manage-SUBJECT-KEY 权限,并将用户角色包含在权限允许的角色数组中
  • 将主题包含到区域导航中 private/local/simplex/Backend/config/navigation.php
  • private/local/simplex/Backend/templates/backend.twig 中设置主题 navigation label,在 areaNavigationLabels 哈希中
  • 执行注销/登录以重新加载权限

调试

  • PHP层:Simplex在开发环境中使用Whoops来打印异常,并使用Kint来转储变量;特别是Kint有两个函数可用
    • 'x($var)': 将变量转储到HTML输出
    • 'xx($var)': 转储变量并立即退出脚本
  • Twig模板:dump函数可以作为Kint转储函数的包装器使用,即'{{ dump(my-variable-of-any-type) }}'

国际化

  • PHP/Twig模板:
    • Simplex使用gettext,并附带一组英文和意大利文翻译,用于提供的UI中的消息

    • 翻译可以插入到

      • PHP文件中,使用gettext()函数或_()别名(参见PHP gettext文档
      • Twig模板中,使用默认包含的i18n扩展中的trans块和过滤器(参见文档
    • private/share/packagist/vukbgit/simplex/bin/translations.php脚本可以用于提取翻译

    • 存储翻译文件的文件夹由TRANSLATIONS_DIR常量指定,默认为private/local/simplex/locales

    • 这是翻译工作流程

      • 安装后,Simplex核心消息的英文和意大利文翻译存储在TRANSLATIONS_DIR

      • 从模板提取翻译依赖于Twig模板缓存;如果您的本地模板使用任何用户定义的Twig过滤器或函数,模板缓存构建将损坏,因此您需要

        • 将Twig过滤器/函数定义放入您的一些本地类的一个公共方法中
        • private/local/simplex下创建一个或多个名为templates-helpers.php的文件:如果此文件存在,则翻译脚本会自动包含它(有一个草稿文件private/local/simplex/bin/templates-helpers.draft.php
        • templates-helpers.php文件中调用所有模板助手构建方法
      • 当添加本地翻译时运行脚本以更新本地消息,.po和.mo文件将保存到TRANSLATIONS_DIR,针对private/local/simplex/config/languages.json中定义的每种语言

          php private/share/packagist/vukbgit/simplex/bin/translations.php update local
        
      • 下载.po文件,使用Poedit或其他类似软件进行翻译

      • 将生成的.po和.mo文件上传回TRANSLATIONS_DIR

    • 如果网站使用的PHP版本与系统版本不同,则必须指定PHP二进制的完整路径,即

        /opt/php-7.3.5/bin/php private/share/packagist/vukbgit/simplex/bin/translations.php update local
      
    • 在安装时,也会在根目录创建一个名为translations.sh的脚本,可用于简化翻译过程,从根目录以这种方式调用它

            ./translations.sh update local
      
  • 数据库:即使网站只使用一种语言,Simplex也鼓励本地化的数据库架构(参见主题设置 > 数据库架构

电子邮件

Simplex使用mjml,通过mjml-php集成到Twig模板中,来构建响应式电子邮件。提供了一个起始模板在private/local/simplex/templates/emails/base.twig

图标字体

Simplex使用Fontello来处理图标,并将图标分解成逻辑组,每个组都有自己的Fontello文件夹,目前有

  • public/share/simplex/form/Fontello用于表单相关的图标(100个预留的Unicode值,从0100到0164)
  • public/share/simplex/Erp/Fontello用于ERP(后端)相关的图标(100个预留的Unicode值,从0165到01C9)
  • public/share/brands/Fontello用于品牌相关的图标,例如社交媒体或文件类型(20个预留的Unicode值,从01CA到01DE)

Unicode编码被分配,以便在使用CSS中的图标时(将CSS属性content设置为Unicode码,将font-family设置为"fontello"),图标不会重叠。如果添加了其他特定于应用程序的图标,它们应从02BC(包含)开始的Unicode码中获取。注意:当在CSS中使用Unicode码时,请记住检查text-transform(小写或大写),因为每个图标对应一个具有特定大小写的Unicode字符,如果元素从上下文中继承大小写,则可能显示错误的符号。

开发到生产

如果您保留独立的开发环境和生产环境,并通过git仓库管理发布,您可以在安装时将一些bash脚本软链接到Web根目录。

  • 开发环境
    • git-setup-dev.sh:交互式脚本,询问仓库URL、git用户电子邮件和git用户名,设置仓库,执行第一个有意义的提交并将其推送到仓库。
    • git-push-all.sh:推送自上次提交以来的所有更改,它添加根文件夹和子文件夹中的所有内容,因此任何要排除在提交之外的文件夹/文件必须添加到.gitignore;如果您需要仅推送一些更改,您必须手动添加、提交和推送。
  • 生产环境
    • 从开发环境复制composer.json文件。
    • 运行composer create-project
    • 运行git-setup-prod.sh,交互式脚本,询问仓库URL并设置仓库以进行拉取。
    • 运行update-all.sh,它
      • 清理DI容器和模板缓存,注意tmp文件夹路径,(请参阅安装后工作 > bash脚本设置

      • 更新Composer包。
      • 通过npm更新NPM包。

Simplex逻辑概述

逻辑结构

  • Simplex\ControllerAbstract:不显示页面的路由的基本控制器
    • 具有DI容器和响应对象作为注入的依赖项。
    • 路由必须传递'动作'(以slug形式)和'区域'参数。
    • 存储请求及其参数。
    • 设置语言。
    • 执行动作参数slug的PSR1翻译命名的函数。
  • Simplex\ControllerWithTemplateAbstract:显示页面的路由控制器
    • 扩展Simplex\ControllerAbstract,因此继承了其属性和功能以及以下内容
    • 具有模板引擎和cookies管理器作为注入的依赖项。
    • 构建一些模板辅助函数。
    • 将一些常量和变量作为参数传递到模板中。
  • Simplex\Erp\ControllerAbstract:应用程序ERP区域中的路由控制器
    • 扩展Simplex\ControllerWithTemplateAbstract,因此继承了其属性和功能以及以下内容
    • 识别当前主题(请参阅上面的“术语”)。
      • 与主题相关的所有文件必须位于同一文件夹中,在_Simplex\Local_命名空间内。
      • 主题名称是文件所在的文件夹名称(即主题文件命名空间最后一部分的名称),从PSR1格式转换为slug(每个大写字母前面加连字符并转换为小写,即'NewsCategories' > 'news-categories')。
      • $this->subject下存储主题。
    • 实例化并注入必需的模型
      • 必须定义在主题命名空间中的类
        • 命名为'Model'。
        • 必须扩展Simplex\Model\ModelAbstract。
        • 必须有一个在subject-namespace\config\model.php下的配置文件。
      • $this->model下存储模型。
    • 加载CRUDL配置,这是ERP必需的,包含CRUDL接口要公开的信息(例如,每个模型字段要使用的输入过滤器)并且必须保存在subject-namespace\config\crudl.php中。
    • 从cookies中获取主题的用户选项(选项从UI中设置到cookie)并将它们存储在$this->userOptions中。
    • 加载导航。
      • 从文件area-namespace\config\navigation.php中加载区域导航(侧边栏菜单)。
      • 从文件 subject-namespace\config\navigation.php 加载主题导航(全局操作选项卡、表记录操作链接)
      • 将导航中的每个路由与当前URL进行比较,以检查它是否是当前选中的路由
    • 构建一些ERP特定的模板辅助工具
    • 将一些ERP特定的常量和变量作为参数传递给模板

应用程序流程

  • .htaccess
    • 根据域名设置PHP环境变量以确定当前环境
    • 拦截每个请求并将其重定向到 index.php
  • index.php:
    • 需要Composer自动加载
    • 在安装过程中,在文件夹 private/local/simplex 中搜索名为 constants.php 的文件,创建 private/local/simplex/config/constants.php(请参阅文件以获取详细信息)
    • 根据环境设置 错误处理器
    • private/share/packagist/vukbgit/simplex/config/di-container.php 加载定义实例化一个 依赖注入容器(请参阅文件以获取详细信息)
    • DI容器 实例化 分发器(分发器是 请求处理器 的另一个名称)
    • 分发器从 MIDDLEWARE_QUEUE_PATH 常量值(默认为 private/share/packagist/vukbgit/simplex/config/middleware.php)加载 中间件队列,Simplex默认队列由以下组成
      • 路由器 加载存储在 private/local/simplex 文件夹下(甚至在子目录中)的任何名为 "routes.php" 的文件的路线定义;路线定义必须包含一个 "action" 参数(private/local/simplex/config/route.php 包含关于路线定义的更多详细信息)
      • Simplex的 身份验证 中间件
        • 如果当前路线定义中找到 "authentication" 参数,则条件性触发
        • 如果触发,则检查用户是否已当前认证,否则重定向到配置的URL
      • 请求处理器(不,不是上面的 分发器,这个话题上有些命名混淆...),它负责处理当前路由,调用在路线定义中指定的本地类 Route Handler
      • Route Handler
        • 将所有请求参数和响应对象存储在类属性中
        • 调用一个以 "action" 路由参数命名的函数
        • 此方法执行操作所需的所有任务,并且通常将HTML代码注入到响应中
      • 分发器 将响应返回到 index.php 范围
    • 检查响应的HTTP状态码,如果与200(表示“一切顺利”)不同,则从 private/share/packagist/vukbgit/simplex/src/errors/ 文件获取适当的HTML代码并将其注入到响应中
    • 实例化 Emitter 并将响应返回到浏览器

文件夹和文件结构

Simplex扩展了类命名空间逻辑到应用程序中的每个文件;本地命名空间private/local/simplex/config/constants.php 中定义的文件夹 LOCAL_DIR 常量开始(默认为 private/local/simplex)并默认命名为 Simplex\Local

在这个文件夹中,类按照典型的应用程序业务域逻辑排列(例如,News 文件夹包含所有与新闻相关的类,Customer 文件夹等)。但其他具有不同目的的文件(配置文件、HTML模板、SASS文件等)也应遵循此逻辑;因此,首先不是按功能分组(顶层 config 文件夹,顶层 views 文件夹等),而是首先按命名空间/业务逻辑分组(因此 /News/configNews/templates 文件夹)。

这是因为典型应用程序开发是按业务逻辑进行的:添加新闻功能意味着至少添加一个新闻类,一些新闻配置(路线和DI容器定义)和一些新闻视图(后端和前端的后端HTML模板);如果所有这些文件都在本地文件夹的子文件夹中分散,我发现这更难开发、维护和“克隆”功能用作新功能的草稿

以下是从Simplex安装的文件夹和文件,来自安装根目录

  • private:所有不能直接通过浏览器访问的文件
    • local:为应用程序开发的文件
      • simplex:应用程序文件的顶级命名空间文件夹,其中定义的每个类都具有基本命名空间 Simplex\Local
        • Backend:后端命名空间草案文件夹
        • Frontend:前端命名空间草案文件夹
        • bin:在安装时创建,用于有用的bash脚本
          • composer.sh:允许使用与PHP CLI应用程序使用的系统默认版本不同的PHP版本使用composer;在安装了多个PHP版本的系统上非常有用;将其软链接到根目录是一个好主意
        • config:整个应用程序的配置文件,可进行自定义
          • constants.php:环境常量,相当直观,其中一些应该在安装后立即设置;注意:关于Simplex使用的所有路径,通常不需要更改;如果需要,请注意,在包含此文件之前,有一对路径是硬编码在 index.php 中的,并且需要手动更改
          • db.php:数据库配置,返回PHP对象,从 config.ini 获取配置
          • di-container.php:DI容器使用的定义,用于实例化应用程序使用的类;它集成了 private/local/share/vukbgit/simplex/src/config/di-container.php/,该文件存储Simplex引擎使用的类的定义
          • languages.json:应用程序使用的语言,按自定义键索引(建议使用ISO-639-1两位字母代码);如果路由传递“语言”参数,则搜索语言,否则使用第一个定义的语言(默认为英语)
          • sass.config:用于通过 sass.sh 脚本加快Sass文件编译的自定义格式文件:您可以为要编译的每个文件定义一个自定义ID(任何字符串)和源路径和目标路径,因此您可以在根目录下使用shell并调用 sass file-id 来编译最小化版本的CSS
        • sass:一些空的scss草案,用于编译Bootstrap和一些应用程序CSS
          • application.scss:整个应用程序的规则
          • bootstrap-variables.scss:在包含Bootstrap附带 variables.scss 文件之前包含,用于覆盖Bootstrap内置变量
          • bootstrap.scss:编译Bootstrap CSS的主要文件,仅包含最常用的组件,取消注释行以包含其他功能; private/local/simplex/config/sass.config 已包含通过根 sass.sh 文件编译此文件的配置,只需在shell中执行 './sass.sh bs' 即可
          • functions.scss:一些有用Sass函数的定义
          • variables.scss:Sass变量,供应用程序使用
        • templates:一些可使用和自定义的Twig模板
    • share:通过Composer安装的文件以及可能来自其他来源的其他第三方库
      • packagist:通过 Packagist 安装的库
        • vukbgit
          • simplex:由应用程序使用的共享Simplex模块,对不太明显的模块有一些解释
            • bin:bash脚本,其中一些在安装时创建composer项目创建时间软链接到根目录
            • installation:在安装时复制以备使用和/或自定义的文件夹和文件
            • src:Simplex在运行时使用的类和其他文件
              • config:配置文件
                • di-container.php:DI容器使用的定义,用于实例化Simplex引擎使用的类;它由位于 private/local/simplex 文件夹下任何具有相同名称的文件集成
                • middleware.php:由分发器处理的中间件队列,可以覆盖将 MIDDLEWARE_QUEUE_PATH 值设置为 private\local\simplex\config\constants.php
              • 错误:在请求引发HTTP错误时显示的HTML文件
              • 模板:适用于具有CRUDL功能的后端区域的现成Twig模板
        • 应用程序使用的所有其他Composer库
  • 公共:所有可以被浏览器访问的文件
    • 本地:为应用程序开发的文件,如编译后的CSS文件和JavaScript文件
    • 共享:从npm安装的库以及任何其他第三方前端JavaScript和CSS资源
      • package.json:npm配置文件,需要最新版本的Bootstrap和jQuery以及其他有用的库,根据需要自定义
    • .htaccess:重定向以"public/"开头的所有请求到index.php,除了真正存在于文件系统中的文件(CSS、JS等)
  • .gitignore:在开发/生产流程中,我将文件从开发站点提交到私有仓库,并将它们拉入生产站点;此.gitignore文件排除了一些Simplex文件夹/文件从提交
  • .htaccess:根Apache指令
    • 重定向根目录的所有请求到public/index.php
  • composer.json:
    • 将供应商目录设置为private/share/packagist
    • 将bin目录设置为./,以便在根目录中创建一些shell脚本的符号链接
    • 将自动加载应用程序目录设置为private/local/simplex,将此路径映射到Simplex\Local命名空间
    • 需要Simplex包(负责要求其他所需的包)
  • index.php:应用程序引导文件,因为它存储在站点根目录中,所以每个文件中的所有PHP包含都使用从站点根目录的绝对路径,有关详细信息,请参阅上面的“应用程序流程”
  • sass.sh:指向辅助脚本private/share/packagist/vukbgit/simplex/bin/sass.sh的软链接,用于编译Sass文件,有关详细信息,请参阅上面的private/local/simplex/config/sass.config解释
  • npm.sh:指向辅助脚本public/share/npm.sh的软链接,用于管理public/share文件夹中的npm包,通过./npm.sh npm-command调用它,例如./npm.sh install foolibrary以在local/share/node_modules/foolibrary中执行安装

从v2迁移到v3

  • index.php:Zend -> Laminas
  • FILTER_SANITIZE_STRING -> FILTER_SANITIZE_SPECIAL_CHARS
  • grep -rl FILTER_SANITIZE_STRING private/local/simplex | xargs sed -i 's/FILTER_SANITIZE_STRING/FILTER_SANITIZE_SPECIAL_CHARS/'
  • ERP
    • list:{% block rows %} {% for record in records %} {{ tableMacros.displayRowBegin(_context, loop, record) }} {{ record.FIELD }} {{ tableMacros.displayRowEnd(_context, loop, record) }} {% endfor %}{% endblock %}
    • crudl-form
      • 用于日期范围的dateTimePickers现在统一
    • css
      • ERP样式不再直接包含,而是集成到区域(例如后端)的scss文件中
        • 创建区域scc文件(从安装文件夹复制),例如private/local/simplex/Backend/sass/backend.css
        • 编译它,例如./sass.sh be
        • 将其包含在区域模板中,例如private/local/simplex/Backend/templates/backend.twig
  • 表单
    • 移除了所有captcha依赖和功能,实现honey trap技术
    • 更新(从安装文件夹复制)语言中的日历日期格式到private/local/simplex/config/languages.json
  • _TWIG
    • 将if条件从for循环中移除,用于搜索的正则表达式:grep -rE "{%\s+for\s+[a-zA-Z ,]+\s+in\s+[a-zA-Z\.]+\s+if" private/local
  • SASS
    • 将算术运算包含在calc()函数中
  • BOOTSTRAP 5
    • .ml-* 和 .mr-* -> .ms-* 和 .me-*.
    • .sr-only -> .visually-hidden
    • 表单网格:form-row -> row
    • .form-inline: 使用网格行 > col / col-md-auto
    • 所有af data-*属性在collapse(例如菜单选项)、carousel等中变为data-bs-*
    • 文本对齐:-left -> -start; right->end
    • 删除input-group-append / prepend
    • 关闭按钮(模态框、警告...)
      • 类名 close -> btn-close
      • data-dismiss -> data-bs-dismiss
      • 移除内部 span
  • 电子表格阅读器/编写器:阅读器已移至 phpoffice/phpspreadsheet 应该没问题,但编写器实现目前仍然存在问题!

注意事项

  • 我选择不使用任何框架,因为我想要完全控制应用内部的流程
  • Simplex 几乎使用第三方类来完成每个专业任务(依赖注入容器、路由、调度、事件发射...)
  • 只有在我找不到外部库来完成一些任务时,我才会将一些组件编码到 Simplex 中:例如,我编写了 nikic/fastroute 中间件,以便能够传递自定义路由参数
  • 设计选择:我试图查找文档,主要寻找“无需框架”的建议(见下文参考),并查看现有的框架(尽管我并非此领域的专家,因为我在2000年开始为重用结构代码);我希望 Simplex 保持最新,同时也要简单易用。对于每个话题,都没有达成一致,例如 依赖注入容器的使用。因此,我做出了自己的(非常可疑的)选择,始终牢记我需要的是一个工具,以最快的速度和最灵活的方式构建Web应用
  • 结果我最终创建了自己的框架!老实说,我不知道

API文档

使用 phpDocumentor 生成的API文档可以在 [https://vukbgit.github.io/simplex] 找到

参考