activecollab/retro 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

activecollab/retro

Composer 安装命令:

composer require activecollab/retro

包简介

Library that ties together different bits needed to write a web app

README 文档

README

Retro is a library that ties together different components that are needed to build web apps that use backend to generate all the content. It is named Retro because it lets us build apps like we did in early 2000s, but with far superior development experience. Wait, what? What was good about web application development back in early 2000s? Several things:

  1. You create a file, and web server picks it up, no route to manually define.
  2. Things make sense even without JavaScript, but JavaScript makes them so much better through progressive enhancement.
  3. Database is the state, and HTML that server returns is rendered representation of that state at the moment.
  4. No JSON between frontend and backend, web servers serve HTML, and browsers render it.
  5. API as RPC, instead of every page begin an API endpoint.

Building blocks of Retro:

  1. Sitemap enables file system based routing, provided by Sitemap package,
  2. Form processing using a simple mechanism to capture data from forms, validate it, and re-render the form with errors when needed.
  3. Controllers don't do any processing, they just route the data to appropriate services, and return the result of their execution.
  4. Services can optionally be exposed and used as JSON-RPC endpoints with minimal effort.

To be continued…

Project Structure

  • /app/current/src - where application is being built
  • /cache
  • /config
  • /logs
  • /public/assets
  • /public/index.php
  • /test/unit/log
  • /test/unit/src
  • /test/unit/boostrap.php
  • /upload
  • .gitignore
  • .php_cs.php
  • .php_qc.php
  • composer.json
  • composer.lock
  • phpunit.xml
  • README.md
  • VERSION

CRUD

To easily generate boilerplate code for entities, run following command in this sequence:

php app/current/bin/console.php retro:create_crud_service plural_entity_name BundleName

This command creates add, edit and delete services, as well as supporting result classes that can be recorded in service execution history.

php app/current/bin/console.php retro:create_crud_form plural_entity_name BundleName

This is not a requirement step, but it follows the naming convention that create_crud_controller command will pick up and use automatically.

php app/current/bin/console.php retro:create_crud_controller plural_entity_name BundleName

This command creates a set of controllers, one for working with collections of entities, and one for working with individual entities.

Service Transactions

Services provide a simple structure to run all execution code within a transaction, and return service result:

use ActiveCollab\Retro\Service\Service;
use ActiveCollab\Retro\Service\Result\ServiceResultInterface;
use ActiveCollab\Retro\Service\Result\Success\Success;

class MyService extends Service
{
    public function serviceMethod(): ServiceResultInterface
    {
        return $this->withinTransaction(
            function () {
                return new Success();
            },
            null,
        )
    }
}

withinService() method will commit the transaction on successful result, and roll it back on failure. While time saving for most scenario, this can be a problem if you want to keep something in the database even if the service fails. In that case, you can use:

  1. afterTransaction() - to run code after the transaction,
  2. onTransactionException() - to capture exceptions that are thrown within transaction closure.
use ActiveCollab\Retro\Service\Service;
use ActiveCollab\Retro\Service\Result\RequestProcessingFailed\RequestProcessingFailed;
use ActiveCollab\Retro\Service\Result\ServiceResultInterface;
use ActiveCollab\Retro\Service\Result\Success\Success;
use Exception;

class LoginService extends Service
{
    public function __construct(private UsersRepositoryInterface $usersRepository)
    {
    }

    public function logUserIn(
        string $username, 
        string $password,
    ): ServiceResultInterface
    {
        return $this->withinTransaction(
            function () use ($username, $password) {
            
                // Capture any exceptions that are thrown during transaction execution.
                $this->onTransactionException(
                    function (Exception $e) use ($username) {
                        $this->usersRepository->logFailedLoginAttempt($e->getMessage(), $username);
                    }
                );
            
                if (!$this->usersRepository->validate($username, $password)) {
                
                    // This callback will be executed after the transaction is rolled back, due to failed service result.
                    $this->afterTransaction(
                        function () use ($username) {
                            $this->usersRepository->logFailedLoginAttempt('Invalid credentials', $username);
                        },
                    );
                    
                    return new RequestProcessingFailed(...);
                }
                
                // This call may throw an exception?
                $this->usersRepository->logUserIn($username);
                
                return new Success();
            },
            null,
        )
    }
}

UI

Why would it be desirable to describe UI with PHP? Several reasons:

  1. It's component library agnostic. When composed using basic elements, UI can be rendered using any component library. Shoelace is currently included, but it can be any UI kit that works with web components or plain HTML,
  2. It's decoupled from template engine. Templating engine provides tags and blocks, like {Button}, or {Badge}, to make writing of templates easier. Actual HTML rendering is done by the component library specific renderer, and you can switch to a different component library simply by changing which renderer is being used, without touching the templates,
  3. UI can be prepared in different layers of the application, not just in templates. Instead of having many checks, calculations, and manipulation in templates, you can simply "ask" entities, services, or utilities to provide you UI description that you just render in templates.

activecollab/retro 适用场景与选型建议

activecollab/retro 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 571 次下载、GitHub Stars 达 0, 最近一次更新时间为 2024 年 12 月 25 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 activecollab/retro 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 activecollab/retro 我们能提供哪些服务?
定制开发 / 二次开发

基于 activecollab/retro 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 571
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 25
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-12-25