1. <?php
  2. /**
  3. * Checks collection constraints for backward compatibility in dry-run mode.
  4. *
  5. * @param array $collection The collection to check.
  6. * @param array $constraints An array of constraint definitions. Each constraint should be an associative array
  7. * with keys: 'name' (string), 'type' (string, e.g., 'int', 'string', 'array'),
  8. * 'min' (int, optional), 'max' (int, optional), 'allowed_values' (array, optional).
  9. * @param bool $dry_run Whether to perform a dry run (no actual changes). Defaults to true.
  10. * @return array An array of constraint violations. Each element is an associative array with
  11. * keys: 'name' (string), 'message' (string). Returns an empty array if no violations.
  12. */
  13. function checkCollectionConstraints(array $collection, array $constraints, bool $dry_run = true): array
  14. {
  15. $violations = [];
  16. foreach ($constraints as $constraint) {
  17. $name = $constraint['name'];
  18. $type = $constraint['type'];
  19. switch ($type) {
  20. case 'int':
  21. if (!is_int($collection[$name])) {
  22. $violations[] = ['name' => $name, 'message' => "Expected integer, got " . gettype($collection[$name])];
  23. }
  24. if (isset($constraint['min']) && $collection[$name] < $constraint['min']) {
  25. $violations[] = ['name' => $name, 'message' => "Must be at least " . $constraint['min']];
  26. }
  27. if (isset($constraint['max']) && $collection[$name] > $constraint['max']) {
  28. $violations[] = ['name' => $name, 'message' => "Must be at most " . $constraint['max']];
  29. }
  30. break;
  31. case 'string':
  32. if (!is_string($collection[$name])) {
  33. $violations[] = ['name' => $name, 'message' => "Expected string, got " . gettype($collection[$name])];
  34. }
  35. if (isset($constraint['min_length']) && strlen($collection[$name]) < $constraint['min_length']) {
  36. $violations[] = ['name' => $name, 'message' => "Must be at least " . $constraint['min_length'] . " characters long"];
  37. }
  38. if (isset($constraint['max_length']) && strlen($collection[$name]) > $constraint['max_length']) {
  39. $violations[] = ['name' => $name, 'message' => "Must be at most " . $constraint['max_length'] . " characters long"];
  40. }
  41. break;
  42. case 'array':
  43. if (!is_array($collection[$name])) {
  44. $violations[] = ['name' => $name, 'message' => "Expected array, got " . gettype($collection[$name])];
  45. }
  46. if (isset($constraint['allowed_values'])) {
  47. $allowedValues = $constraint['allowed_values'];
  48. $valid = true;
  49. foreach ($collection[$name] as $item) {
  50. if (!in_array($item, $allowedValues)) {
  51. $valid = false;
  52. break;
  53. }
  54. }
  55. if (!$valid) {
  56. $violations[] = ['name' => $name, 'message' => "Array must contain only values from: " . implode(', ', $allowedValues)];
  57. }
  58. }
  59. break;
  60. default:
  61. // Unknown type - log a warning or handle as needed
  62. error_log("Unknown constraint type: " . $type);
  63. break;
  64. }
  65. }
  66. return $violations;
  67. }
  68. //Example usage (dry run)
  69. $collection = [
  70. 'age' => 30,
  71. 'name' => 'John Doe',
  72. 'tags' => ['tag1', 'tag2', 'invalid_tag'],
  73. 'score' => 150
  74. ];
  75. $constraints = [
  76. ['name' => 'age', 'type' => 'int', 'min' => 18, 'max' => 100],
  77. ['name' => 'name', 'type' => 'string', 'min_length' => 3, 'max_length' => 20],
  78. ['name' => 'tags', 'type'

Add your comment