Skip to content

Commit ee8f63b

Browse files
committed
v3.7.0-rc.3
1 parent c243877 commit ee8f63b

File tree

1 file changed

+48
-7
lines changed

1 file changed

+48
-7
lines changed

src/Google/Protobuf/Internal/Message.php

+48-7
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,12 @@ private function convertJsonValueToProtoValue(
976976
* ]);
977977
* ```
978978
*
979+
* This method will trigger an error if it is passed data that cannot
980+
* be converted to the correct type. For example, a StringValue field
981+
* must receive data that is either a string or a StringValue object.
982+
*
979983
* @param array $array An array containing message properties and values.
980984
* @return null.
981-
* @throws \Exception Invalid data.
982985
*/
983986
protected function mergeFromArray(array $array)
984987
{
@@ -990,22 +993,61 @@ protected function mergeFromArray(array $array)
990993
'Invalid message property: ' . $key);
991994
}
992995
$setter = $field->getSetter();
993-
if ($field->isWrapperType()) {
994-
self::normalizeToMessageType($value, $field->getMessageType()->getClass());
996+
if ($field->isMap()) {
997+
$valueField = $field->getMessageType()->getFieldByName('value');
998+
if (!is_null($valueField) && $valueField->isWrapperType()) {
999+
self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()->getClass());
1000+
}
1001+
} elseif ($field->isWrapperType()) {
1002+
$class = $field->getMessageType()->getClass();
1003+
if ($field->isRepeated()) {
1004+
self::normalizeArrayElementsToMessageType($value, $class);
1005+
} else {
1006+
self::normalizeToMessageType($value, $class);
1007+
}
9951008
}
9961009
$this->$setter($value);
9971010
}
9981011
}
9991012

1013+
/**
1014+
* Tries to normalize the elements in $value into a provided protobuf
1015+
* wrapper type $class. If $value is any type other than array, we do
1016+
* not do any conversion, and instead rely on the existing protobuf
1017+
* type checking. If $value is an array, we process each element and
1018+
* try to convert it to an instance of $class.
1019+
*
1020+
* @param mixed $value The array of values to normalize.
1021+
* @param string $class The expected wrapper class name
1022+
*/
1023+
private static function normalizeArrayElementsToMessageType(&$value, $class)
1024+
{
1025+
if (!is_array($value)) {
1026+
// In the case that $value is not an array, we do not want to
1027+
// attempt any conversion. Note that this includes the cases
1028+
// when $value is a RepeatedField of MapField. In those cases,
1029+
// we do not need to convert the elements, as they should
1030+
// already be the correct types.
1031+
return;
1032+
} else {
1033+
// Normalize each element in the array.
1034+
foreach ($value as $key => &$elementValue) {
1035+
self::normalizeToMessageType($elementValue, $class);
1036+
}
1037+
}
1038+
}
1039+
10001040
/**
10011041
* Tries to normalize $value into a provided protobuf wrapper type $class.
10021042
* If $value is any type other than an object, we attempt to construct an
10031043
* instance of $class and assign $value to it using the setValue method
10041044
* shared by all wrapper types.
10051045
*
1046+
* This method will raise an error if it receives a type that cannot be
1047+
* assigned to the wrapper type via setValue.
1048+
*
10061049
* @param mixed $value The value to normalize.
10071050
* @param string $class The expected wrapper class name
1008-
* @throws \Exception If $value cannot be converted to a wrapper type
10091051
*/
10101052
private static function normalizeToMessageType(&$value, $class)
10111053
{
@@ -1022,10 +1064,9 @@ private static function normalizeToMessageType(&$value, $class)
10221064
$value = $msg;
10231065
return;
10241066
} catch (\Exception $exception) {
1025-
throw new \Exception(
1067+
trigger_error(
10261068
"Error normalizing value to type '$class': " . $exception->getMessage(),
1027-
$exception->getCode(),
1028-
$exception
1069+
E_USER_ERROR
10291070
);
10301071
}
10311072
}

0 commit comments

Comments
 (0)