{"id":2668,"date":"2025-03-24T08:46:49","date_gmt":"2025-03-23T23:46:49","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=2668"},"modified":"2025-03-24T08:47:18","modified_gmt":"2025-03-23T23:47:18","slug":"laravel%e3%81%aemvc%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3%e5%ae%8c%e5%85%a8%e8%a7%a3%e8%aa%ac%ef%bc%81%e5%ae%9f%e8%b7%b5%e3%81%a7%e4%bd%bf%e3%81%88%e3%82%8b7%e3%81%a4%e3%81%ae%e9%87%8d%e8%a6%81%e3%83%9d","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=2668","title":{"rendered":"Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u5b8c\u5168\u89e3\u8aac\uff01\u5b9f\u8df5\u3067\u4f7f\u3048\u308b7\u3064\u306e\u91cd\u8981\u30dd\u30a4\u30f3\u30c8"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u89e3\u8aac<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-1\">MVC\u30d1\u30bf\u30fc\u30f3\u304c\u89e3\u6c7a\u3059\u308b3\u3064\u306e\u958b\u767a\u306e\u8ab2\u984c<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-2\">Laravel\u3067MVC\u30d1\u30bf\u30fc\u30f3\u3092\u63a1\u7528\u3059\u308b\u30e1\u30ea\u30c3\u30c8<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-3\">Laravel\u306b\u304a\u3051\u308b\u5404\u5c64\u306e\u5f79\u5272\u3068\u5b9f\u88c5\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-4\">\u30e2\u30c7\u30eb\u5c64\u3067\u306e\u30c7\u30fc\u30bf\u64cd\u4f5c\u3068\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-5\">Controller\u5c64\u3067\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u51e6\u7406\u3068\u30ec\u30b9\u30dd\u30f3\u30b9\u751f\u6210<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-6\">View\u5c64\u3067\u306e\u30c7\u30fc\u30bf\u8868\u793a\u3068\u30e6\u30fc\u30b6\u30fc\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-7\">\u5b9f\u8df5MVC\u8a2d\u8a08\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u624b\u9806<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-8\">\u30b9\u30c6\u30c3\u30d71\uff1a\u30e2\u30c7\u30eb\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u8a2d\u8a08<\/a>      <\/li>      <li>        <a href=\"#i-9\">\u30b9\u30c6\u30c3\u30d72\uff1a\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5\u3068\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u8a2d\u5b9a<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-10\">\u30b9\u30c6\u30c3\u30d73\uff1a\u30d3\u30e5\u30fc\u306e\u4f5c\u6210\u3068\u30d6\u30ec\u30fc\u30c9\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u6d3b\u7528<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-11\">Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u306b\u304a\u3051\u308b\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-12\">\u30d5\u30a1\u30c3\u30c8\u30e2\u30c7\u30eb\u30fb\u30b7\u30f3\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u539f\u5247<\/a>      <\/li>      <li>        <a href=\"#i-13\">\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u3092\u6d3b\u7528\u3057\u305f\u8cac\u52d9\u306e\u5206\u96e2<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-14\">\u30ea\u30dd\u30b8\u30c8\u30ea\u30d1\u30bf\u30fc\u30f3\u306e\u5c0e\u5165\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-15\">\u3088\u304f\u3042\u308bMVC\u5b9f\u88c5\u306e\u554f\u984c\u70b9\u3068\u89e3\u6c7a\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-16\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304c\u80a5\u5927\u5316\u3059\u308b\u554f\u984c\u306e\u5bfe\u51e6\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-17\">\u30e2\u30c7\u30eb\u306e\u8cac\u52d9\u304c\u80a5\u5927\u5316\u3059\u308b\u554f\u984c\u306e\u89e3\u6c7a\u7b56<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-18\">\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u914d\u7f6e\u5834\u6240\u306e\u9069\u5207\u306a\u5224\u65ad\u65b9\u6cd5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-19\">\u5b9f\u8df5\u7684\u306a\u30b3\u30fc\u30c9\u4f8b\u3067\u5b66\u3076MVC\u30d1\u30bf\u30fc\u30f3<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-20\">\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li>        <a href=\"#i-21\">\u5546\u54c1\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-22\">API\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306e\u5b9f\u88c5\u4f8b<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-23\">MVC\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3057\u305f\u958b\u767a\u306e\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-24\">\u30af\u30ea\u30fc\u30f3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3078\u306e\u767a\u5c55<\/a>      <\/li>      <li>        <a href=\"#i-25\">\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\u3068\u306e\u7d44\u307f\u5408\u308f\u305b<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-26\">\u30c6\u30b9\u30bf\u30d3\u30ea\u30c6\u30a3\u306e\u5411\u4e0a\u3068\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u306e\u5b9f\u73fe<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u89e3\u8aac<\/h2>\n\n\n\n<p>Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u306f\u3001Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u69cb\u9020\u3092\u6574\u7406\u3057\u3001\u4fdd\u5b88\u6027\u3068\u62e1\u5f35\u6027\u3092\u9ad8\u3081\u308b\u305f\u3081\u306e\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u3002Model\uff08\u30e2\u30c7\u30eb\uff09\u3001View\uff08\u30d3\u30e5\u30fc\uff09\u3001Controller\uff08\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\uff09\u306e3\u3064\u306e\u5c64\u306b\u5206\u96e2\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u8cac\u52d9\u3092\u660e\u78ba\u306b\u5206\u3051\u3001\u958b\u767a\u52b9\u7387\u3092\u5411\u4e0a\u3055\u305b\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-1\">MVC\u30d1\u30bf\u30fc\u30f3\u304c\u89e3\u6c7a\u3059\u308b3\u3064\u306e\u958b\u767a\u306e\u8ab2\u984c<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b3\u30fc\u30c9\u306e\u6df7\u5728\u306b\u3088\u308b\u4fdd\u5b88\u6027\u306e\u4f4e\u4e0b<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3001\u8868\u793a\u30ed\u30b8\u30c3\u30af\u3001\u30c7\u30fc\u30bf\u64cd\u4f5c\u304c1\u3064\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u6df7\u5728\u3059\u308b\u554f\u984c\u3092\u89e3\u6c7a<\/li>\n\n\n\n<li>\u5404\u5c64\u306e\u8cac\u52d9\u3092\u660e\u78ba\u306b\u5206\u96e2\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u898b\u901a\u3057\u304c\u6539\u5584<\/li>\n\n\n\n<li>\u4fee\u6b63\u3084\u6a5f\u80fd\u8ffd\u52a0\u6642\u306e\u5f71\u97ff\u7bc4\u56f2\u3092\u7279\u5b9a\u3057\u3084\u3059\u304f\u306a\u308b<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c1\u30fc\u30e0\u958b\u767a\u306b\u304a\u3051\u308b\u751f\u7523\u6027\u306e\u4f4e\u4e0b<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u8907\u6570\u306e\u958b\u767a\u8005\u304c\u540c\u3058\u30d5\u30a1\u30a4\u30eb\u3092\u540c\u6642\u306b\u7de8\u96c6\u3059\u308b\u3053\u3068\u306b\u3088\u308b\u7af6\u5408\u3092\u6e1b\u5c11<\/li>\n\n\n\n<li>\u5404\u5c64\u306e\u62c5\u5f53\u8005\uff08\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30fb\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\uff09\u304c\u4e26\u884c\u3057\u3066\u958b\u767a\u53ef\u80fd<\/li>\n\n\n\n<li>\u7d71\u4e00\u3055\u308c\u305f\u69cb\u9020\u306b\u3088\u308a\u3001\u65b0\u30e1\u30f3\u30d0\u30fc\u306e\u5b66\u7fd2\u30b3\u30b9\u30c8\u3092\u524a\u6e1b<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c6\u30b9\u30c8\u306e\u56f0\u96e3\u3055<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5404\u5c64\u3092\u72ec\u7acb\u3057\u3066\u30c6\u30b9\u30c8\u53ef\u80fd\u306a\u69cb\u9020\u3092\u5b9f\u73fe<\/li>\n\n\n\n<li>\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u306e\u8a18\u8ff0\u304c\u5bb9\u6613\u306b\u306a\u308b<\/li>\n\n\n\n<li>\u30e2\u30c3\u30af\u3084\u30b9\u30bf\u30d6\u3092\u4f7f\u7528\u3057\u305f isolated \u30c6\u30b9\u30c8\u306e\u5b9f\u88c5\u304c\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-2\">Laravel\u3067MVC\u30d1\u30bf\u30fc\u30f3\u3092\u63a1\u7528\u3059\u308b\u30e1\u30ea\u30c3\u30c8<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u30ec\u30d9\u30eb\u3067\u306e\u5f37\u529b\u306a\u30b5\u30dd\u30fc\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eloquent ORM\u306b\u3088\u308b\u76f4\u611f\u7684\u306a\u30e2\u30c7\u30eb\u5c64\u306e\u5b9f\u88c5<\/li>\n\n\n\n<li>Blade\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30a8\u30f3\u30b8\u30f3\u306b\u3088\u308b\u52b9\u7387\u7684\u306a\u30d3\u30e5\u30fc\u5c64\u306e\u958b\u767a<\/li>\n\n\n\n<li>\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5bc6\u63a5\u306a\u7d71\u5408<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8c4a\u5bcc\u306a\u958b\u767a\u652f\u63f4\u6a5f\u80fd<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">   \/\/ \u30e2\u30c7\u30eb\u306e\u4f8b\uff1aEloquent ORM\u306b\u3088\u308b\u7c21\u6f54\u306a\u8a18\u8ff0\n   class User extends Model\n   {\n       \/\/ \u30ea\u30ec\u30fc\u30b7\u30e7\u30f3\u30b7\u30c3\u30d7\u306e\u5b9a\u7fa9\u304c\u5bb9\u6613\n       public function posts()\n       {\n           return $this-&gt;hasMany(Post::class);\n       }\n   }<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5bfe\u7b56\u306e\u6a19\u6e96\u88c5\u5099<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>XSS\u5bfe\u7b56\uff1aBlade\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306b\u3088\u308b\u81ea\u52d5\u30a8\u30b9\u30b1\u30fc\u30d7<\/li>\n\n\n\n<li>CSRF\u5bfe\u7b56\uff1a\u30d5\u30a9\u30fc\u30e0\u9001\u4fe1\u6642\u306e\u81ea\u52d5\u7684\u306a\u30c8\u30fc\u30af\u30f3\u691c\u8a3c<\/li>\n\n\n\n<li>SQL\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f3\u5bfe\u7b56\uff1aEloquent ORM\u3068\u30af\u30a8\u30ea\u30d3\u30eb\u30c0<\/li>\n<\/ul>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u5927\u898f\u6a21\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3078\u306e\u5bfe\u5fdc<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306b\u3088\u308b\u6a5f\u80fd\u306e\u5206\u5272\u3068\u4f9d\u5b58\u6027\u306e\u7ba1\u7406<\/li>\n\n\n\n<li>\u30df\u30c9\u30eb\u30a6\u30a7\u30a2\u306b\u3088\u308b\u30ea\u30af\u30a8\u30b9\u30c8\/\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u67d4\u8edf\u306a\u5236\u5fa1<\/li>\n\n\n\n<li>\u30a4\u30d9\u30f3\u30c8\/\u30ea\u30b9\u30ca\u30fc\u306b\u3088\u308b\u758e\u7d50\u5408\u306a\u6a5f\u80fd\u62e1\u5f35<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u7279\u5fb4\u306b\u3088\u308a\u3001Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u306f\u3001\u5c0f\u898f\u6a21\u304b\u3089\u5927\u898f\u6a21\u307e\u3067\u3001\u69d8\u3005\u306aWeb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u306b\u9069\u3057\u305f\u9078\u629e\u80a2\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u7279\u306b\u3001\u30c1\u30fc\u30e0\u958b\u767a\u306b\u304a\u3044\u3066\u306f\u3001\u7d71\u4e00\u3055\u308c\u305f\u8a2d\u8a08\u65b9\u91dd\u3068\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u898f\u7d04\u3092\u81ea\u7136\u306b\u5c0e\u5165\u3067\u304d\u308b\u70b9\u304c\u5927\u304d\u306a\u5229\u70b9\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-3\">Laravel\u306b\u304a\u3051\u308b\u5404\u5c64\u306e\u5f79\u5272\u3068\u5b9f\u88c5\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-4\">\u30e2\u30c7\u30eb\u5c64\u3067\u306e\u30c7\u30fc\u30bf\u64cd\u4f5c\u3068\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u30e2\u30c7\u30eb\u5c64\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3068\u30c7\u30fc\u30bf\u64cd\u4f5c\u3092\u62c5\u5f53\u3059\u308b\u91cd\u8981\u306a\u5c64\u3067\u3059\u3002Laravel\u3067\u306f\u3001Eloquent ORM\u3092\u4f7f\u7528\u3057\u3066\u3001\u76f4\u611f\u7684\u304b\u3064\u5f37\u529b\u306a\u30e2\u30c7\u30eb\u306e\u5b9f\u88c5\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u57fa\u672c\u7684\u306a\u30e2\u30c7\u30eb\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Product.php\nclass Product extends Model\n{\n    \/\/ Mass Assignment \u4fdd\u8b77\u306e\u8a2d\u5b9a\n    protected $fillable = [\n        'name', 'price', 'description', 'stock'\n    ];\n\n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30a2\u30af\u30bb\u30b5\u306e\u5b9a\u7fa9\n    public function getDisplayPriceAttribute()\n    {\n        return '\u00a5' . number_format($this-&gt;price);\n    }\n\n    \/\/ \u30b9\u30b3\u30fc\u30d7\u306e\u5b9a\u7fa9\n    public function scopeInStock($query)\n    {\n        return $query-&gt;where('stock', '&gt;', 0);\n    }\n\n    \/\/ \u30ea\u30ec\u30fc\u30b7\u30e7\u30f3\u30b7\u30c3\u30d7\u306e\u5b9a\u7fa9\n    public function category()\n    {\n        return $this-&gt;belongsTo(Category::class);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u5b9f\u88c5\u4f8b<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public function decreaseStock($quantity)\n{\n    if ($this-&gt;stock &lt; $quantity) {\n        throw new InsufficientStockException();\n    }\n\n    $this-&gt;stock -= $quantity;\n    $this-&gt;save();\n\n    if ($this-&gt;stock &lt;= $this-&gt;reorder_point) {\n        event(new LowStockAlert($this));\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">Controller\u5c64\u3067\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u51e6\u7406\u3068\u30ec\u30b9\u30dd\u30f3\u30b9\u751f\u6210<\/h3>\n\n\n\n<p>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u5c64\u306f\u3001HTTP\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u53d7\u3051\u53d6\u308a\u3001\u9069\u5207\u306a\u51e6\u7406\u3092\u884c\u3044\u3001\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u8fd4\u3059\u5f79\u5272\u3092\u62c5\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ea\u30bd\u30fc\u30b9\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/ProductController.php\nclass ProductController extends Controller\n{\n    public function index()\n    {\n        $products = Product::inStock()\n            -&gt;with('category')\n            -&gt;paginate(20);\n\n        return view('products.index', compact('products'));\n    }\n\n    public function store(ProductRequest $request)\n    {\n        $product = Product::create($request-&gt;validated());\n\n        return redirect()\n            -&gt;route('products.show', $product)\n            -&gt;with('success', '\u5546\u54c1\u3092\u767b\u9332\u3057\u307e\u3057\u305f');\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30d5\u30a9\u30fc\u30e0\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u3088\u308b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Requests\/ProductRequest.php\nclass ProductRequest extends FormRequest\n{\n    public function rules()\n    {\n        return [\n            'name' =&gt; 'required|max:255',\n            'price' =&gt; 'required|integer|min:0',\n            'stock' =&gt; 'required|integer|min:0',\n            'category_id' =&gt; 'required|exists:categories,id'\n        ];\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">View\u5c64\u3067\u306e\u30c7\u30fc\u30bf\u8868\u793a\u3068\u30e6\u30fc\u30b6\u30fc\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9<\/h3>\n\n\n\n<p>\u30d3\u30e5\u30fc\u5c64\u306f\u3001\u30e6\u30fc\u30b6\u30fc\u306b\u60c5\u5831\u3092\u8868\u793a\u3057\u3001\u30a4\u30f3\u30bf\u30e9\u30af\u30b7\u30e7\u30f3\u3092\u63d0\u4f9b\u3059\u308b\u5f79\u5272\u3092\u62c5\u3044\u307e\u3059\u3002Laravel\u3067\u306f\u3001Blade\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30a8\u30f3\u30b8\u30f3\u3092\u4f7f\u7528\u3057\u3066\u52b9\u7387\u7684\u306a\u30d3\u30e5\u30fc\u306e\u4f5c\u6210\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/layouts\/app.blade.php --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;@yield('title') - {{ config('app.name') }}&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    @include('layouts.header')\n\n    @if(session('success'))\n        &lt;div class=\"alert alert-success\"&gt;\n            {{ session('success') }}\n        &lt;\/div&gt;\n    @endif\n\n    @yield('content')\n\n    @include('layouts.footer')\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/components\/product-card.blade.php --&gt;\n@props(['product'])\n\n&lt;div class=\"product-card\"&gt;\n    &lt;h3&gt;{{ $product-&gt;name }}&lt;\/h3&gt;\n    &lt;p class=\"price\"&gt;{{ $product-&gt;display_price }}&lt;\/p&gt;\n    &lt;p class=\"stock\"&gt;\u5728\u5eab: {{ $product-&gt;stock }}\u500b&lt;\/p&gt;\n\n    @if($product-&gt;stock &gt; 0)\n        &lt;form action=\"{{ route('cart.add', $product) }}\" method=\"POST\"&gt;\n            @csrf\n            &lt;button type=\"submit\"&gt;\u30ab\u30fc\u30c8\u306b\u8ffd\u52a0&lt;\/button&gt;\n        &lt;\/form&gt;\n    @else\n        &lt;p class=\"out-of-stock\"&gt;\u5728\u5eab\u5207\u308c&lt;\/p&gt;\n    @endif\n&lt;\/div&gt;<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30d3\u30e5\u30fc\u3067\u306e\u30c7\u30fc\u30bf\u8868\u793a<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/products\/index.blade.php --&gt;\n@extends('layouts.app')\n\n@section('title', '\u5546\u54c1\u4e00\u89a7')\n\n@section('content')\n    &lt;div class=\"products-grid\"&gt;\n        @foreach($products as $product)\n            &lt;x-product-card :product=\"$product\" \/&gt;\n        @endforeach\n    &lt;\/div&gt;\n\n    {{ $products-&gt;links() }}\n@endsection<\/pre>\n\n\n\n<p>\u3053\u306e\u3088\u3046\u306b\u3001\u5404\u5c64\u304c\u660e\u78ba\u306a\u8cac\u52d9\u3092\u6301\u3061\u3001\u305d\u308c\u305e\u308c\u304c\u72ec\u7acb\u3057\u3066\u6a5f\u80fd\u3057\u306a\u304c\u3089\u3082\u3001\u5bc6\u63a5\u306b\u9023\u643a\u3057\u3066\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3092\u69cb\u7bc9\u3057\u307e\u3059\u3002\u3053\u306e\u69cb\u9020\u306b\u3088\u308a\u3001\u30b3\u30fc\u30c9\u306e\u4fdd\u5b88\u6027\u304c\u9ad8\u307e\u308a\u3001\u6a5f\u80fd\u306e\u8ffd\u52a0\u3084\u5909\u66f4\u304c\u5bb9\u6613\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-7\">\u5b9f\u8df5MVC\u8a2d\u8a08\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u624b\u9806<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">\u30b9\u30c6\u30c3\u30d71\uff1a\u30e2\u30c7\u30eb\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u8a2d\u8a08<\/h3>\n\n\n\n<p>\u30e2\u30c7\u30eb\u8a2d\u8a08\u306f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u57fa\u76e4\u3068\u306a\u308b\u91cd\u8981\u306a\u30b9\u30c6\u30c3\u30d7\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u624b\u9806\u3067\u5b9f\u88c5\u3092\u9032\u3081\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ database\/migrations\/2024_02_07_create_orders_table.php\npublic function up()\n{\n    Schema::create('orders', function (Blueprint $table) {\n        $table-&gt;id();\n        $table-&gt;foreignId('user_id')-&gt;constrained();\n        $table-&gt;string('order_number')-&gt;unique();\n        $table-&gt;decimal('total_amount', 10, 2);\n        $table-&gt;enum('status', ['pending', 'processing', 'completed', 'cancelled']);\n        $table-&gt;timestamps();\n\n        \/\/ \u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u8ffd\u52a0\u306b\u3088\u308b\u691c\u7d22\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306e\u6700\u9069\u5316\n        $table-&gt;index(['status', 'created_at']);\n    });\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30e2\u30c7\u30eb\u30af\u30e9\u30b9\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Order.php\nclass Order extends Model\n{\n    use HasFactory;\n\n    protected $fillable = [\n        'order_number',\n        'total_amount',\n        'status'\n    ];\n\n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5b9a\u6570\u306e\u5b9a\u7fa9\n    const STATUS_PENDING = 'pending';\n    const STATUS_PROCESSING = 'processing';\n    const STATUS_COMPLETED = 'completed';\n    const STATUS_CANCELLED = 'cancelled';\n\n    \/\/ \u30ea\u30ec\u30fc\u30b7\u30e7\u30f3\u30b7\u30c3\u30d7\u306e\u5b9a\u7fa9\n    public function user()\n    {\n        return $this-&gt;belongsTo(User::class);\n    }\n\n    public function items()\n    {\n        return $this-&gt;hasMany(OrderItem::class);\n    }\n\n    \/\/ \u30b9\u30c6\u30fc\u30bf\u30b9\u5909\u66f4\u306e\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\n    public function markAsProcessing()\n    {\n        if ($this-&gt;status !== self::STATUS_PENDING) {\n            throw new InvalidOrderStatusTransitionException();\n        }\n\n        $this-&gt;update(['status' =&gt; self::STATUS_PROCESSING]);\n        event(new OrderStatusChanged($this));\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">\u30b9\u30c6\u30c3\u30d72\uff1a\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5\u3068\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u8a2d\u5b9a<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u5b9a\u7fa9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ routes\/web.php\nRoute::middleware(['auth'])-&gt;group(function () {\n    Route::resource('orders', OrderController::class);\n\n    \/\/ \u30ab\u30b9\u30bf\u30e0\u30a2\u30af\u30b7\u30e7\u30f3\u7528\u306e\u30eb\u30fc\u30c8\n    Route::post('orders\/{order}\/process', [OrderController::class, 'process'])\n        -&gt;name('orders.process');\n});<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/OrderController.php\nclass OrderController extends Controller\n{\n    public function __construct(\n        private OrderRepository $orders,\n        private OrderProcessor $processor\n    ) {}\n\n    public function index()\n    {\n        $orders = $this-&gt;orders-&gt;getPaginatedOrders(\n            auth()-&gt;id(),\n            request('status')\n        );\n\n        return view('orders.index', compact('orders'));\n    }\n\n    public function store(CreateOrderRequest $request)\n    {\n        DB::transaction(function () use ($request) {\n            $order = $this-&gt;orders-&gt;create($request-&gt;validated());\n            $this-&gt;processor-&gt;processNewOrder($order);\n        });\n\n        return redirect()\n            -&gt;route('orders.show', $order)\n            -&gt;with('success', '\u6ce8\u6587\u3092\u53d7\u3051\u4ed8\u3051\u307e\u3057\u305f');\n    }\n\n    public function process(Order $order)\n    {\n        $this-&gt;authorize('process', $order);\n\n        try {\n            $this-&gt;processor-&gt;startProcessing($order);\n            return back()-&gt;with('success', '\u6ce8\u6587\u306e\u51e6\u7406\u3092\u958b\u59cb\u3057\u307e\u3057\u305f');\n        } catch (InvalidOrderStatusTransitionException $e) {\n            return back()-&gt;with('error', '\u73fe\u5728\u306e\u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u3067\u306f\u51e6\u7406\u3092\u958b\u59cb\u3067\u304d\u307e\u305b\u3093');\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">\u30b9\u30c6\u30c3\u30d73\uff1a\u30d3\u30e5\u30fc\u306e\u4f5c\u6210\u3068\u30d6\u30ec\u30fc\u30c9\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u6d3b\u7528<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5171\u901a\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/layouts\/app.blade.php --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"ja\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;@yield('title') - \u6ce8\u6587\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0&lt;\/title&gt;\n    @vite(['resources\/css\/app.css', 'resources\/js\/app.js'])\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;x-navigation \/&gt;\n\n    &lt;main class=\"container mx-auto px-4 py-6\"&gt;\n        &lt;x-alerts \/&gt;\n        @yield('content')\n    &lt;\/main&gt;\n\n    &lt;x-footer \/&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u6ce8\u6587\u4e00\u89a7\u30d3\u30e5\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/orders\/index.blade.php --&gt;\n@extends('layouts.app')\n\n@section('title', '\u6ce8\u6587\u4e00\u89a7')\n\n@section('content')\n    &lt;div class=\"space-y-6\"&gt;\n        &lt;x-order-filters :status=\"request('status')\" \/&gt;\n\n        &lt;div class=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\"&gt;\n            @foreach($orders as $order)\n                &lt;x-order-card :order=\"$order\"&gt;\n                    @can('process', $order)\n                        &lt;x-slot name=\"actions\"&gt;\n                            &lt;form action=\"{{ route('orders.process', $order) }}\" method=\"POST\"&gt;\n                                @csrf\n                                &lt;x-button type=\"submit\"&gt;\u51e6\u7406\u958b\u59cb&lt;\/x-button&gt;\n                            &lt;\/form&gt;\n                        &lt;\/x-slot&gt;\n                    @endcan\n                &lt;\/x-order-card&gt;\n            @endforeach\n        &lt;\/div&gt;\n\n        {{ $orders-&gt;withQueryString()-&gt;links() }}\n    &lt;\/div&gt;\n@endsection<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u518d\u5229\u7528\u53ef\u80fd\u306a\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u4f5c\u6210<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- resources\/views\/components\/order-card.blade.php --&gt;\n@props(['order'])\n\n&lt;div class=\"bg-white rounded-lg shadow p-6\"&gt;\n    &lt;div class=\"flex justify-between items-start\"&gt;\n        &lt;div&gt;\n            &lt;h3 class=\"text-lg font-semibold\"&gt;\n                \u6ce8\u6587\u756a\u53f7: {{ $order-&gt;order_number }}\n            &lt;\/h3&gt;\n            &lt;p class=\"text-gray-600\"&gt;\n                {{ $order-&gt;created_at-&gt;format('Y\/m\/d H:i') }}\n            &lt;\/p&gt;\n        &lt;\/div&gt;\n        &lt;x-status-badge :status=\"$order-&gt;status\" \/&gt;\n    &lt;\/div&gt;\n\n    &lt;div class=\"mt-4\"&gt;\n        &lt;p class=\"font-medium\"&gt;\n            \u5408\u8a08\u91d1\u984d: {{ number_format($order-&gt;total_amount) }}\u5186\n        &lt;\/p&gt;\n    &lt;\/div&gt;\n\n    @if(isset($actions))\n        &lt;div class=\"mt-4 space-x-2\"&gt;\n            {{ $actions }}\n        &lt;\/div&gt;\n    @endif\n&lt;\/div&gt;<\/pre>\n\n\n\n<p>\u3053\u306e\u5b9f\u88c5\u624b\u9806\u306b\u5f93\u3046\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u62e1\u5f35\u6027\u306e\u3042\u308bMVC\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002\u5404\u5c64\u306e\u8cac\u52d9\u3092\u660e\u78ba\u306b\u5206\u96e2\u3057\u3001\u9069\u5207\u306a\u30c7\u30b6\u30a4\u30f3\u30d1\u30bf\u30fc\u30f3\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u54c1\u8cea\u3068\u958b\u767a\u52b9\u7387\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-11\">Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u306b\u304a\u3051\u308b\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-12\">\u30d5\u30a1\u30c3\u30c8\u30e2\u30c7\u30eb\u30fb\u30b7\u30f3\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u539f\u5247<\/h3>\n\n\n\n<p>\u30d5\u30a1\u30c3\u30c8\u30e2\u30c7\u30eb\u30fb\u30b7\u30f3\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u539f\u5247\u306f\u3001\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3092\u30e2\u30c7\u30eb\u306b\u96c6\u4e2d\u3055\u305b\u3001\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u3067\u304d\u308b\u3060\u3051\u30b7\u30f3\u30d7\u30eb\u306b\u4fdd\u3064\u30a2\u30d7\u30ed\u30fc\u30c1\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u826f\u3044\u5b9f\u88c5\u4f8b<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Order.php\nclass Order extends Model\n{\n    public function calculateTotalAmount()\n    {\n        return $this-&gt;items-&gt;sum(function ($item) {\n            return $item-&gt;quantity * $item-&gt;unit_price;\n        });\n    }\n\n    public function canBeCancelled()\n    {\n        return in_array($this-&gt;status, [\n            self::STATUS_PENDING,\n            self::STATUS_PROCESSING\n        ]);\n    }\n\n    public function cancel()\n    {\n        if (!$this-&gt;canBeCancelled()) {\n            throw new OrderCancellationException('\u3053\u306e\u6ce8\u6587\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3067\u304d\u307e\u305b\u3093');\n        }\n\n        $this-&gt;status = self::STATUS_CANCELLED;\n        $this-&gt;cancelled_at = now();\n        $this-&gt;save();\n\n        event(new OrderCancelled($this));\n    }\n}\n\n\/\/ app\/Http\/Controllers\/OrderController.php\nclass OrderController extends Controller\n{\n    public function cancel(Order $order)\n    {\n        $this-&gt;authorize('cancel', $order);\n\n        try {\n            $order-&gt;cancel();\n            return back()-&gt;with('success', '\u6ce8\u6587\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f');\n        } catch (OrderCancellationException $e) {\n            return back()-&gt;with('error', $e-&gt;getMessage());\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u3092\u6d3b\u7528\u3057\u305f\u8cac\u52d9\u306e\u5206\u96e2<\/h3>\n\n\n\n<p>\u8907\u96d1\u306a\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306f\u3001\u5c02\u7528\u306e\u30b5\u30fc\u30d3\u30b9\u30af\u30e9\u30b9\u306b\u5206\u96e2\u3059\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027\u3068\u4fdd\u5b88\u6027\u3092\u5411\u4e0a\u3055\u305b\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Services\/OrderService.php\nclass OrderService\n{\n    public function __construct(\n        private PaymentGateway $paymentGateway,\n        private InventoryManager $inventoryManager,\n        private NotificationService $notificationService\n    ) {}\n\n    public function createOrder(array $data): Order\n    {\n        return DB::transaction(function () use ($data) {\n            \/\/ \u6ce8\u6587\u306e\u4f5c\u6210\n            $order = Order::create([\n                'user_id' =&gt; auth()-&gt;id(),\n                'total_amount' =&gt; $this-&gt;calculateTotal($data['items'])\n            ]);\n\n            \/\/ \u6ce8\u6587\u8a73\u7d30\u306e\u4f5c\u6210\n            $this-&gt;createOrderItems($order, $data['items']);\n\n            \/\/ \u5728\u5eab\u306e\u78ba\u4fdd\n            $this-&gt;inventoryManager-&gt;reserveStock($order);\n\n            \/\/ \u652f\u6255\u3044\u51e6\u7406\n            $this-&gt;processPayment($order, $data['payment']);\n\n            \/\/ \u901a\u77e5\u306e\u9001\u4fe1\n            $this-&gt;notificationService-&gt;sendOrderConfirmation($order);\n\n            return $order;\n        });\n    }\n\n    private function calculateTotal(array $items): float\n    {\n        return collect($items)-&gt;sum(function ($item) {\n            return $item['quantity'] * $item['price'];\n        });\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">\u30ea\u30dd\u30b8\u30c8\u30ea\u30d1\u30bf\u30fc\u30f3\u306e\u5c0e\u5165\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30ea\u30dd\u30b8\u30c8\u30ea\u30d1\u30bf\u30fc\u30f3\u3092\u5c0e\u5165\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30fc\u30bf\u30a2\u30af\u30bb\u30b9\u30ed\u30b8\u30c3\u30af\u3092\u62bd\u8c61\u5316\u3057\u3001\u30e2\u30c7\u30eb\u3068\u306e\u7d50\u5408\u5ea6\u3092\u4f4e\u6e1b\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306e\u5b9a\u7fa9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Repositories\/Contracts\/OrderRepositoryInterface.php\ninterface OrderRepositoryInterface\n{\n    public function findByOrderNumber(string $orderNumber): ?Order;\n    public function getPendingOrders(): Collection;\n    public function getOrdersByStatus(string $status, int $perPage = 15);\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30ea\u30dd\u30b8\u30c8\u30ea\u30af\u30e9\u30b9\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Repositories\/Eloquent\/OrderRepository.php\nclass OrderRepository implements OrderRepositoryInterface\n{\n    public function findByOrderNumber(string $orderNumber): ?Order\n    {\n        return Order::where('order_number', $orderNumber)\n            -&gt;with(['items', 'user'])\n            -&gt;first();\n    }\n\n    public function getPendingOrders(): Collection\n    {\n        return Order::where('status', Order::STATUS_PENDING)\n            -&gt;with(['items'])\n            -&gt;orderBy('created_at')\n            -&gt;get();\n    }\n\n    public function getOrdersByStatus(string $status, int $perPage = 15)\n    {\n        return Order::where('status', $status)\n            -&gt;with(['items', 'user'])\n            -&gt;latest()\n            -&gt;paginate($perPage);\n    }\n}<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3067\u306e\u767b\u9332<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Providers\/RepositoryServiceProvider.php\nclass RepositoryServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        $this-&gt;app-&gt;bind(\n            OrderRepositoryInterface::class,\n            OrderRepository::class\n        );\n    }\n}<\/pre>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3067\u306e\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderController extends Controller\n{\n    public function __construct(\n        private OrderRepositoryInterface $orderRepository,\n        private OrderService $orderService\n    ) {}\n\n    public function index(Request $request)\n    {\n        $status = $request-&gt;get('status', Order::STATUS_PENDING);\n        $orders = $this-&gt;orderRepository-&gt;getOrdersByStatus($status);\n\n        return view('orders.index', compact('orders'));\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4ee5\u4e0b\u306e\u30e1\u30ea\u30c3\u30c8\u304c\u5f97\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u306e\u8cac\u52d9\u304c\u660e\u78ba\u306b\u5206\u96e2\u3055\u308c\u3001\u4fdd\u5b88\u6027\u304c\u5411\u4e0a<\/li>\n\n\n\n<li>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u518d\u5229\u7528\u304c\u5bb9\u6613\u306b\u306a\u308b<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u304c\u66f8\u304d\u3084\u3059\u304f\u306a\u308b<\/li>\n\n\n\n<li>\u4f9d\u5b58\u95a2\u4fc2\u304c\u660e\u78ba\u306b\u306a\u308a\u3001\u5909\u66f4\u306e\u5f71\u97ff\u7bc4\u56f2\u304c\u628a\u63e1\u3057\u3084\u3059\u3044<\/li>\n\n\n\n<li>\u30c1\u30fc\u30e0\u958b\u767a\u3067\u306e\u4f5c\u696d\u5206\u62c5\u304c\u3057\u3084\u3059\u304f\u306a\u308b<\/li>\n<\/ul>\n\n\n\n<p>\u7279\u306b\u5927\u898f\u6a21\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u6301\u7d9a\u53ef\u80fd\u306a\u958b\u767a\u4f53\u5236\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-15\">\u3088\u304f\u3042\u308bMVC\u5b9f\u88c5\u306e\u554f\u984c\u70b9\u3068\u89e3\u6c7a\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-16\">\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304c\u80a5\u5927\u5316\u3059\u308b\u554f\u984c\u306e\u5bfe\u51e6\u6cd5<\/h3>\n\n\n\n<p>\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u80a5\u5927\u5316\u306f\u3001MVC\u30d1\u30bf\u30fc\u30f3\u306b\u304a\u3044\u3066\u6700\u3082\u4e00\u822c\u7684\u306a\u554f\u984c\u306e\u4e00\u3064\u3067\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u554f\u984c\u306e\u3042\u308b\u5b9f\u88c5\u4f8b<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderController extends Controller\n{\n    public function store(Request $request)\n    {\n        \/\/ \u5165\u529b\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\n        $validated = $request-&gt;validate([\n            'items' =&gt; 'required|array',\n            'items.*.id' =&gt; 'required|exists:products,id',\n            'items.*.quantity' =&gt; 'required|integer|min:1',\n            'shipping_address' =&gt; 'required|string',\n            'payment_method' =&gt; 'required|in:credit_card,bank_transfer'\n        ]);\n\n        \/\/ \u5546\u54c1\u60c5\u5831\u306e\u53d6\u5f97\u3068\u5728\u5eab\u30c1\u30a7\u30c3\u30af\n        $items = collect($validated['items'])-&gt;map(function ($item) {\n            $product = Product::find($item['id']);\n            if ($product-&gt;stock &lt; $item['quantity']) {\n                throw new InsufficientStockException();\n            }\n            return ['product' =&gt; $product, 'quantity' =&gt; $item['quantity']];\n        });\n\n        \/\/ \u5408\u8a08\u91d1\u984d\u306e\u8a08\u7b97\n        $totalAmount = $items-&gt;sum(function ($item) {\n            return $item['product']-&gt;price * $item['quantity'];\n        });\n\n        \/\/ \u652f\u6255\u3044\u51e6\u7406\n        $payment = PaymentGateway::process([\n            'amount' =&gt; $totalAmount,\n            'method' =&gt; $validated['payment_method']\n        ]);\n\n        \/\/ \u6ce8\u6587\u306e\u4f5c\u6210\n        $order = Order::create([\n            'user_id' =&gt; auth()-&gt;id(),\n            'total_amount' =&gt; $totalAmount,\n            'shipping_address' =&gt; $validated['shipping_address'],\n            'payment_id' =&gt; $payment-&gt;id\n        ]);\n\n        \/\/ \u6ce8\u6587\u8a73\u7d30\u306e\u4f5c\u6210\u3068\u5728\u5eab\u306e\u66f4\u65b0\n        foreach ($items as $item) {\n            $order-&gt;items()-&gt;create([\n                'product_id' =&gt; $item['product']-&gt;id,\n                'quantity' =&gt; $item['quantity'],\n                'price' =&gt; $item['product']-&gt;price\n            ]);\n\n            $item['product']-&gt;decrement('stock', $item['quantity']);\n        }\n\n        \/\/ \u30e1\u30fc\u30eb\u9001\u4fe1\n        Mail::to($order-&gt;user)-&gt;send(new OrderConfirmation($order));\n\n        return redirect()-&gt;route('orders.show', $order);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u6539\u5584\u3055\u308c\u305f\u5b9f\u88c5\u4f8b<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderController extends Controller\n{\n    public function __construct(\n        private OrderService $orderService,\n        private ProductRepository $products\n    ) {}\n\n    public function store(CreateOrderRequest $request)\n    {\n        try {\n            $order = $this-&gt;orderService-&gt;createOrder(\n                $request-&gt;validated()\n            );\n\n            return redirect()\n                -&gt;route('orders.show', $order)\n                -&gt;with('success', '\u6ce8\u6587\u3092\u53d7\u3051\u4ed8\u3051\u307e\u3057\u305f');\n        } catch (InsufficientStockException $e) {\n            return back()\n                -&gt;withErrors(['stock' =&gt; '\u5728\u5eab\u304c\u4e0d\u8db3\u3057\u3066\u3044\u307e\u3059'])\n                -&gt;withInput();\n        } catch (PaymentFailedException $e) {\n            return back()\n                -&gt;withErrors(['payment' =&gt; '\u6c7a\u6e08\u51e6\u7406\u306b\u5931\u6557\u3057\u307e\u3057\u305f'])\n                -&gt;withInput();\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u30e2\u30c7\u30eb\u306e\u8cac\u52d9\u304c\u80a5\u5927\u5316\u3059\u308b\u554f\u984c\u306e\u89e3\u6c7a\u7b56<\/h3>\n\n\n\n<p>\u30e2\u30c7\u30eb\u306b\u904e\u5ea6\u306b\u8cac\u52d9\u304c\u96c6\u4e2d\u3059\u308b\u554f\u984c\u306f\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u65b9\u6cd5\u3067\u89e3\u6c7a\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c8\u30ec\u30a4\u30c8\u3092\u4f7f\u7528\u3057\u305f\u6a5f\u80fd\u306e\u5206\u5272<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Traits\/HasOrderStatus.php\ntrait HasOrderStatus\n{\n    public function isPending(): bool\n    {\n        return $this-&gt;status === self::STATUS_PENDING;\n    }\n\n    public function markAsProcessing(): void\n    {\n        $this-&gt;update(['status' =&gt; self::STATUS_PROCESSING]);\n        event(new OrderStatusChanged($this));\n    }\n}\n\n\/\/ app\/Models\/Traits\/ManagesInventory.php\ntrait ManagesInventory\n{\n    public function adjustStock(int $quantity): void\n    {\n        $this-&gt;increment('stock', $quantity);\n\n        if ($this-&gt;stock &lt;= $this-&gt;reorder_point) {\n            event(new LowStockAlert($this));\n        }\n    }\n}\n\n\/\/ app\/Models\/Order.php\nclass Order extends Model\n{\n    use HasOrderStatus;\n\n    \/\/ \u30e2\u30c7\u30eb\u306e\u57fa\u672c\u7684\u306a\u8a2d\u5b9a\u306e\u307f\u3092\u8a18\u8ff0\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u5024\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/ValueObjects\/Money.php\nclass Money\n{\n    public function __construct(\n        private float $amount,\n        private string $currency = 'JPY'\n    ) {}\n\n    public function add(Money $other): self\n    {\n        if ($this-&gt;currency !== $other-&gt;currency) {\n            throw new InvalidCurrencyException();\n        }\n        return new self($this-&gt;amount + $other-&gt;amount, $this-&gt;currency);\n    }\n\n    public function format(): string\n    {\n        return number_format($this-&gt;amount) . ' ' . $this-&gt;currency;\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u914d\u7f6e\u5834\u6240\u306e\u9069\u5207\u306a\u5224\u65ad\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u914d\u7f6e\u306f\u3001\u4ee5\u4e0b\u306e\u539f\u5247\u306b\u5f93\u3063\u3066\u5224\u65ad\u3057\u307e\u3059\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30b5\u30fc\u30d3\u30b9\u306e\u6d3b\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Services\/Domain\/OrderFulfillmentService.php\nclass OrderFulfillmentService\n{\n    public function __construct(\n        private InventoryManager $inventory,\n        private ShippingProvider $shipping\n    ) {}\n\n    public function fulfill(Order $order): void\n    {\n        if (!$order-&gt;isPaid()) {\n            throw new UnpaidOrderException();\n        }\n\n        DB::transaction(function () use ($order) {\n            \/\/ \u5728\u5eab\u306e\u5f15\u304d\u5f53\u3066\n            $this-&gt;inventory-&gt;allocate($order);\n\n            \/\/ \u914d\u9001\u624b\u914d\n            $trackingNumber = $this-&gt;shipping-&gt;arrange($order);\n\n            \/\/ \u6ce8\u6587\u30b9\u30c6\u30fc\u30bf\u30b9\u306e\u66f4\u65b0\n            $order-&gt;update([\n                'status' =&gt; Order::STATUS_SHIPPING,\n                'tracking_number' =&gt; $trackingNumber\n            ]);\n        });\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30a2\u30af\u30b7\u30e7\u30f3\u30af\u30e9\u30b9\u306e\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Actions\/Orders\/CancelOrder.php\nclass CancelOrder\n{\n    public function __construct(\n        private RefundService $refundService,\n        private InventoryManager $inventoryManager\n    ) {}\n\n    public function execute(Order $order): void\n    {\n        if (!$order-&gt;canBeCancelled()) {\n            throw new OrderCancellationException();\n        }\n\n        DB::transaction(function () use ($order) {\n            \/\/ \u8fd4\u91d1\u51e6\u7406\n            $this-&gt;refundService-&gt;refund($order-&gt;payment);\n\n            \/\/ \u5728\u5eab\u306e\u623b\u3057\n            $this-&gt;inventoryManager-&gt;returnItems($order-&gt;items);\n\n            \/\/ \u6ce8\u6587\u306e\u30ad\u30e3\u30f3\u30bb\u30eb\n            $order-&gt;markAsCancelled();\n        });\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u89e3\u6c7a\u7b56\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u5229\u70b9\u304c\u5f97\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30b3\u30fc\u30c9\u306e\u8cac\u52d9\u304c\u9069\u5207\u306b\u5206\u6563\u3055\u308c\u3001\u4fdd\u5b88\u6027\u304c\u5411\u4e0a<\/li>\n\n\n\n<li>\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247\u306b\u5f93\u3063\u305f\u8a2d\u8a08\u304c\u53ef\u80fd<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u304c\u3057\u3084\u3059\u304f\u306a\u308b<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027\u304c\u5411\u4e0a<\/li>\n\n\n\n<li>\u5909\u66f4\u306e\u5f71\u97ff\u7bc4\u56f2\u304c\u9650\u5b9a\u7684\u306b\u306a\u308b<\/li>\n<\/ul>\n\n\n\n<p>\u7279\u306b\u5927\u898f\u6a21\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u72b6\u6cc1\u306b\u5fdc\u3058\u3066\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-19\">\u5b9f\u8df5\u7684\u306a\u30b3\u30fc\u30c9\u4f8b\u3067\u5b66\u3076MVC\u30d1\u30bf\u30fc\u30f3<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">\u30e6\u30fc\u30b6\u30fc\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<p>Laravel\u306eMVC\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3057\u305f\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u4f8b\u3092\u793a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u7528\u306e\u30e2\u30c7\u30eb\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/User.php\nclass User extends Authenticatable\n{\n    use HasFactory, Notifiable, HasApiTokens;\n\n    protected $fillable = [\n        'name', 'email', 'password',\n        'last_login_at', 'email_verified_at'\n    ];\n\n    protected $hidden = [\n        'password',\n        'remember_token',\n    ];\n\n    \/\/ \u4e8c\u8981\u7d20\u8a8d\u8a3c\u306e\u72b6\u614b\u78ba\u8a8d\n    public function hasTwoFactorEnabled(): bool\n    {\n        return !is_null($this-&gt;two_factor_secret);\n    }\n\n    \/\/ \u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u30ed\u30c3\u30af\u72b6\u614b\u78ba\u8a8d\n    public function isLocked(): bool\n    {\n        return $this-&gt;login_attempts &gt;= 5 &amp;&amp;\n            $this-&gt;locked_until &gt; now();\n    }\n\n    \/\/ \u30ed\u30b0\u30a4\u30f3\u8a66\u884c\u306e\u8a18\u9332\n    public function recordLoginAttempt(): void\n    {\n        $this-&gt;increment('login_attempts');\n\n        if ($this-&gt;login_attempts &gt;= 5) {\n            $this-&gt;locked_until = now()-&gt;addMinutes(30);\n            $this-&gt;save();\n        }\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u8a8d\u8a3c\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Auth\/LoginController.php\nclass LoginController extends Controller\n{\n    public function __construct(\n        private AuthenticationService $authService\n    ) {}\n\n    public function login(LoginRequest $request)\n    {\n        try {\n            $result = $this-&gt;authService-&gt;attemptLogin(\n                $request-&gt;validated()\n            );\n\n            if ($result-&gt;requiresTwoFactor()) {\n                return redirect()-&gt;route('2fa.challenge');\n            }\n\n            return redirect()-&gt;intended(route('dashboard'));\n        } catch (AccountLockedException $e) {\n            return back()\n                -&gt;withErrors(['email' =&gt; '\u4e00\u6642\u7684\u306b\u30a2\u30ab\u30a6\u30f3\u30c8\u304c\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059']);\n        }\n    }\n\n    public function twoFactorChallenge(TwoFactorRequest $request)\n    {\n        try {\n            $this-&gt;authService-&gt;verifyTwoFactor(\n                $request-&gt;validated()\n            );\n\n            return redirect()-&gt;intended(route('dashboard'));\n        } catch (InvalidTwoFactorCodeException $e) {\n            return back()-&gt;withErrors(['code' =&gt; '\u7121\u52b9\u306a\u8a8d\u8a3c\u30b3\u30fc\u30c9\u3067\u3059']);\n        }\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u5546\u54c1\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<p>\u5546\u54c1\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u306b\u304a\u3051\u308bMVC\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u4f8b\u3092\u793a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5546\u54c1\u30ab\u30c6\u30b4\u30ea\u30fc\u306e\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Category.php\nclass Category extends Model\n{\n    use HasSlug;\n\n    protected $fillable = ['name', 'description', 'parent_id'];\n\n    public function children()\n    {\n        return $this-&gt;hasMany(Category::class, 'parent_id');\n    }\n\n    public function products()\n    {\n        return $this-&gt;hasMany(Product::class);\n    }\n}\n\n\/\/ app\/Http\/Controllers\/Admin\/CategoryController.php\nclass CategoryController extends Controller\n{\n    public function __construct(\n        private CategoryRepository $categories\n    ) {}\n\n    public function index()\n    {\n        $categories = $this-&gt;categories-&gt;getTreeStructure();\n        return view('admin.categories.index', compact('categories'));\n    }\n\n    public function store(CategoryRequest $request)\n    {\n        $category = $this-&gt;categories-&gt;create($request-&gt;validated());\n\n        return redirect()\n            -&gt;route('admin.categories.index')\n            -&gt;with('success', '\u30ab\u30c6\u30b4\u30ea\u30fc\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f');\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u5546\u54c1\u5728\u5eab\u306e\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Models\/Product.php\nclass Product extends Model\n{\n    use HasFactory, SoftDeletes;\n\n    protected $fillable = [\n        'name', 'description', 'price',\n        'stock', 'category_id', 'sku'\n    ];\n\n    public function category()\n    {\n        return $this-&gt;belongsTo(Category::class);\n    }\n\n    public function isLowStock(): bool\n    {\n        return $this-&gt;stock &lt;= $this-&gt;reorder_point;\n    }\n}\n\n\/\/ app\/Http\/Controllers\/Admin\/ProductController.php\nclass ProductController extends Controller\n{\n    public function __construct(\n        private ProductService $productService,\n        private CategoryRepository $categories\n    ) {}\n\n    public function create()\n    {\n        $categories = $this-&gt;categories-&gt;getSelectOptions();\n        return view('admin.products.create', compact('categories'));\n    }\n\n    public function store(CreateProductRequest $request)\n    {\n        $product = $this-&gt;productService-&gt;createProduct(\n            $request-&gt;validated()\n        );\n\n        return redirect()\n            -&gt;route('admin.products.show', $product)\n            -&gt;with('success', '\u5546\u54c1\u3092\u767b\u9332\u3057\u307e\u3057\u305f');\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">API\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306e\u5b9f\u88c5\u4f8b<\/h3>\n\n\n\n<p>RESTful API\u306b\u304a\u3051\u308bMVC\u30d1\u30bf\u30fc\u30f3\u306e\u5b9f\u88c5\u4f8b\u3092\u793a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>API\u30ea\u30bd\u30fc\u30b9\u306e\u5b9a\u7fa9<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Resources\/ProductResource.php\nclass ProductResource extends JsonResource\n{\n    public function toArray($request)\n    {\n        return [\n            'id' =&gt; $this-&gt;id,\n            'name' =&gt; $this-&gt;name,\n            'slug' =&gt; $this-&gt;slug,\n            'description' =&gt; $this-&gt;description,\n            'price' =&gt; [\n                'amount' =&gt; $this-&gt;price,\n                'formatted' =&gt; '\u00a5' . number_format($this-&gt;price)\n            ],\n            'category' =&gt; new CategoryResource($this-&gt;whenLoaded('category')),\n            'stock_status' =&gt; $this-&gt;stock &gt; 0 ? 'in_stock' : 'out_of_stock',\n            'created_at' =&gt; $this-&gt;created_at-&gt;toIso8601String(),\n            'updated_at' =&gt; $this-&gt;updated_at-&gt;toIso8601String(),\n        ];\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>API\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Http\/Controllers\/Api\/ProductController.php\nclass ProductController extends Controller\n{\n    public function __construct(\n        private ProductRepository $products\n    ) {}\n\n    public function index(ProductIndexRequest $request)\n    {\n        $products = $this-&gt;products-&gt;searchProducts(\n            $request-&gt;validated(),\n            $request-&gt;input('per_page', 15)\n        );\n\n        return ProductResource::collection($products);\n    }\n\n    public function store(CreateProductRequest $request)\n    {\n        $product = $this-&gt;products-&gt;create($request-&gt;validated());\n\n        return new ProductResource($product);\n    }\n\n    public function update(UpdateProductRequest $request, Product $product)\n    {\n        $this-&gt;products-&gt;update($product, $request-&gt;validated());\n\n        return new ProductResource($product-&gt;fresh());\n    }\n}\n\n\/\/ app\/Http\/Controllers\/Api\/OrderController.php\nclass OrderController extends Controller\n{\n    public function __construct(\n        private OrderService $orderService\n    ) {}\n\n    public function store(CreateOrderRequest $request)\n    {\n        try {\n            $order = $this-&gt;orderService-&gt;createOrder(\n                $request-&gt;validated()\n            );\n\n            return new OrderResource($order);\n        } catch (OutOfStockException $e) {\n            return response()-&gt;json([\n                'message' =&gt; '\u5728\u5eab\u304c\u4e0d\u8db3\u3057\u3066\u3044\u307e\u3059',\n                'errors' =&gt; [\n                    'stock' =&gt; ['\u6307\u5b9a\u3055\u308c\u305f\u5546\u54c1\u306e\u5728\u5eab\u304c\u4e0d\u8db3\u3057\u3066\u3044\u307e\u3059']\n                ]\n            ], 422);\n        }\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u4f8b\u306f\u3001\u4ee5\u4e0b\u306e\u8a2d\u8a08\u539f\u5247\u306b\u57fa\u3065\u3044\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247\uff08SRP\uff09<\/li>\n\n\n\n<li>\u4f9d\u5b58\u6027\u306e\u6ce8\u5165\uff08DI\uff09<\/li>\n\n\n\n<li>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306e\u5206\u96e2<\/li>\n\n\n\n<li>\u30ea\u30dd\u30b8\u30c8\u30ea\u30d1\u30bf\u30fc\u30f3\u306e\u6d3b\u7528<\/li>\n\n\n\n<li>\u30b5\u30fc\u30d3\u30b9\u30ec\u30a4\u30e4\u30fc\u306e\u9069\u5207\u306a\u4f7f\u7528<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u539f\u5247\u3092\u610f\u8b58\u3057\u306a\u304c\u3089\u5b9f\u88c5\u3059\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u62e1\u5f35\u6027\u306e\u3042\u308b\u30b3\u30fc\u30c9\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-23\">MVC\u30d1\u30bf\u30fc\u30f3\u3092\u6d3b\u7528\u3057\u305f\u958b\u767a\u306e\u6b21\u306e\u30b9\u30c6\u30c3\u30d7<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-24\">\u30af\u30ea\u30fc\u30f3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3078\u306e\u767a\u5c55<\/h3>\n\n\n\n<p>MVC\u30d1\u30bf\u30fc\u30f3\u3092\u30d9\u30fc\u30b9\u306b\u3001\u30af\u30ea\u30fc\u30f3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306e\u8003\u3048\u65b9\u3092\u53d6\u308a\u5165\u308c\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u4fdd\u5b88\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u5c64\u306e\u5c0e\u5165<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/UseCases\/CreateOrder\/CreateOrderUseCase.php\nclass CreateOrderUseCase\n{\n    public function __construct(\n        private OrderRepository $orders,\n        private ProductRepository $products,\n        private PaymentGateway $paymentGateway\n    ) {}\n\n    public function execute(CreateOrderInput $input): CreateOrderOutput\n    {\n        \/\/ \u5165\u529b\u30c7\u30fc\u30bf\u306e\u691c\u8a3c\n        $products = $this-&gt;validateProducts($input-&gt;getProductIds());\n\n        \/\/ \u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u9069\u7528\n        $order = new Order([\n            'user_id' =&gt; $input-&gt;getUserId(),\n            'total_amount' =&gt; $this-&gt;calculateTotal($products, $input-&gt;getQuantities())\n        ]);\n\n        \/\/ \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\n        DB::transaction(function () use ($order, $products, $input) {\n            \/\/ \u5728\u5eab\u306e\u78ba\u8a8d\u3068\u66f4\u65b0\n            $this-&gt;updateInventory($products, $input-&gt;getQuantities());\n\n            \/\/ \u652f\u6255\u3044\u51e6\u7406\n            $payment = $this-&gt;processPayment($input-&gt;getPaymentData());\n\n            \/\/ \u6ce8\u6587\u306e\u4fdd\u5b58\n            $this-&gt;orders-&gt;save($order);\n\n            \/\/ \u6ce8\u6587\u8a73\u7d30\u306e\u4f5c\u6210\n            $this-&gt;createOrderItems($order, $products, $input-&gt;getQuantities());\n        });\n\n        return new CreateOrderOutput($order);\n    }\n}\n\n\/\/ app\/UseCases\/CreateOrder\/CreateOrderInput.php\nclass CreateOrderInput\n{\n    public function __construct(\n        private array $productIds,\n        private array $quantities,\n        private int $userId,\n        private array $paymentData\n    ) {}\n\n    \/\/ Getter\u30e1\u30bd\u30c3\u30c9...\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3068\u30c9\u30e1\u30a4\u30f3\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u5206\u96e2<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Domain\/Order\/Order.php\nclass Order\n{\n    private Collection $items;\n    private OrderStatus $status;\n    private Money $totalAmount;\n\n    public function addItem(Product $product, int $quantity): void\n    {\n        if ($this-&gt;status-&gt;isPaid()) {\n            throw new OrderAlreadyPaidException();\n        }\n\n        $this-&gt;items-&gt;add(new OrderItem($product, $quantity));\n        $this-&gt;recalculateTotal();\n    }\n\n    public function pay(Payment $payment): void\n    {\n        if (!$this-&gt;canBePaid()) {\n            throw new InvalidOrderStateException();\n        }\n\n        $this-&gt;status = OrderStatus::paid();\n        $this-&gt;payment = $payment;\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-25\">\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\u3068\u306e\u7d44\u307f\u5408\u308f\u305b<\/h3>\n\n\n\n<p>\u30c9\u30e1\u30a4\u30f3\u99c6\u52d5\u8a2d\u8a08\uff08DDD\uff09\u306e\u8003\u3048\u65b9\u3092\u53d6\u308a\u5165\u308c\u308b\u3053\u3068\u3067\u3001\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u3092\u3088\u308a\u660e\u78ba\u306b\u8868\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u96c6\u7d04\u30eb\u30fc\u30c8\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Domain\/Order\/OrderAggregate.php\nclass OrderAggregate implements AggregateRoot\n{\n    private Collection $domainEvents;\n\n    public function __construct(\n        private OrderId $id,\n        private UserId $userId,\n        private OrderStatus $status,\n        private Collection $items\n    ) {\n        $this-&gt;domainEvents = new Collection;\n    }\n\n    public function addItem(ProductId $productId, Quantity $quantity): void\n    {\n        \/\/ \u30d3\u30b8\u30cd\u30b9\u30eb\u30fc\u30eb\u306e\u691c\u8a3c\n        if ($this-&gt;status-&gt;isNotDraft()) {\n            throw new OrderNotEditableException();\n        }\n\n        $this-&gt;items-&gt;add(new OrderItem($productId, $quantity));\n\n        \/\/ \u30c9\u30e1\u30a4\u30f3\u30a4\u30d9\u30f3\u30c8\u306e\u767a\u884c\n        $this-&gt;raise(new OrderItemAdded($this-&gt;id, $productId, $quantity));\n    }\n\n    public function confirm(): void\n    {\n        if ($this-&gt;items-&gt;isEmpty()) {\n            throw new EmptyOrderException();\n        }\n\n        $this-&gt;status = OrderStatus::confirmed();\n        $this-&gt;raise(new OrderConfirmed($this-&gt;id));\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30b5\u30fc\u30d3\u30b9\u306e\u5b9f\u88c5<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ app\/Domain\/Order\/Services\/OrderPricingService.php\nclass OrderPricingService\n{\n    public function __construct(\n        private ProductPriceRepository $prices,\n        private DiscountPolicy $discountPolicy\n    ) {}\n\n    public function calculateTotal(OrderAggregate $order): Money\n    {\n        $subtotal = $this-&gt;calculateSubtotal($order);\n        $discount = $this-&gt;discountPolicy-&gt;calculateDiscount($order);\n\n        return $subtotal-&gt;subtract($discount);\n    }\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-26\">\u30c6\u30b9\u30bf\u30d3\u30ea\u30c6\u30a3\u306e\u5411\u4e0a\u3068\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u306e\u5b9f\u73fe<\/h3>\n\n\n\n<p>\u30c6\u30b9\u30c8\u5bb9\u6613\u6027\u3092\u8003\u616e\u3057\u305f\u8a2d\u8a08\u306b\u3088\u308a\u3001\u4fe1\u983c\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u306e\u30c6\u30b9\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class CreateOrderUseCaseTest extends TestCase\n{\n    private CreateOrderUseCase $useCase;\n    private MockInterface $orderRepository;\n    private MockInterface $productRepository;\n    private MockInterface $paymentGateway;\n\n    protected function setUp(): void\n    {\n        parent::setUp();\n\n        $this-&gt;orderRepository = Mockery::mock(OrderRepository::class);\n        $this-&gt;productRepository = Mockery::mock(ProductRepository::class);\n        $this-&gt;paymentGateway = Mockery::mock(PaymentGateway::class);\n\n        $this-&gt;useCase = new CreateOrderUseCase(\n            $this-&gt;orderRepository,\n            $this-&gt;productRepository,\n            $this-&gt;paymentGateway\n        );\n    }\n\n    public function testCreateOrderSuccessfully(): void\n    {\n        \/\/ \u30c6\u30b9\u30c8\u30c7\u30fc\u30bf\u306e\u6e96\u5099\n        $input = new CreateOrderInput(\n            productIds: [1, 2],\n            quantities: [2, 1],\n            userId: 1,\n            paymentData: ['method' =&gt; 'credit_card']\n        );\n\n        \/\/ \u30e2\u30c3\u30af\u306e\u8a2d\u5b9a\n        $this-&gt;productRepository\n            -&gt;shouldReceive('findMany')\n            -&gt;with([1, 2])\n            -&gt;andReturn(collect([\n                new Product(['id' =&gt; 1, 'price' =&gt; 1000]),\n                new Product(['id' =&gt; 2, 'price' =&gt; 2000])\n            ]));\n\n        \/\/ \u30c6\u30b9\u30c8\u306e\u5b9f\u884c\n        $output = $this-&gt;useCase-&gt;execute($input);\n\n        \/\/ \u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\n        $this-&gt;assertEquals(4000, $output-&gt;getOrder()-&gt;total_amount);\n        $this-&gt;assertEquals(OrderStatus::PENDING, $output-&gt;getOrder()-&gt;status);\n    }\n}<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u306e\u30c6\u30b9\u30c8<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class OrderAggregateTest extends TestCase\n{\n    public function testCannotAddItemToConfirmedOrder(): void\n    {\n        \/\/ \u30c6\u30b9\u30c8\u30c7\u30fc\u30bf\u306e\u6e96\u5099\n        $order = new OrderAggregate(\n            id: new OrderId(1),\n            userId: new UserId(1),\n            status: OrderStatus::confirmed(),\n            items: new Collection\n        );\n\n        \/\/ \u4f8b\u5916\u306e\u691c\u8a3c\n        $this-&gt;expectException(OrderNotEditableException::class);\n\n        \/\/ \u30c6\u30b9\u30c8\u306e\u5b9f\u884c\n        $order-&gt;addItem(\n            new ProductId(1),\n            new Quantity(2)\n        );\n    }\n\n    public function testCalculateTotalAmount(): void\n    {\n        \/\/ \u30c6\u30b9\u30c8\u30c7\u30fc\u30bf\u306e\u6e96\u5099\n        $order = new OrderAggregate(\n            id: new OrderId(1),\n            userId: new UserId(1),\n            status: OrderStatus::draft(),\n            items: new Collection\n        );\n\n        $order-&gt;addItem(new ProductId(1), new Quantity(2));\n        $order-&gt;addItem(new ProductId(2), new Quantity(1));\n\n        \/\/ \u30c9\u30e1\u30a4\u30f3\u30b5\u30fc\u30d3\u30b9\u306e\u5229\u7528\n        $pricingService = new OrderPricingService(\n            new InMemoryProductPriceRepository([\n                1 =&gt; new Money(1000),\n                2 =&gt; new Money(2000)\n            ]),\n            new NoDiscountPolicy()\n        );\n\n        \/\/ \u30c6\u30b9\u30c8\u306e\u5b9f\u884c\n        $total = $pricingService-&gt;calculateTotal($order);\n\n        \/\/ \u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\n        $this-&gt;assertEquals(\n            new Money(4000),\n            $total\n        );\n    }\n}<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u767a\u5c55\u7684\u306a\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u5c0e\u5165\u3059\u308b\u3053\u3068\u3067\u3001\u4ee5\u4e0b\u306e\u30e1\u30ea\u30c3\u30c8\u304c\u5f97\u3089\u308c\u307e\u3059\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u660e\u78ba\u306a\u8868\u73fe<\/li>\n\n\n\n<li>\u30c9\u30e1\u30a4\u30f3\u306e\u5909\u66f4\u306b\u5bfe\u3059\u308b\u67d4\u8edf\u306a\u5bfe\u5fdc<\/li>\n\n\n\n<li>\u30c6\u30b9\u30c8\u306e\u5bb9\u6613\u6027\u5411\u4e0a<\/li>\n\n\n\n<li>\u30b3\u30fc\u30c9\u306e\u518d\u5229\u7528\u6027\u306e\u5411\u4e0a<\/li>\n\n\n\n<li>\u30c1\u30fc\u30e0\u9593\u306e\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3\u6539\u5584<\/li>\n<\/ul>\n\n\n\n<p>\u7279\u306b\u5927\u898f\u6a21\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u3067\u306f\u3001\u3053\u308c\u3089\u306e\u30a2\u30d7\u30ed\u30fc\u30c1\u3092\u6bb5\u968e\u7684\u306b\u5c0e\u5165\u3059\u308b\u3053\u3068\u3067\u3001\u6301\u7d9a\u53ef\u80fd\u306a\u958b\u767a\u4f53\u5236\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,12],"tags":[],"class_list":{"0":"post-2668","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-php-laravel","7":"category-php","8":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2668","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2668"}],"version-history":[{"count":2,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2668\/revisions"}],"predecessor-version":[{"id":2670,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/2668\/revisions\/2670"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}