bbn/bbn

PHP意见性框架

This package is auto-updated.

Last update: 2024-09-25 00:48:28 UTC


README

BBN PHP

bbn

app-UI使用的PHP库

您可以通过Composer安装此库

{
  "require": {
    "bbn/bbn": "dev/master"
  }
}

针对单页应用的库,包括

  • MVC框架
  • 强大的ORM,支持数据库结构分析和多种返回方法
  • 基于此的选项类,大多数app-UI功能都基于此
  • 用于集成外部服务的API类(Virtualmin、Cloudmin、Github、Gitlab、支付...)
  • 一个历史类,允许存储数据库中的每个更改并撤销它们
  • 文件、图像和PDF文件操作类
  • 文件系统探索器
  • 自动任务管理系统
  • 通用缓存系统
  • HTML生成类
  • 用户和组管理类
  • PHP、Javascript和VueJS组件的解析器
  • 针对app-UI功能的特定类,例如
    • 笔记
    • 媒体
    • 聊天
    • 剪贴板
    • 内容管理系统
    • 仪表板
    • 数据库管理系统
    • 数据库同步系统
    • I.D.E.
    • 自动邮件发送
    • 国际化
    • 信件和文本的掩码系统
    • 通知系统
    • 数据观察者
    • 密码管理
    • 计划和事件管理
    • 项目管理系统
    • 统计系统
    • 通用项目和工作流管理系统
    • 用于操作所有类型数据和其他有用功能的静态方法
  • 还有很多其他功能!

bbn框架与路由器和一些配置文件一起工作。预计将在2022年发布安装程序

代码审查、翻译和文档方面还有大量工作要做。

欢迎任何帮助!

典型安装结构

  • app-ui/
    • data/
    • src/
      • cfg/
        • environments.yml
        • settings.yml
        • custom2.php
      • cli/
      • components/
      • lib/
      • locale/
      • mvc/
        • css/
        • html/
        • js/
        • model/
        • private/
        • public/
      • plugins/
    • router.php
  • public_html/
    • .htaccess
    • index.php

默认情况下,如果存在POST,BBN框架返回HTML文档,否则返回JSON对象。

bbn-jsbbn-vue库与此框架密切相关,并处理其I/O。

它们捕获每个本地链接的点击,将其作为POST请求发送,然后处理响应。

点击链接返回的JSON对象通常包含以下属性

典型请求的生命周期

重定向

➡️ 调用https://myapp.com/just/testing(该页面不存在)
➡️ .htaccess文件将所有未找到的文件重写为index.php文件
➡️ 索引文件在app文件夹src/chdir,该文件夹应位于公共根目录之外
➡️ 然后包括路由器,该路由器应在src/目录中(作为指向vendor的符号链接)

路由

➡️ 通过 hostnameapp_path 定义从 src/cfg/environment.yml 中识别它所处的预定义配置
➡️ 定义常量并初始化自动加载
➡️ 根据配置实例化不同的类
➡️ 创建 MVC 类,该类将寻找正确的控制器

  • 它在 src/mvc/public/ 中查找对应于路径 just/testing 的控制器
    • 如果是落地页(无 POST),则文件应为:src/mvc/public/just/testing/index.php
    • 否则文件应为:src/mvc/public/just/testing.php
  • 当找不到文件时,它会逐级回退到目录中
    • 如果是落地页(无 POST),它会查找:src/mvc/public/just/index.php,最后查找:src/mvc/public/index.php
    • 否则它查找:src/mvc/public/just.php,如果找不到,则返回 404

执行

➡️ 可选的文件 src/custom1.php 被包含,其中对象 $bbn 可通过属性 mvc 访问
➡️ 如果不在 CLI 模式下,则启动会话
➡️ 仍不在 CLI 模式下,可选的文件 src/custom2.php 被包含,其中对象 $bbn 可通过属性 mvcusersession 访问,具体取决于配置
➡️ MVC 包含控制器

输出

➡️ 输出缓冲区成为响应对象的 content 属性
➡️ 可选的文件 src/custom3.php 被包含,其中对象 $bbn 可通过新属性 obj 访问,该属性将是输出
➡️ 如果是落地页(无 POST),则返回带有 HTML 头部的 content 属性
➡️ 否则,将返回经过 JSON 头部编码的 mvc->obj 对象
➡️ 如果在 obj 中没有 content 但有 fileimage,则相应地处理响应,并使用相应的头文件

一些示例

ORM

<?php
use bbn\X;

/** @var bbn\Db $db */

// Returns an array with fields, cols and keys props which will give you all information about a table
X::adump($db->modelize("my_table"));
// Simple query
X::adump($db->getRows("SELECT * FROM my_table WHERE status = ?", $var));
// Same query
X::adump($db->select(
  "my_table", // table
  [], // all columns
  ["status" => $var] // WHERE
));

// More arguments
X::adump($db->rselectAll(
  "my_table", // table
  ["field1", "field2"], // columns
  [["id", "<", 25], ["name", "LIKE", "tri%"]], // WHERE
  ["date" => DESC, "name"], // ORDER
  50, // LIMIT
  20 // START
));

// The full way 
X::adump($db->rselectAll([
  'tables'  => ["my_table_name", "my_table_name2"],
  'fields'  => ["field1", "field2"], // all columns
  'where'   => [
    'logic'      => 'OR',
    'conditions' => [
      'user'       => 'admin',
      'conditions' => [
        'logic'      => 'AND',
        'conditions' => [ // Mixed mode allowed in filters
          [
            'field'    => 'my_date',
            'operator' => '<',
            'exp'      => 'NOW()'
          ],
          ["id", "<", 25]
          'name' => 'tri%'
        ],
      ]
    ]
  ],
  'join'    => [
    [
      'table' => 'my_table3',
      'on' => [
        [
          'field' => 'my_table3.uid',
          'exp'   => 'my_table.uid_table3' // Operator is = by default
        ]
      ]
    ]
  ],
  'order'    => ["date" => DESC, "name"], // ORDER
  'group_by' => ['my_table.id'],
  'limit'    => 50,
  'start'    => 20
]));

MVC

use bbn\X;
/** @var bbn\Mvc\Controller $ctrl */

// the/path/to/the/controller
X::adump($ctrl->getPath()); 

// The corresponding (= same path) model
X::adump($ctrl->getModel()); 

// Another model to which we send data
X::adump($ctrl->getModel('another/model', ['some' => 'data']));

X::adump(
  // HTML view with same path (in html)
  $ctrl->getView(), 
  // with data sent to js
  $ctrl->getView('another/view', 'js', ['my_data' => 'my_value']), 
  // encapsulated in a script tag
  $ctrl->getJs('another/view', ['my_data' => 'my_value']), 
  // compiles and returns the Less code from the same path (in css)
  $ctrl->getLess(), 
  // The post data
  $ctrl->post,
  // The get data 
  $ctrl->get, 
  // The files array (revisited)
  $ctrl->files, 
  // an array of each bit of the path which are not part of (=after) the controller 
  $ctrl->arguments,
  // an associative array that will be sent to the model if nothiung else is sent
  $ctrl->data, 
  // Adds properties to $ctrl->data
  $ctrl->addData(['my' => 'var']) 
  // Moves the request to another controller
  $ctrl->reroute('another/route') 
  // Includes another controller
  $ctrl->add('another/controller', ['some' => 'data']), 
  // Includes a private controller (unaccessible through URL)
  $ctrl->add('another/controller', [], true),
  // timer will be a property of the $ctrl->inc property, also available in the subsequent models
  $ctrl->addInc('timer', new bbn\Util\Timer()) 
);

// The most useful functions:

// Fetches for everything related to the current controller (model, html, js, css) and combines the results into a single object ($ctrl->obj). That's the typical function for showing a page
$ctrl->combo("My page title");

// Transform all input (get, post, files) data into a single data array
// Fetches the corresponding model with this data
// and returns its result as an object.
// Typically used for write operations.
$ctrl->action();

// The second parameter allows the javascript to access the model's data
$ctrl->combo("My page title", true);

// Here the second parameter is the data sent to javascript
$ctrl->combo("My page title", ['my' => 'data']);

?>

通过 JavaScript 访问数据

如果匿名函数返回一个 函数,则数据将是它的 第二个参数
(() => {
  return (container, data) => {
    if (data && data.success && data.color) {
      container.style.color = '#' + data.color;
    }
  };
})();
如果匿名函数返回一个 对象,则数据将位于 source 属性
(() => {
  return {
    computed: {
      realColor() {
        return '#' + this.source.color
      }
    }
  };
})();

HTML 视图是服务器端渲染的,因此默认情况下可以访问所有数据

HTML 视图示例
<div style="color: #{{color}}">Hello world</div>
PHP 视图示例
<div style="color: #<?= $color ?>"><?= _("Hello world") ?></div>

选项

选项系统内置在一个数据库中,有一个具有以下结构的表

code 系统允许我们通过代码路径找到选项。
例如,代码序列 permissionsideappui 目标

  • 在具有代码 appui 且父级为 root 的选项中
  • 在具有代码 ide 的选项中
  • 具有代码 permissions 的选项

顺序被反转,从最精确到最一般,而实际上序列是
root ➡️ appui ➡️ ide ➡️ permissions

use bbn\X;
/** @var bbn\Appui\Option $option */


// Returns the option ID from its code sequence
X::adump($option->fromCode('permissions', 'ide', 'appui')); 
// The whole option with the same arguments (which work for all fetching functions)
X::adump($option->option('permissions', 'ide', 'appui')); 

// It works also with the ID:
$id_option = $option->fromCode('permissions', 'ide', 'appui');
X::adump($option->option($id_option));
// ID is a 32 hex value, so a code shouldn't look like one
// If the last parameter is an ID, it will take this ID as the root
X::adump($option->option('test', 'page', $id_option));
// Is the same as
X::adump($option->option('test', 'page', 'permissions', 'ide', 'appui'));

// Then you can fetch options (i.e. the children of an option) in many different ways
X::adump(
  // Only the IDs, in the right order if orderable
  $option->items($id_option),
  // Only the IDs, text, and code if applicable
  $option->options($id_option),
  // All the option properties (but cfg)
  $option->fullOptions($id_option),
  // Same as options but with an items property holding the lineage
  $option->tree($id_option),
  // Same as fullOptions but with an items property holding the lineage
  $option->fullTree($id_option),
  // Returns the code: permissions
  $option->code($id_option),
  // Returns the text
  $option->text($id_option),
  // You can insert whaever you like
  $option->add(['id_parent' => $id_option, 'text' => 'Hello', 'myProp' => 'myValue'])
);