Skip to content

Commit eab0925

Browse files
silinmykolaandrewbess
authored andcommitted
Fix call_user_func_array call in lib
1 parent cd5f68a commit eab0925

File tree

3 files changed

+65
-112
lines changed

3 files changed

+65
-112
lines changed

lib/internal/Magento/Framework/Data/Collection.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ public function walk($callback, array $args = [])
512512
$cb = $callback;
513513
array_unshift($params, $item);
514514
}
515-
$results[$id] = call_user_func_array($cb, $params);
515+
// The `array_values` is a workaround to ensure the same behavior in PHP 7 and 8.
516+
$results[$id] = call_user_func_array($cb, array_values($params));
516517
}
517518
return $results;
518519
}

lib/internal/Magento/Framework/MessageQueue/Consumer.php

Lines changed: 40 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
*/
66
namespace Magento\Framework\MessageQueue;
77

8+
use Exception;
9+
use Magento\Framework\App\ObjectManager;
810
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\Communication\ConfigInterface as CommunicationConfig;
912
use Magento\Framework\Exception\LocalizedException;
10-
use Magento\Framework\Phrase;
13+
use Magento\Framework\Exception\NotFoundException;
1114
use Magento\Framework\MessageQueue\Consumer\ConfigInterface as ConsumerConfig;
12-
use Magento\Framework\Communication\ConfigInterface as CommunicationConfig;
13-
use Magento\Framework\MessageQueue\QueueRepository;
15+
use Magento\Framework\Phrase;
1416
use Psr\Log\LoggerInterface;
1517

1618
/**
@@ -84,7 +86,13 @@ class Consumer implements ConsumerInterface
8486
* @param MessageEncoder $messageEncoder
8587
* @param ResourceConnection $resource
8688
* @param ConsumerConfigurationInterface $configuration
87-
* @param LoggerInterface $logger
89+
* @param LoggerInterface|null $logger
90+
* @param ConsumerConfig|null $consumerConfig
91+
* @param CommunicationConfig|null $communicationConfig
92+
* @param QueueRepository|null $queueRepository
93+
* @param MessageController|null $messageController
94+
* @param MessageValidator|null $messageValidator
95+
* @param EnvelopeFactory|null $envelopeFactory
8896
*
8997
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
9098
*/
@@ -93,13 +101,26 @@ public function __construct(
93101
MessageEncoder $messageEncoder,
94102
ResourceConnection $resource,
95103
ConsumerConfigurationInterface $configuration,
96-
LoggerInterface $logger = null
104+
LoggerInterface $logger = null,
105+
ConsumerConfig $consumerConfig = null,
106+
CommunicationConfig $communicationConfig = null,
107+
QueueRepository $queueRepository = null,
108+
MessageController $messageController = null,
109+
MessageValidator $messageValidator = null,
110+
EnvelopeFactory $envelopeFactory = null
97111
) {
98112
$this->invoker = $invoker;
99113
$this->messageEncoder = $messageEncoder;
100114
$this->resource = $resource;
101115
$this->configuration = $configuration;
102-
$this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class);
116+
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
117+
$this->consumerConfig = $consumerConfig ?: ObjectManager::getInstance()->get(ConsumerConfig::class);
118+
$this->communicationConfig = $communicationConfig
119+
?: ObjectManager::getInstance()->get(CommunicationConfig::class);
120+
$this->queueRepository = $queueRepository ?: ObjectManager::getInstance()->get(QueueRepository::class);
121+
$this->messageController = $messageController ?: ObjectManager::getInstance()->get(MessageController::class);
122+
$this->messageValidator = $messageValidator ?: ObjectManager::getInstance()->get(MessageValidator::class);
123+
$this->envelopeFactory = $envelopeFactory ?: ObjectManager::getInstance()->get(EnvelopeFactory::class);
103124
}
104125

105126
/**
@@ -142,7 +163,8 @@ private function dispatchMessage(EnvelopeInterface $message, $isSync = false)
142163
$messageSchemaType = $this->configuration->getMessageSchemaType($topicName);
143164
if ($messageSchemaType == CommunicationConfig::TOPIC_REQUEST_TYPE_METHOD) {
144165
foreach ($handlers as $callback) {
145-
$result = call_user_func_array($callback, $decodedMessage);
166+
// The `array_values` is a workaround to ensure the same behavior in PHP 7 and 8.
167+
$result = call_user_func_array($callback, array_values($decodedMessage));
146168
return $this->processSyncResponse($topicName, $result);
147169
}
148170
} else {
@@ -168,7 +190,7 @@ private function dispatchMessage(EnvelopeInterface $message, $isSync = false)
168190
private function processSyncResponse($topicName, $result)
169191
{
170192
if (isset($result)) {
171-
$this->getMessageValidator()->validate($topicName, $result, false);
193+
$this->messageValidator->validate($topicName, $result, false);
172194
return $this->messageEncoder->encode($topicName, $result, false);
173195
} else {
174196
throw new LocalizedException(new Phrase('No reply message resulted in RPC.'));
@@ -179,14 +201,15 @@ private function processSyncResponse($topicName, $result)
179201
* Send RPC response message.
180202
*
181203
* @param EnvelopeInterface $envelope
204+
*
182205
* @return void
206+
* @throws LocalizedException
183207
*/
184208
private function sendResponse(EnvelopeInterface $envelope)
185209
{
186210
$messageProperties = $envelope->getProperties();
187-
$connectionName = $this->getConsumerConfig()
188-
->getConsumer($this->configuration->getConsumerName())->getConnection();
189-
$queue = $this->getQueueRepository()->get($connectionName, $messageProperties['reply_to']);
211+
$connectionName = $this->consumerConfig->getConsumer($this->configuration->getConsumerName())->getConnection();
212+
$queue = $this->queueRepository->get($connectionName, $messageProperties['reply_to']);
190213
$queue->push($envelope);
191214
}
192215

@@ -203,12 +226,12 @@ private function getTransactionCallback(QueueInterface $queue)
203226
$lock = null;
204227
try {
205228
$topicName = $message->getProperties()['topic_name'];
206-
$topicConfig = $this->getCommunicationConfig()->getTopic($topicName);
207-
$lock = $this->getMessageController()->lock($message, $this->configuration->getConsumerName());
229+
$topicConfig = $this->communicationConfig->getTopic($topicName);
230+
$lock = $this->messageController->lock($message, $this->configuration->getConsumerName());
208231

209232
if ($topicConfig[CommunicationConfig::TOPIC_IS_SYNCHRONOUS]) {
210233
$responseBody = $this->dispatchMessage($message, true);
211-
$responseMessage = $this->getEnvelopeFactory()->create(
234+
$responseMessage = $this->envelopeFactory->create(
212235
['body' => $responseBody, 'properties' => $message->getProperties()]
213236
);
214237
$this->sendResponse($responseMessage);
@@ -224,15 +247,15 @@ private function getTransactionCallback(QueueInterface $queue)
224247
$queue->acknowledge($message);
225248
} catch (MessageLockException $exception) {
226249
$queue->acknowledge($message);
227-
} catch (\Magento\Framework\MessageQueue\ConnectionLostException $e) {
250+
} catch (ConnectionLostException $e) {
228251
if ($lock) {
229252
$this->resource->getConnection()
230253
->delete($this->resource->getTableName('queue_lock'), ['id = ?' => $lock->getId()]);
231254
}
232-
} catch (\Magento\Framework\Exception\NotFoundException $e) {
255+
} catch (NotFoundException $e) {
233256
$queue->acknowledge($message);
234257
$this->logger->warning($e->getMessage());
235-
} catch (\Exception $e) {
258+
} catch (Exception $e) {
236259
$queue->reject($message, false, $e->getMessage());
237260
if ($lock) {
238261
$this->resource->getConnection()
@@ -241,98 +264,4 @@ private function getTransactionCallback(QueueInterface $queue)
241264
}
242265
};
243266
}
244-
245-
/**
246-
* Get consumer config.
247-
*
248-
* @return ConsumerConfig
249-
*
250-
* @deprecated 103.0.0
251-
*/
252-
private function getConsumerConfig()
253-
{
254-
if ($this->consumerConfig === null) {
255-
$this->consumerConfig = \Magento\Framework\App\ObjectManager::getInstance()->get(ConsumerConfig::class);
256-
}
257-
return $this->consumerConfig;
258-
}
259-
260-
/**
261-
* Get communication config.
262-
*
263-
* @return CommunicationConfig
264-
*
265-
* @deprecated 103.0.0
266-
*/
267-
private function getCommunicationConfig()
268-
{
269-
if ($this->communicationConfig === null) {
270-
$this->communicationConfig = \Magento\Framework\App\ObjectManager::getInstance()
271-
->get(CommunicationConfig::class);
272-
}
273-
return $this->communicationConfig;
274-
}
275-
276-
/**
277-
* Get queue repository.
278-
*
279-
* @return QueueRepository
280-
*
281-
* @deprecated 103.0.0
282-
*/
283-
private function getQueueRepository()
284-
{
285-
if ($this->queueRepository === null) {
286-
$this->queueRepository = \Magento\Framework\App\ObjectManager::getInstance()->get(QueueRepository::class);
287-
}
288-
return $this->queueRepository;
289-
}
290-
291-
/**
292-
* Get message controller.
293-
*
294-
* @return MessageController
295-
*
296-
* @deprecated 103.0.0
297-
*/
298-
private function getMessageController()
299-
{
300-
if ($this->messageController === null) {
301-
$this->messageController = \Magento\Framework\App\ObjectManager::getInstance()
302-
->get(MessageController::class);
303-
}
304-
return $this->messageController;
305-
}
306-
307-
/**
308-
* Get message validator.
309-
*
310-
* @return MessageValidator
311-
*
312-
* @deprecated 103.0.0
313-
*/
314-
private function getMessageValidator()
315-
{
316-
if ($this->messageValidator === null) {
317-
$this->messageValidator = \Magento\Framework\App\ObjectManager::getInstance()
318-
->get(MessageValidator::class);
319-
}
320-
return $this->messageValidator;
321-
}
322-
323-
/**
324-
* Get envelope factory.
325-
*
326-
* @return EnvelopeFactory
327-
*
328-
* @deprecated 103.0.0
329-
*/
330-
private function getEnvelopeFactory()
331-
{
332-
if ($this->envelopeFactory === null) {
333-
$this->envelopeFactory = \Magento\Framework\App\ObjectManager::getInstance()
334-
->get(EnvelopeFactory::class);
335-
}
336-
return $this->envelopeFactory;
337-
}
338267
}

lib/internal/Magento/Framework/Test/Unit/Data/CollectionTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\Framework\Test\Unit\Data;
99

10+
use Exception;
1011
use Magento\Framework\Data\Collection;
1112
use Magento\Framework\Data\Collection\EntityFactoryInterface;
1213
use Magento\Framework\DataObject;
@@ -56,6 +57,28 @@ public function testWalk()
5657
);
5758
}
5859

60+
/**
61+
* Test that callback function works correctly with associative array in method params on php 8.0
62+
*
63+
* @throws Exception
64+
*/
65+
public function testWalkWithAssociativeArrayInParameter()
66+
{
67+
$elementOne = new DataObject(['id' => 1, 'name' => 'firstElement']);
68+
$elementTwo = new DataObject(['id' => 2, 'name' => 'secondElement']);
69+
$elementThree = new DataObject(['id' => 3, 'name' => 'thirdElement']);
70+
$this->collection->addItem($elementOne);
71+
$this->collection->addItem($elementTwo);
72+
$this->collection->addItem($elementThree);
73+
$this->collection->walk([$this, 'modifyObjectNames'], ['testPrefix' => 'test prefix']);
74+
$expectedNames = [
75+
'test prefix firstElement',
76+
'test prefix secondElement',
77+
'test prefix thirdElement'
78+
];
79+
$this->assertEquals($expectedNames, $this->collection->getColumnValues('name'));
80+
}
81+
5982
/**
6083
* Ensure that getSize works correctly with clear
6184
*

0 commit comments

Comments
 (0)