定制 inklabs/kommerce-core 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

inklabs/kommerce-core

Composer 安装命令:

composer require inklabs/kommerce-core

包简介

Zen Kommerce Core

关键字:

README 文档

README

Test Coverage Build Status Downloads Apache License 2.0

Introduction

Zen Kommerce is a PHP shopping cart system written with SOLID design principles. It is PSR compatible, dependency free, and contains 100% code coverage using TDD practices.

All code (including tests) conform to the PSR-2 coding standards. The namespace and autoloader are using the PSR-4 standard.

Description

This project is over 62,000 lines of code. Unit tests account for 30-40% of that total and execute in under 10 seconds. The repository tests use an in-memory SQLite database.

Design Patterns

Architecture

Flow of Control

  • Action

    • Command and Queries are the Use Cases and main entry-point into the application.

    • Command Actions are dispatched to the CommandBusInterface to be handled.

      $applyToShipping = true;
      $command = new CreateStateTaxRateCommand('CA', 9.5, $applyToShipping);
      $this->dispatch($command);
      • There is no return value from the $this->dispatch(...) method. Only exceptions are thrown if the Command is invalid.
    • Query Actions are dispatched to the QueryBusInterface to be handled. Instead of returning the Product entity, the handler will inject a ProductDTOBuilder object into the Response. The DTO Builder is used to produce a ProductDTO which can be retrieved using the $response->getProductDTO() method.

      $productId = '15dc6044-910c-431a-a578-430759ef5dcf';
      $query = new GetProductQuery($productId);
      
      /** @var GetProductResponse $response */
      $response = $this->dispatchQuery($query);
      
      $productDTO = $response->getProductDTO();
      var_export($productDTO);
        inklabs\kommerce\EntityDTO\ProductDTO::__set_state([
            'slug' => 'test-product',
            'sku' => '5b6541751fd10',
            'name' => 'Test Product',
            'unitPrice' => 1200,
            'quantity' => 10,
            'isInventoryRequired' => false,
            'isPriceVisible' => true,
            'isActive' => true,
            'isVisible' => true,
            'isTaxable' => true,
            'isShippable' => true,
            'isInStock' => true,
            'areAttachmentsEnabled' => false,
            'shippingWeight' => 16,
            'description' => null,
            'rating' => null,
            'tags' => [],
            'images' => [],
            'tagImages' => [],
            'options' => [],
            'textOptions' => [],
            'productQuantityDiscounts' => [],
            'optionProducts' => [],
            'productAttributes' => [],
            'price' => inklabs\kommerce\EntityDTO\PriceDTO::__set_state([
                'origUnitPrice' => 1200,
                'unitPrice' => 1200,
                'origQuantityPrice' => 1200,
                'quantityPrice' => 1200,
                'catalogPromotions' => [],
                'productQuantityDiscounts' => []
            ]),
            'id' => inklabs\kommerce\Lib\UUID::fromString('15dc6044-910c-431a-a578-430759ef5dcf'),
            'created' => DateTime::__set_state([
                'date' => '2018-08-04 06:04:26.000000',
                'timezone_type' => 3,
                'timezone' => 'UTC',
            ]),
            'updated' => null,
            'createdFormatted' => 'August 3, 2018 11:04 pm PDT',
            'updatedFormatted' => null,
        ]);

      HTML Template:

      Product: <?=$productDTO->name?> - <?=$productDTO->sku?>
      Price: <?=$productDTO->price->unitPrice?>
      Tag: <?=$productDTO->tags[0]->name?>
    • Both implementations (CommandBus and QueryBus) defer to the MapperInterface to determine the location of the class to handle the execution.

    • This CQRS strategy allows us to separate Commands from Queries while also keeping the Entity business objects separate from the main application. We prefer not to expose internal classes containing methods with business logic. This also serves to decouple the main application from the Use Cases handler implementation. The main application only needs to know about the Use Case Actions.

  • Domain Event

    • Domain Events can be raised in the Entity layer and are dispatched in the service layer.
    // UserEntity:
    public function setPassword($password)
    {
        $this->passwordHash = // hash the password...
    
        $this->raise(
            new PasswordChangedEvent(
                $this->id,
                $this->email,
                $this->getFullName()
            )
        );
    }
    // UserService:
    $user = $this->userRepository->findOneById($userId);
    $user->setPassword($password);
    $this->userRepository->update($user);
    
    $this->eventDispatcher->dispatch($user->releaseEvents());
    • Events can be dispatched directly in the service layer. (deprecated)
    // CartService:
    $order = Order::fromCart($cart);
    $this->orderRepository->create($order);
    
    $this->eventDispatcher->dispatchEvent(
        new OrderCreatedFromCartEvent($order->getId())
    );
  • Service

    • These are the domain services to manage persisting domain state to the database through repositories. They contain behavior related to multiple Entities and any business logic that does not fit any specific Entity or single Use Case.
  • Entity

    • These are plain old PHP objects. You will not find any ORM code or external dependencies here. This is where the relationships between objects are constructed. An Entity contains business logic and behavior with high cohesion to its own properties. Business logic related to the data of a single instance of an Entity belongs here.

      $tag = new Entity\Tag
      $tag->setName('Test Tag');
      
      $product = new Entity\Product;
      $product->setName('Test Product');
      $product->setUnitPrice(500);
      $product->setQuantity(1);
      $product->setIsInventoryRequired(true);
      $product->addTag($tag);
      
      if ($product->inStock()) {
        // Show add to cart button
      }
  • EntityRepository

    • This module is responsible for storing and retrieving entities. Doctrine 2 is used in this layer to hydrate Entities using the Data Mapper Pattern.

      $productRepository = $this->entityManager->getRepository(Product::class);
      
      $productId = 1;
      $product = $productRepository->findOneById($productId);
      $product->setUnitPrice(600);
      
      $productRepository->persist($product);
  • EntityDTO

    • These classes are simple anemic objects with no business logic. Data is accessible via public class member variables. Using the EntityDTOBuilder, the complete network graph relationships are available (e.g., withAllData()) prior to calling build(). The primary reason for using these Data Transfer Objects (DTO) is to flatten the object graph from lazy loaded Doctrine proxy objects on the Entities for use in view templates. This avoids lazy loaded queries from being executed outside the core application and somewhere they don't belong, such as in a view template.

      $product = new Entity\Product;
      $product->addTag(new Entity\Tag);
      
      $productDTO = $product->getDTOBuilder()
        ->withAllData(new Lib\Pricing)
        ->build();
      
      echo $productDTO->sku;
      echo $productDTO->price->unitPrice;
      echo $productDTO->tags[0]->name;
  • Lib

    • This is where you will find a variety of utility code including the Payment Gateway (src/Lib/PaymentGateway).

      $creditCard = new Entity\CreditCard;
      $creditCard->setName('John Doe');
      $creditCard->setZip5('90210');
      $creditCard->setNumber('4242424242424242');
      $creditCard->setCvc('123');
      $creditCard->setExpirationMonth('1');
      $creditCard->setExpirationYear('2020');
      
      $chargeRequest = new Lib\PaymentGateway\ChargeRequest;
      $chargeRequest->setCreditCard($creditCard);
      $chargeRequest->setAmount(2000);
      $chargeRequest->setCurrency('usd');
      $chargeRequest->setDescription('test@example.com');
      
      $stripe = new Lib\PaymentGateway\StripeFake;
      $charge = $stripe->getCharge($chargeRequest);

Installation

Add the following lines to your composer.json file.

{
    "require": {
        "inklabs/kommerce-core": "dev-master"
    }
}
   composer install

Unit Tests:

    vendor/bin/phpunit

With Code Coverage:

    vendor/bin/phpunit --coverage-text --coverage-html coverage_report

Run Coding Standards Test:

    vendor/bin/phpcs -p --standard=PSR2 src/ tests/

Count Lines of Code:

    vendor/bin/phploc src/ tests/ --names="*.php,*.xml"

Export SQL

    vendor/bin/doctrine orm:schema-tool:create --dump-sql
    vendor/bin/doctrine orm:schema-tool:update --dump-sql

License

Copyright 2014 Jamie Isaacs pdt256@gmail.com

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

inklabs/kommerce-core 适用场景与选型建议

inklabs/kommerce-core 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 366 次下载、GitHub Stars 达 64, 最近一次更新时间为 2014 年 12 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「zen」 「kommerce」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

围绕 inklabs/kommerce-core 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 366
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 64
  • 点击次数: 10
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 64
  • Watchers: 4
  • Forks: 11
  • 开发语言: PHP

其他信息

  • 授权协议: Apache-2.0
  • 更新时间: 2014-12-04