Serializer.php 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. /**
  3. * @copyright Vertex. All rights reserved. https://www.vertexinc.com/
  4. * @author Mediotype https://www.mediotype.com/
  5. */
  6. namespace Vertex\Tax\Model\Cache;
  7. /**
  8. * Handle data exchange serialization for StorageInterface.
  9. *
  10. * This is a compatibility fill for unsupported SerializerInterface in Magento < 2.2.
  11. */
  12. class Serializer
  13. {
  14. const MAX_ARRAY_DEPTH = 255;
  15. /**
  16. * Declaration of accepted types for serialization.
  17. *
  18. * @var array
  19. */
  20. private $supportedTypes = [
  21. 'string',
  22. 'integer',
  23. 'double',
  24. 'boolean',
  25. 'NULL',
  26. 'array',
  27. 'object',
  28. ];
  29. /**
  30. * {@inheritdoc}
  31. */
  32. public function serialize($data)
  33. {
  34. $this->validate($data);
  35. return \json_encode($data);
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function unserialize($string)
  41. {
  42. // Resets last error state
  43. \json_decode('{}');
  44. $result = \json_decode($string, false);
  45. if (\json_last_error() !== JSON_ERROR_NONE) {
  46. throw new \InvalidArgumentException('Cannot unserialize input');
  47. }
  48. return $result;
  49. }
  50. /**
  51. * Perform input validation to ensure that only supported data types are accepted for serialization.
  52. *
  53. * @param mixed $input
  54. * @param int $depth
  55. * @return void
  56. * @throws \InvalidArgumentException
  57. */
  58. private function validate($input, $depth = 0)
  59. {
  60. if (!in_array(gettype($input), $this->supportedTypes)) {
  61. throw new \InvalidArgumentException(
  62. sprintf('Cannot serialize unsupported type "%s"', gettype($input))
  63. );
  64. } elseif (gettype($input) === 'object' && !($input instanceof \stdClass)) {
  65. throw new \InvalidArgumentException(
  66. sprintf('Cannot serialize unsupported object type "%s"', get_class($input))
  67. );
  68. } elseif (gettype($input) === 'array') {
  69. $depth++;
  70. if ($depth > self::MAX_ARRAY_DEPTH) {
  71. throw new \InvalidArgumentException(
  72. sprintf('Serializable array depth cannot exceed %d', self::MAX_ARRAY_DEPTH)
  73. );
  74. }
  75. foreach ($input as $item) {
  76. $this->validate($item, $depth);
  77. }
  78. }
  79. }
  80. }