Coder Social home page Coder Social logo

eccube-api4's Introduction

EC-CUBE 4.2

Unit test for EC-CUBE E2E test for EC-CUBE Plugin test for EC-CUBE PHPStan codecov

Slack

4.1からの更新内容はリリースノートをご確認ください。

  • 本ドキュメントはEC-CUBEの開発者を主要な対象者としております。
  • パッケージ版はEC-CUBEオフィシャルサイトで配布しています。
  • カスタマイズやEC-CUBEの利用、仕様に関しては開発コミュニティをご利用ください。
  • 本体開発にあたって不明点などあればIssueをご利用下さい。
  • EC-CUBE 3系の保守については、 EC-CUBE/ec-cube3にて開発を行っております。
  • EC-CUBE 2系の保守については、 EC-CUBE/ec-cube2にて開発を行っております。

インストール

EC-CUBE 4.2のインストール方法

開発ドキュメントの インストール方法 の手順に従ってインストールしてください。

CSS の編集・ビルド方法

Sass を使用して記述されています。 Sass のソースコードは html/template/{admin,default}/assets/scss にあります。 前提として [https://nodejs.org/ja/] より、 Node.js をインストールしておいてください。

以下のコマンドでビルドすることで、 html/template/**/assets/css に CSS ファイルが出力されます。

npm ci # 初回およびpackage-lock.jsonに変更があったとき
npm run build # Sass のビルド

docker compose を使用している場合は以下のコマンドを実行してください

# 初回およびpackage-lock.jsonに変更があったとき
docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.nodejs.yml run --rm -T nodejs npm ci
# Sass のビルド
docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.nodejs.yml run --rm -T nodejs npm run build

JavaScript のビルド方法

フロントエンドで使用する JavaScript のライブラリは npm で管理されています。 JavaScript のライブラリは webpack でバンドル/minifyされます。 バンドルするライブラリを変更する場合は、テンプレートごとに以下の bundle.js を修正し、リビルドしてください。

npm ci # 初回およびpackage-lock.jsonに変更があったとき
npm run build # Sass 及び JavaScript のビルド

JavaScript ライブラリのみをビルドしたい場合は以下でも可能です。

npx webpack

docker compose を使用している場合は以下のコマンドを実行してください

# 初回およびpackage-lock.jsonに変更があったとき
docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.nodejs.yml run --rm -T nodejs npm ci
# Sass のビルド
docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.nodejs.yml run --rm -T nodejs npm run build
# JavaScript ライブラリのみのビルド
docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.nodejs.yml run --rm -T nodejs npx webpack

動作確認環境

  • Apache 2.4.x (mod_rewrite / mod_ssl 必須)
  • PHP 7.4.x / 8.0.x / 8.1.x
  • PostgreSQL 10.x or higher / MySQL 5.7.x or 8.0.x
  • ブラウザー:Google Chrome

詳しくは開発ドキュメントの システム要件 をご確認ください。

ドキュメント

EC-CUBE 4.x 系の仕様や手順、開発Tipsに関するドキュメントを掲載しています。 修正や追記、新規ドキュメントの作成をいただく場合、以下のレポジトリからPullRequestをお送りください。 https://github.com/EC-CUBE/doc4.ec-cube.net

開発への参加

EC-CUBE 4.2の不具合の修正、機能のブラッシュアップを目的として、継続的に開発を行っております。
コードのリファクタリング、不具合修正以外のPullRequestを送る際は、Pull Requestのコメントなどに意図を明確に記載してください。

Pull Requestの送信前に、Issueにて提議いただく事も可能です。 Issuesの利用方法については、こちらをご確認ください。

Slackでも本体の開発に関する意見交換などを行っております。

コピーライトポリシーへの同意

コードの提供・追加、修正・変更その他「EC-CUBE」への開発の御協力(Issue投稿、Pull Request投稿など、GitHub上での活動)を行っていただく場合には、 EC-CUBEのコピーライトポリシーをご理解いただき、ご了承いただく必要がございます。 Issueの投稿やPull Requestを送信する際は、EC-CUBEのコピーライトポリシーに同意したものとみなします。

eccube-api4's People

Contributors

chihiro-adachi avatar dependabot[bot] avatar dotani1111 avatar kiy0taka avatar nanasess avatar okazy avatar pineray avatar polidog avatar snyk-bot avatar takeuji avatar tps-nghiale avatar yv-101 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eccube-api4's Issues

検索条件の日付指定で秒まで指定してもエラーが出ない

検索条件の日付指定で時まで指定してもエラーが出ません。
例えば以下のように秒まで指定してもエラーとなりませんが、 *_date_* フォーマットでは日までしか指定できないので時間以下が意味をなさず、指定した日付全てが取得対象となってしまいます。

query {
  orders (page: 1, limit: 4, order_date_start:"2020-10-09 00:15:00", order_date_end:"2020-10-09 00:16:00") {
    nodes {
      id
    }
    totalCount
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
  }
}

紛らわしいので日付までの指定以外はエラーとなるようにしたいです。

Variablesを利用しないで引数を指定した場合に出荷日の登録ができない

Variablesを利用しないで引数を指定した場合に出荷日の登録ができない不具合があります。

文字列から DataTime へは DateTimeType::parseValue() で変換しています。

public function parseValue($value)
{
$dateTime = DateTime::createFromFormat(DateTime::ATOM, $value);
if ($dateTime) {
return $dateTime;
} else {
throw new InvalidArgumentException('DateTime parse error, please specify in "Y-m-d\TH:i:sP".'.Utils::printSafe($value));
}
}

Mutationのリゾルバ内で引数を利用していますが、リゾルバ実行時点で文字列のまま引数が渡される場合があります。
リクエストの引数の指定の方法の違いでこちらの処理を通らないで文字列のまま場合があるようです。

public function updateShipped($root, $args)

引数を直接指定する場合

mutation UpdateShipped {
  updateShipped (
    id: 1,
    shipping_date: "2020-05-18T12:57:08+09:00"
  ) {
    id
    shipping_date
  }
}

こちらの場合はリゾルバ実行時点で $args から文字列が取得できます。

引数をvariablesで指定する場合

mutation UpdateShipped (
  $shipping_date: DateTime
){
  updateShipped (
    id: 99,
    shipping_date: $shipping_date
  ) {
    id
    shipping_date
  }
}
{
  "shipping_date": "2020-05-18T12:57:08+09:00"
}

こちらの場合はリゾルバ実行時点で $args から DateTime が取得できます。

リゾルバで文字列か DateTime か調べることで回避できますが、他のクエリでも起こり得ることかと思いますので、原因の追究はしておきたいです。

Paging

基本的には管理画面のようなページングを目指す。

表示件数と何ページ目かを指定して取得できる。

スコープの精査

現在暫定的に read のスコープを設定しているが、エンドポイントが一つしかないので、読み書きどちらもできてしまう。
graphqlあたりに変更するのはいかがでしょうか。

redirect_uri の追加ができない

redirect_uri はカンマ区切りで複数登録可能だが、現状は新規登録時にしか登録ができない。
テスト環境→本番環境の切替等で、後から追加したいケースがあるため、編集機能が欲しい

認可サーバーとリソースサーバーを分ける

  • 顧客API, 商品API を別々のサーバーにしたい場合、認可サーバーも別サーバーにできたらいいなというイメージ
  • 現状のライブラリでは、データベースも分けようとした場合辛そう

出荷ステータスの更新

  • 注文出荷情報のステータスを更新

パラメータ

Name type Description
id ID 出荷ID (必須)
shipping_delivery_name String 配送方法 (変更する場合は必須)
shipping_date String 出荷日 (変更する場合は必須)
tracking_number String お問い合わせ番号 (変更する場合は必須)
note String 出荷用メモ欄 (変更する場合は必須)

※注文情報に紐づく全ての出荷情報に出荷日が入れば、その注文情報が出荷済みとなる。

実行例

mutation {
    editShippingStatus (
        id: 1
        shipping_delivery_name: "サンプル宅配"
        shipping_date: "2020-01-01"
        tracking_number: "tracking0123"
        note: "出荷しました。"
    ) {
        id
        shipping_delivery_name
        shipping_date
        tracking_number
        note
    }
}

デフォルトで Refresh Token Grant が有効になっていない

Refresh Token Grant でも401 が返りログインが求められる

再現方法

Access Token の TTL を短くして Refresh Token Grant を発生させてところ、ログインを求められた。

trikoder_oauth2:
    authorization_server:
        access_token_ttl:     PT1S

OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE => 'onAuthorizationRequestResolve' が影響しているのかと思うが、 /token では呼ばれないはずなので原因はわかっていない。

APIクライアントは Insomnia を利用

商品在庫更新

概要

  • 商品規格情報の在庫数を更新

パラメータ

Name type Description
code string 商品コード (必須)
stock Int 商品規格の在庫数 (在庫無制限が無効の場合は必須)
stock_unlimited Boolean 商品規格の在庫無制限 (必須)

実行例

# 在庫無制限ではない商品
mutation {
    editProductStock (
        code: "product-001"
        stock: 5
        stock_unlimited: false
    ) {
        code
        stock
        stock_unlimited
    }
}
# 在庫無制限の商品
mutation {
    editProductStock (
        code: "product-002"
        stock_unlimited: true
    ) {
        code
        stock
        stock_unlimited
    }
}

商品コードで一意にならない場合は、エラーとする。

`cube-01` の在庫を更新できない

初期状態で cube-01 の商品規格が2レコード登録されてしまっているので、在庫数を更新できない。
仕様通りではあるが、流石に初期データの更新ができないのは回避したい。

https://github.com/EC-CUBE/ec-cube/blob/4.0/src/Eccube/Resource/doctrine/import_csv/ja/dtb_product_class.csv

対象を visible = true のみに絞る方法も考えられるが、非表示も活用されている可能性もあるので心配ではある。
本体の初期データを変更するのも一案。

[Webhook] 一度の画面遷移で複数回通知が送信される場合がある

Slackにてご報告いただきました。
https://ec-cube.slack.com/archives/C03P2Q8QL/p1604373774011600

Webhookを設定し、購入フローで商品を購入した場合、一度の画面遷移で複数回通知される場合がある。

フロントの「カートの商品」→「ご注文手続き」画面への遷移で以下
▼受注情報登録:3回
body: ‘[{“entity”:“order”,“id”:16,“action”:“created”}]’

「ご注文手続き」から「確認画面」へ遷移した際に以下
▼受注情報更新:3回
body: ‘[{“entity”:“order”,“id”:16,“action”:“updated”}]’

購入完了時は、こちらの1回の通知が来ております。
▼受注・商品・会員情報更新:1回
body: ‘[{“entity”:“order”,“id”:16,“action”:“updated”},{“entity”:“product”,“id”:2,“action”:“updated”},{“entity”:“customer”,“id”:1,“action”:“updated”}]’

少なくとも “action”:“created” が3回通知されるのは意図した動きではないはず。

KernelEvents::RESPONSE のイベントで通知をしている。
https://github.com/EC-CUBE/eccube-api4/blob/master/Service/WebHookService.php#L59

サブリクエストで KernelEvents::RESPONSE のイベントが複数回呼ばれることがあるのだと推察するが、原因調査はできていない。

WebHook URLが接続できない場合のエラー処理が適切でない可能性がある

本プラグインをインストール後にテスト用にWebHookのURLを追加してみたところ、URLの入力ミスで接続できず、WebHookへのリクエスト送信時に以下のエラーが画面に出力されました。

Argument 1 passed to Plugin\Api\Service\WebHookService::Plugin\Api\Service\{closure}() must be an instance of GuzzleHttp\Exception\RequestException, instance of GuzzleHttp\Exception\ConnectException given

該当コードでは RequestException を想定しているのですが、その手前でエラーになった場合 ConnectException が渡ってくる可能性があるので \Exception を指定したほうが良いかと思いますが、エラーハンドリングの想定スコープが分からなかったためissueのみ上げさせていただきます。

環境

eccube/api 2.1.3

日時の入力と出力のフォーマットにズレがある

日時の入力と出力のフォーマットにズレがある

出力フォーマット: 2020-07-13T17:40:50+09:00
入力フォーマット: 2020-07-13 17:40:50

入力フォーマットでも 2020-07-13T17:40:50+09:00 形式で取得可能にしたい。

商品価格の更新

商品の価格を更新する Mutation が欲しい。
究極は商品規格情報の変更の Mutation があれば良いのかもしれないが、仕様が複雑になってしまうので、まずは #38 の在庫更新と同様に、商品コードを指定して商品の価格を更新するシンプルな Mutation を用意するのがよいと思う。

パラメータ

Name type Description
code string 商品コード (必須)
price01 Int 通常価格
price02 Int 販売価格 (必須)

実行例

# 在庫無制限ではない商品
mutation {
    updateProductPrice (
        code: "product-001"
        price01: 3000
        price02: 2800
    ) {
        code
        price01
        price02
    }
}

商品コードで一意にならない場合は、エラーとする。

プラグイン削除時に MappingException がスローされる場合がある

bin/console eccube:composer:remove ec-cube/Api を実行した場合に、以下の MappingException がスローされる場合がある。
composer install を実行してから、再度 eccube:composer:remove を実行することで解消される

[68.7MiB/0.15s] Loading composer repositories with package information
[69.2MiB/0.15s] <warning>Warning: Accessing 127.0.0.1 over http which is an insecure protocol.</warning>
[69.2MiB/1.15s] Updating dependencies (including require-dev)
[466.2MiB/7.54s] Package operations: 0 installs, 0 updates, 11 removals
[466.2MiB/7.54s]   - Removing webonyx/graphql-php (v14.0.2)
[466.2MiB/7.57s]   - Removing trikoder/oauth2-bundle (v2.1.1)
[466.2MiB/7.59s]   - Removing symfony/psr-http-message-bridge (v1.2.0)
[466.2MiB/7.61s]   - Removing psr/http-factory (1.0.1)
[466.2MiB/7.63s]   - Removing php-http/message-factory (v1.0.2)
[466.2MiB/7.64s]   - Removing nyholm/psr7 (1.3.0)
[466.2MiB/7.66s]   - Removing league/oauth2-server (7.4.0)
[466.2MiB/7.68s]   - Removing league/event (2.2.0)
[466.2MiB/7.70s]   - Removing lcobucci/jwt (3.3.2)

In MappingException.php line 49:

  File mapping drivers must have a valid directory path, however the given path [/path/to/ec-cube/ven
  dor/trikoder/oauth2-bundle/Resources/config/doctrine/model] seems to be incorrect!


remove [--dev] [--no-progress] [--no-update] [--no-scripts] [--update-no-dev] [--update-with-dependencies] [--no-update-with-dependencies] [--ignore-platform-reqs] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--] <packages> (<packages>)...


In ComposerApiService.php line 319:

  [Eccube\Exception\PluginException]


eccube:composer:remove [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command> <package>

マスターデータの取得

マスターデータの取得方法が現状でGraphQLを辿っていくしかない。
マスターデータを取得できる方法が欲しい。

案1: Queryで取得

マスターデータ取得用のクエリを実装

query {
  orderStatuses {
    id
    name
  }
}

案2: Schemaで取得

enumでスキーマを定義

enum OrderStatus {
  NEW
  CANCEL
  IN_PROGRESS
  ...
}

案2は既存のEC-CUBEのコードからSchemaを生成するのが難しいので諦めざるを得ないか。。。
(CountryやJobなどのマスターデータは英語の変数名を持っていないので自動生成できない??)

WebHook

概要

商品/顧客/受注情報の変更時(登録/更新/削除)に登録されたWebHookに対して変更を通知する。

以下のようなコマンドと同等の内容を送信する。

curl \
    -X POST \
    --header "Content-Type: application/json" \
    --header 'X-ECCUBE-URL': 'https://eccube.exampel.com/' \
    'https://webhook.example.com' \
    --data '{
        "events": [
            {
                "entity": "product",
                "id": 13,
                "action": "created"
            },
            {
                "entity": "product",
                "id": 14,
                "action": "created"
            }
        ]
    }'

WebHookの登録

// TBD

Entityに対するWebHookの発火

Product / Customer / Order に対する変更はWebHookで通知されるが、これら3つのEntityに関連するEntityが変更されたときはデフォルトで通知されない。
プラグインやカスタマイズで3つのEntityに関連するEntityを作成していて通知させたい場合は、Plugin\Api\Service\WebHookTrigger インターフェイスを実装したクラスを定義する。

WebHook側の処理

通知を受け取る側の実装は以下のようにすることを推奨します。

  • 素早くレスポンス(200 OK)を返す。受け取った通知をキューに登録して先にレスポンスを返すようにする。処理はレスポンスを返したあとに実行する。
  • 空のレスポンスを返す。EC-CUBE側ではレスポンスボディの内容は無視します。

Webhooksを有効にするとエラーが発生する

Webhooksの登録をして商品などを編集すると発生

プロダクロモードで以下のエラーが発生

image

Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to Plugin\Api\Service\WebHookService::Plugin\Api\Service\{closure}() must be an instance of Nyholm\Psr7\Response, instance of GuzzleHttp\Psr7\Response given in /Users/hideki_okajima/temp/eccube-api/ec-cube-rc/app/Plugin/Api/Service/WebHookService.php:85 Stack trace: #0 [internal function]: Plugin\Api\Service\WebHookService->Plugin\Api\Service\{closure}(Object(GuzzleHttp\Psr7\Response), 0, Object(GuzzleHttp\Promise\Promise)) #1 /Users/hideki_okajima/temp/eccube-api/ec-cube-rc/vendor/guzzlehttp/promises/src/EachPromise.php(158): call_user_func(Object(Closure), Object(GuzzleHttp\Psr7\Response), 0, Object(GuzzleHttp\Promise\Promise)) #2 /Users/hideki_okajima/temp/eccube-api/ec-cube-rc/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Promise\EachPromise->GuzzleHttp\Promise\{closure}(Object(GuzzleHttp\Psr7\Response)) #3 /Users/hideki_okajima/temp/eccube-api/ec-cube-rc/vendor/guzzlehttp/promises/src/Promise.php(1 in /Users/hideki_okajima/temp/eccube-api/ec-cube-rc/app/Plugin/Api/Service/WebHookService.php on line 85

debugモードで実行すると

image

limit に0を設定してリクエストすると Internal Server Error となる

「顧客一覧の取得」APIで「limit」に0を設定してリクエストすると「Internal Server Error」となります。他のパラメータに0を設定しても「Internal Server Error」とはなりませんでした。

リクエスト

POST /api HTTP/1.1
Host: api-202008.ec-cube.net
User-Agent: curl/7.71.1
Accept: */*
Content-Type: application/json
Authorization: Bearer eyJ0eXAi...
{ "query": "query{customers(page:1,limit:0,multi:\"1\",customer_status:[\"2\"]){nodes{id name01 name02}totalCount pageInfo{hasNextPage hasPreviousPage}}}"}

レスポンス

{
  "errors": [
    {
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 1,
          "column": 7
        }
      ],
      "path": [
        "customers"
      ]
    }
  ],
  "data": {
    "customers": null
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.