protected function get_attribute_value_info($value, $depth = 0)
{
// If the recursion limit is succeeded, then the value is invalid
if ($depth > 1)
{
return null;
}
// Handle objects (including DynamoDB Binary types)
if (is_object($value))
{
if ($value instanceof DynamoDB_Binary || $value instanceof DynamoDB_BinarySet)
{
$type = ($value instanceof DynamoDB_Binary) ? self::TYPE_BINARY : self::TYPE_BINARY_SET;
return array(
'value' => $value->{$type},
'type' => $type
);
}
elseif ($value instanceof Traversable)
{
$value = iterator_to_array($value);
}
elseif (method_exists($value, '__toString'))
{
$value = (string) $value;
}
else
{
return null;
}
}
// Handle empty values (zeroes are OK though) and resources
if ($value === null || $value === array() || $value === '' || is_resource($value))
{
return null;
}
// Create the attribute value info
$info = array();
// Handle boolean values
if (is_bool($value))
{
$info['type'] = self::TYPE_NUMBER;
$info['value'] = $value ? '1' : '0';
}
// Handle numeric values
elseif (is_int($value) || is_float($value))
{
$info['type'] = self::TYPE_NUMBER;
$info['value'] = (string) $value;
}
// Handle arrays
elseif (is_array($value))
{
$set_type = null;
$info['value'] = array();
// Loop through each value to analyze and prepare it
foreach ($value as $sub_value)
{
// Recursively get the info for this sub-value. The depth param only allows one level of recursion
$sub_info = $this->get_attribute_value_info($sub_value, $depth + 1);
// If a sub-value is invalid, the whole array is invalid as well
if ($sub_info === null)
{
return null;
}
// The type of each sub-value must be the same, or else the whole array is invalid
if ($set_type === null)
{
$set_type = $sub_info['type'];
}
elseif ($set_type !== $sub_info['type'])
{
return null;
}
// Save the value for the upstream array
$info['value'][] = $sub_info['value'];
}
// Make sure the type is changed to be the appropriate array/set type
$info['type'] = $set_type . self::SUFFIX_FOR_TYPES;
}
// Handle strings
else
{
$info = array('value' => (string) $value, 'type' => self::TYPE_STRING);
}
return $info;
}