/
ServicesUpdate.php
149 lines (125 loc) · 4.38 KB
/
ServicesUpdate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
/**
* @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
* @copyright Metaways Infosystems GmbH, 2014
* @copyright Aimeos (aimeos.org), 2015-2018
* @package MShop
* @subpackage Plugin
*/
namespace Aimeos\MShop\Plugin\Provider\Order;
/**
* Updates service items on basket change
*
* Delivery or payment service options can be restricted to certain requirements
* like the basket value, the delivery address or if virtual (download) products
* are in the basket. If the service option is not available any more due to one
* of these restrictions, it will be removed from the basket. Otherwise, the
* price of the service option is recalculated.
*
* This plugin interacts with the "Autofill" plugin, which may re-add one of the
* other delivery/payment options automatically, that are still available!
*
* @package MShop
* @subpackage Plugin
*/
class ServicesUpdate
extends \Aimeos\MShop\Plugin\Provider\Factory\Base
implements \Aimeos\MShop\Plugin\Provider\Iface, \Aimeos\MShop\Plugin\Provider\Factory\Iface
{
/**
* Subscribes itself to a publisher
*
* @param \Aimeos\MW\Observer\Publisher\Iface $p Object implementing publisher interface
* @return \Aimeos\MShop\Plugin\Provider\Iface Plugin object for method chaining
*/
public function register( \Aimeos\MW\Observer\Publisher\Iface $p )
{
$plugin = $this->getObject();
$p->attach( $plugin, 'addAddress.after' );
$p->attach( $plugin, 'deleteAddress.after' );
$p->attach( $plugin, 'setAddresses.after' );
$p->attach( $plugin, 'addCoupon.after' );
$p->attach( $plugin, 'deleteCoupon.after' );
$p->attach( $plugin, 'setCoupons.after' );
$p->attach( $plugin, 'setCoupon.after' );
$p->attach( $plugin, 'addProduct.after' );
$p->attach( $plugin, 'deleteProduct.after' );
$p->attach( $plugin, 'setProducts.after' );
return $this;
}
/**
* Receives a notification from a publisher object
*
* @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
* @param string $action Name of the action to listen for
* @param mixed $value Object or value changed in publisher
* @return mixed Modified value parameter
*/
public function update( \Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null )
{
\Aimeos\MW\Common\Base::checkClass( \Aimeos\MShop\Order\Item\Base\Iface::class, $order );
$services = $order->getServices();
if( count( $order->getProducts() ) === 0 )
{
$priceManager = \Aimeos\MShop::create( $this->getContext(), 'price' );
foreach( $services as $type => $list )
{
foreach( $list as $key => $item ) {
$services[$type][$key] = $item->setPrice( $priceManager->createItem() );
}
}
$order->setServices( $services );
return $value;
}
$serviceItems = $this->getServiceItems( $services );
$serviceManager = \Aimeos\MShop::create( $this->getContext(), 'service' );
foreach( $services as $type => $list )
{
foreach( $list as $key => $item )
{
if( isset( $serviceItems[$item->getServiceId()] ) )
{
$serviceItem = $serviceItems[$item->getServiceId()];
$provider = $serviceManager->getProvider( $serviceItem, $serviceItem->getType() );
if( $provider->isAvailable( $order ) ) {
$services[$type][$key] = $item->setPrice( $provider->calcPrice( $order ) );
} else {
unset( $services[$type][$key] );
}
}
else
{
unset( $services[$type][$key] );
}
}
}
$order->setServices( $services );
return $value;
}
/**
* Returns the service items for the given order services
*
* @param array $services Associative list of service types as key and list
* of items implementing \Aimeos\MShop\Order\Item\Base\Service\Iface as values
* @return \Aimeos\MShop\Service\Item\Iface[] List of service items with IDs as keys and items as values
*/
protected function getServiceItems( array $services )
{
$list = [];
foreach( $services as $type => $items )
{
foreach( $items as $service ) {
$list[] = $service->getServiceId();
}
}
if( $list !== [] )
{
$serviceManager = \Aimeos\MShop::create( $this->getContext(), 'service' );
$search = $serviceManager->createSearch( true );
$expr = [$search->compare( '==', 'service.id', $list ), $search->getConditions()];
$search->setConditions( $search->combine( '&&', $expr ) );
$list = $serviceManager->searchItems( $search, ['media', 'price', 'text'] );
}
return $list;
}
}