11<?php
22
3+ declare (strict_types=1 );
4+
35/**
46 * Example: E-commerce Order Processing with Groups and Nested Flows
5- *
7+ *
68 * This example demonstrates a complete e-commerce order processing workflow
79 * using step groups and nested flows for modular organization.
810 */
1416// Define reusable step groups
1517Flowpipe::group ('order-validation ' , [
1618 // Validate order has items
17- fn ($ order , $ next ) => $ next (
18- isset ($ order ['items ' ]) && count ($ order ['items ' ]) > 0
19- ? $ order
19+ fn ($ order , $ next ) => $ next (
20+ isset ($ order ['items ' ]) && count ($ order ['items ' ]) > 0
21+ ? $ order
2022 : throw new InvalidArgumentException ('Order must have items ' )
2123 ),
22-
24+
2325 // Validate customer information
24- fn ($ order , $ next ) => $ next (
25- isset ($ order ['customer ' ]) && !empty ($ order ['customer ' ]['email ' ])
26- ? $ order
26+ fn ($ order , $ next ) => $ next (
27+ isset ($ order ['customer ' ]) && ! empty ($ order ['customer ' ]['email ' ])
28+ ? $ order
2729 : throw new InvalidArgumentException ('Customer email required ' )
2830 ),
29-
31+
3032 // Validate order total
31- fn ($ order , $ next ) => $ next (
32- isset ($ order ['total ' ]) && $ order ['total ' ] > 0
33- ? $ order
33+ fn ($ order , $ next ) => $ next (
34+ isset ($ order ['total ' ]) && $ order ['total ' ] > 0
35+ ? $ order
3436 : throw new InvalidArgumentException ('Order total must be greater than 0 ' )
3537 ),
3638]);
3739
3840Flowpipe::group ('inventory-management ' , [
3941 // Check item availability
40- fn ($ order , $ next ) => $ next (array_merge ($ order , [
42+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
4143 'inventory_checked ' => true ,
4244 'items_available ' => true , // Simplified for example
4345 ])),
44-
46+
4547 // Reserve items
46- fn ($ order , $ next ) => $ next (array_merge ($ order , [
48+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
4749 'items_reserved ' => true ,
48- 'reservation_id ' => 'res_ ' . uniqid (),
50+ 'reservation_id ' => 'res_ ' . uniqid (),
4951 ])),
5052]);
5153
5254Flowpipe::group ('order-notifications ' , [
5355 // Send customer confirmation
54- fn ($ order , $ next ) => $ next (array_merge ($ order , [
56+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
5557 'customer_notified ' => true ,
5658 'confirmation_email_sent ' => true ,
5759 ])),
58-
60+
5961 // Notify fulfillment team
60- fn ($ order , $ next ) => $ next (array_merge ($ order , [
62+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
6163 'fulfillment_notified ' => true ,
62- 'fulfillment_ticket ' => 'ticket_ ' . uniqid (),
64+ 'fulfillment_ticket ' => 'ticket_ ' . uniqid (),
6365 ])),
6466]);
6567
8688try {
8789 $ result = Flowpipe::make ()
8890 ->send ($ orderData )
89-
91+
9092 // Step 1: Validate order
9193 ->useGroup ('order-validation ' )
92-
94+
9395 // Step 2: Check and reserve inventory
9496 ->useGroup ('inventory-management ' )
95-
97+
9698 // Step 3: Process payment in nested flow (isolated)
9799 ->nested ([
98100 // Payment processing sub-flow
99- fn ($ order , $ next ) => $ next (array_merge ($ order , [
100- 'payment_id ' => 'pay_ ' . uniqid (),
101+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
102+ 'payment_id ' => 'pay_ ' . uniqid (),
101103 'payment_method ' => 'credit_card ' ,
102104 ])),
103-
104- fn ($ order , $ next ) => $ next (array_merge ($ order , [
105+
106+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
105107 'payment_status ' => 'processed ' ,
106108 'payment_date ' => date ('Y-m-d H:i:s ' ),
107109 ])),
108-
109- fn ($ order , $ next ) => $ next (array_merge ($ order , [
110+
111+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
110112 'transaction_fee ' => round ($ order ['total ' ] * 0.029 , 2 ), // 2.9% fee
111113 ])),
112114 ])
113-
115+
114116 // Step 4: Create order record in nested flow
115117 ->nested ([
116118 // Order creation sub-flow
117- fn ($ order , $ next ) => $ next (array_merge ($ order , [
118- 'order_id ' => 'order_ ' . uniqid (),
119- 'order_number ' => 'ORD- ' . date ('Ymd ' ) . '- ' . rand (1000 , 9999 ),
119+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
120+ 'order_id ' => 'order_ ' . uniqid (),
121+ 'order_number ' => 'ORD- ' . date ('Ymd ' ). '- ' . rand (1000 , 9999 ),
120122 ])),
121-
122- fn ($ order , $ next ) => $ next (array_merge ($ order , [
123+
124+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
123125 'status ' => 'confirmed ' ,
124126 'created_at ' => date ('Y-m-d H:i:s ' ),
125127 ])),
126-
127- fn ($ order , $ next ) => $ next (array_merge ($ order , [
128+
129+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
128130 'estimated_delivery ' => date ('Y-m-d ' , strtotime ('+5 days ' )),
129131 ])),
130132 ])
131-
133+
132134 // Step 5: Send notifications
133135 ->useGroup ('order-notifications ' )
134-
136+
135137 // Step 6: Final processing
136138 ->through ([
137- fn ($ order , $ next ) => $ next (array_merge ($ order , [
139+ fn ($ order , $ next ) => $ next (array_merge ($ order , [
138140 'processing_completed ' => true ,
139141 'completed_at ' => date ('Y-m-d H:i:s ' ),
140142 ])),
141143 ])
142-
144+
143145 ->thenReturn ();
144-
146+
145147 echo "Order processed successfully! \n\n" ;
146148 echo "Final Order Data: \n" ;
147149 print_r ($ result );
148-
150+
149151 echo "\n=== Order Summary === \n" ;
150- echo " Order ID: " . $ result ['order_id ' ] . "\n" ;
151- echo " Order Number: " . $ result ['order_number ' ] . "\n" ;
152- echo " Status: " . $ result ['status ' ] . "\n" ;
153- echo " Payment ID: " . $ result ['payment_id ' ] . "\n" ;
154- echo " Payment Status: " . $ result ['payment_status ' ] . "\n" ;
155- echo " Total: $ " . number_format ($ result ['total ' ], 2 ) . "\n" ;
156- echo " Transaction Fee: $ " . number_format ($ result ['transaction_fee ' ], 2 ) . "\n" ;
157- echo " Estimated Delivery: " . $ result ['estimated_delivery ' ] . "\n" ;
158- echo " Customer Notified: " . ($ result ['customer_notified ' ] ? 'Yes ' : 'No ' ) . "\n" ;
159- echo " Fulfillment Notified: " . ($ result ['fulfillment_notified ' ] ? 'Yes ' : 'No ' ) . "\n" ;
160-
152+ echo ' Order ID: ' . $ result ['order_id ' ]. "\n" ;
153+ echo ' Order Number: ' . $ result ['order_number ' ]. "\n" ;
154+ echo ' Status: ' . $ result ['status ' ]. "\n" ;
155+ echo ' Payment ID: ' . $ result ['payment_id ' ]. "\n" ;
156+ echo ' Payment Status: ' . $ result ['payment_status ' ]. "\n" ;
157+ echo ' Total: $ ' . number_format ($ result ['total ' ], 2 ). "\n" ;
158+ echo ' Transaction Fee: $ ' . number_format ($ result ['transaction_fee ' ], 2 ). "\n" ;
159+ echo ' Estimated Delivery: ' . $ result ['estimated_delivery ' ]. "\n" ;
160+ echo ' Customer Notified: ' . ($ result ['customer_notified ' ] ? 'Yes ' : 'No ' ). "\n" ;
161+ echo ' Fulfillment Notified: ' . ($ result ['fulfillment_notified ' ] ? 'Yes ' : 'No ' ). "\n" ;
162+
161163} catch (Exception $ e ) {
162- echo " Error processing order: " . $ e ->getMessage () . "\n" ;
164+ echo ' Error processing order: ' . $ e ->getMessage (). "\n" ;
163165}
164166
165167echo "\n=== Groups Information === \n" ;
166168echo "Available Groups: \n" ;
167169foreach (Flowpipe::getGroups () as $ groupName => $ steps ) {
168- echo "- $ groupName ( " . count ($ steps ) . " steps) \n" ;
170+ echo "- $ groupName ( " . count ($ steps ). " steps) \n" ;
169171}
170172
171173echo "\n=== Workflow Benefits === \n" ;
172174echo "✓ Modular: Each group handles specific concerns \n" ;
173175echo "✓ Reusable: Groups can be used in different flows \n" ;
174176echo "✓ Isolated: Nested flows provide encapsulation \n" ;
175177echo "✓ Maintainable: Easy to update individual components \n" ;
176- echo "✓ Testable: Each group and nested flow can be tested independently \n" ;
178+ echo "✓ Testable: Each group and nested flow can be tested independently \n" ;
0 commit comments