function cast_and_filter($data, $documentation, $return_default_values = false, $for_output = false)
{
$return_as_object = false;
if (is_object($data)) {
// @todo this should probably be a deep copy if $data can ever have nested objects
$data = (array) $data;
$return_as_object = true;
} elseif (!is_array($data)) {
return $data;
}
$boolean_arg = array('false', 'true');
$naeloob_arg = array('true', 'false');
$return = array();
foreach ($documentation as $key => $description) {
if (is_array($description)) {
// String or boolean array keys only
$whitelist = array_keys($description);
if ($whitelist === $boolean_arg || $whitelist === $naeloob_arg) {
// Truthiness
if (isset($data[$key])) {
$return[$key] = (bool) WPCOM_JSON_API::is_truthy($data[$key]);
} elseif ($return_default_values) {
$return[$key] = $whitelist === $naeloob_arg;
// Default to true for naeloob_arg and false for boolean_arg.
}
} elseif (isset($data[$key]) && isset($description[$data[$key]])) {
// String Key
$return[$key] = (string) $data[$key];
} elseif ($return_default_values) {
// Default value
$return[$key] = (string) current($whitelist);
}
continue;
}
$types = $this->parse_types($description);
$type = array_shift($types);
// Explicit default - string and int only for now. Always set these reguardless of $return_default_values
if (isset($type['default'])) {
if (!isset($data[$key])) {
$data[$key] = $type['default'];
}
}
if (!isset($data[$key])) {
continue;
}
$this->cast_and_filter_item($return, $type, $key, $data[$key], $types, $for_output);
}
if ($return_as_object) {
return (object) $return;
}
return $return;
}