PluginProbe
Packeta / 2.0.9
Packeta v2.0.9
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / src / Packetery / Module / Shipping / ShippingProvider.php

ShippingProvider.php in Packeta 2.0.9, at src/Packetery/Module/Shipping/ShippingProvider.php

243 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare( strict_types=1 );
4
5 namespace Packetery\Module\Shipping;
6
7 use Packetery\Core\Entity\Carrier;
8 use Packetery\Module\Carrier\CarDeliveryConfig;
9 use Packetery\Module\Carrier\CarrierOptionsFactory;
10 use Packetery\Module\Carrier\EntityRepository;
11 use Packetery\Module\Carrier\PacketaPickupPointsConfig;
12 use Packetery\Module\ContextResolver;
13 use Packetery\Module\Options\FlagManager\FeatureFlagProvider;
14 use Packetery\Module\ShippingMethod;
15 use Packetery\Module\ShippingZoneRepository;
16 use WC_Order;
17
18 class ShippingProvider {
19
20 /**
21 * @var FeatureFlagProvider
22 */
23 private $featureFlagProvider;
24
25 /**
26 * @var PacketaPickupPointsConfig
27 */
28 private $pickupPointConfig;
29
30 /**
31 * @var CarDeliveryConfig
32 */
33 private $carDeliveryConfig;
34
35 /**
36 * @var ContextResolver
37 */
38 private $contextResolver;
39
40 /**
41 * @var ShippingZoneRepository
42 */
43 private $shippingZoneRepository;
44
45 /**
46 * @var EntityRepository
47 */
48 private $carrierRepository;
49
50 /**
51 * @var CarrierOptionsFactory
52 */
53 private $carrierOptionsFactory;
54
55 public function __construct(
56 FeatureFlagProvider $featureFlagProvider,
57 PacketaPickupPointsConfig $pickupPointConfig,
58 CarDeliveryConfig $carDeliveryConfig,
59 ContextResolver $contextResolver,
60 ShippingZoneRepository $shippingZoneRepository,
61 EntityRepository $carrierRepository,
62 CarrierOptionsFactory $carrierOptionsFactory
63 ) {
64 $this->featureFlagProvider = $featureFlagProvider;
65 $this->pickupPointConfig = $pickupPointConfig;
66 $this->carDeliveryConfig = $carDeliveryConfig;
67 $this->contextResolver = $contextResolver;
68 $this->shippingZoneRepository = $shippingZoneRepository;
69 $this->carrierRepository = $carrierRepository;
70 $this->carrierOptionsFactory = $carrierOptionsFactory;
71 }
72
73 /**
74 * Loads generated shipping methods, including split ones when split is off.
75 * Used in CLI generator.
76 */
77 public static function loadAllClasses(): void {
78 $generatedClassesPath = __DIR__ . '/Generated';
79 foreach ( scandir( $generatedClassesPath ) as $filename ) {
80 if ( preg_match( '/\.php$/', $filename ) ) {
81 require_once $generatedClassesPath . '/' . $filename;
82 }
83 }
84 }
85
86 /**
87 * Loads generated shipping methods.
88 */
89 public function loadClasses(): void {
90 $generatedClassesPath = __DIR__ . '/Generated';
91 foreach ( scandir( $generatedClassesPath ) as $filename ) {
92 if ( ! preg_match( '/\.php$/', $filename ) ) {
93 continue;
94 }
95 if ( $this->carDeliveryConfig->isDisabled() ) {
96 $carDeliveryIds = implode( '|', Carrier::CAR_DELIVERY_CARRIERS );
97 if ( preg_match( '/^ShippingMethod_(' . $carDeliveryIds . ')\.php$/', $filename ) ) {
98 continue;
99 }
100 }
101 if ( $this->featureFlagProvider->isSplitActive() === false ) {
102 $internalCountries = implode( '|', $this->pickupPointConfig->getInternalCountries() );
103 $vendorGroups = Carrier::VENDOR_GROUP_ZPOINT . '|' . Carrier::VENDOR_GROUP_ZBOX;
104 if ( preg_match( '/^ShippingMethod_(' . $internalCountries . ')(' . $vendorGroups . ')\.php$/', $filename ) ) {
105 continue;
106 }
107 }
108 require_once $generatedClassesPath . '/' . $filename;
109 }
110 }
111
112 /**
113 * Gets all full classnames of generated shipping methods.
114 */
115 private function getGeneratedClassnames(): array {
116 $namespace = __NAMESPACE__ . '\Generated';
117
118 return array_filter(
119 get_declared_classes(),
120 function ( $fullyQualifiedClassname ) use ( $namespace ) {
121 return strpos( $fullyQualifiedClassname, $namespace ) === 0;
122 }
123 );
124 }
125
126 /**
127 * Checks if provided order uses our shipping method like native has_shipping_method method.
128 */
129 public static function wcOrderHasOurMethod( WC_Order $wcOrder ): bool {
130 foreach ( $wcOrder->get_shipping_methods() as $shippingMethod ) {
131 if ( self::isPacketaMethod( $shippingMethod->get_method_id() ) ) {
132 return true;
133 }
134 }
135
136 return false;
137 }
138
139 /**
140 * Checks if provided shipping method id belongs to one of Packeta methods.
141 */
142 public static function isPacketaMethod( string $methodId ): bool {
143 return (
144 $methodId === ShippingMethod::PACKETERY_METHOD_ID ||
145 strpos( $methodId, BaseShippingMethod::PACKETA_METHOD_PREFIX ) === 0
146 );
147 }
148
149 /**
150 * Loads shipping methods, uses different approach for zone setting page.
151 *
152 * @param array<string, string> $methods Previous state.
153 *
154 * @return array<string, string>
155 */
156 public function addMethods( array $methods ): array {
157 $zoneId = $this->contextResolver->getShippingZoneId();
158 if ( $zoneId === null ) {
159 return $this->addAllMethods( $methods );
160 }
161
162 $allowedCountries = $this->shippingZoneRepository->getCountryCodesForShippingZone( $zoneId );
163 if ( $allowedCountries === [] ) {
164 return $this->addAllMethods( $methods );
165 }
166
167 foreach ( $allowedCountries as $countryCode ) {
168 $carriers = $this->carrierRepository->getByCountryIncludingNonFeed( $countryCode );
169 foreach ( $carriers as $carrier ) {
170 foreach ( $this->getGeneratedClassnames() as $fullyQualifiedClassname ) {
171 if ( $carrier->getId() === $fullyQualifiedClassname::CARRIER_ID ) {
172 $methods = $this->addActiveCarrierMethod( $fullyQualifiedClassname, $methods );
173
174 break;
175 }
176 }
177 }
178 }
179
180 return $methods;
181 }
182
183 /**
184 * Add shipping methods to array.
185 *
186 * @param array<string, string> $methods Array.
187 *
188 * @return array<string, string>
189 */
190 private function addAllMethods( array $methods ): array {
191 foreach ( $this->getGeneratedClassnames() as $fullyQualifiedClassname ) {
192 $methods = $this->addActiveCarrierMethod( $fullyQualifiedClassname, $methods );
193 }
194
195 return $methods;
196 }
197
198 /**
199 * Adds shipping method to array in case the carrier is active.
200 *
201 * @param string $fullyQualifiedClassname Fully qualified classname.
202 * @param array<string, string> $methods Methods.
203 *
204 * @return array<string, string>
205 */
206 private function addActiveCarrierMethod( string $fullyQualifiedClassname, array $methods ): array {
207 /**
208 * Generated shipping method.
209 *
210 * @var BaseShippingMethod $fullyQualifiedClassname
211 */
212 // @phpstan-ignore-next-line
213 $carrierOptions = $this->carrierOptionsFactory->createByCarrierId( $fullyQualifiedClassname::CARRIER_ID );
214 if ( $carrierOptions->isActive() ) {
215 $methods[ $fullyQualifiedClassname::getShippingMethodId() ] = $fullyQualifiedClassname;
216 }
217
218 return $methods;
219 }
220
221 /**
222 * Sort classnames by method_title property.
223 *
224 * @param array<string, string> $methods Methods to sort.
225 *
226 * @return array<string, string>
227 */
228 public function sortMethods( array $methods ): array {
229 uasort(
230 $methods,
231 function ( $classA, $classB ) {
232 $objectA = new $classA();
233 $objectB = new $classB();
234
235 // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
236 return strcmp( $objectA->method_title, $objectB->method_title );
237 }
238 );
239
240 return $methods;
241 }
242 }
243