Guid.php 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. /**
  3. * @package Kohana/ORM
  4. * @author Koseven Team
  5. * @copyright (c) 2016-2018 Koseven Team
  6. * @license https://koseven.ga/LICENSE.md
  7. */
  8. class ORM_Behavior_Guid extends ORM_Behavior {
  9. /**
  10. * Table column for GUID value
  11. * @var string
  12. */
  13. protected $_guid_column = 'guid';
  14. /**
  15. * Allow model creaton on guid key only
  16. * @var boolean
  17. */
  18. protected $_guid_only = TRUE;
  19. /**
  20. * Constructs a behavior object
  21. *
  22. * @param array $config Configuration parameters
  23. */
  24. protected function __construct($config)
  25. {
  26. parent::__construct($config);
  27. $this->_guid_column = Arr::get($config, 'column', $this->_guid_column);
  28. $this->_guid_only = Arr::get($config, 'guid_only', $this->_guid_only);
  29. }
  30. /**
  31. * Constructs a new model and loads a record if given
  32. *
  33. * @param ORM $model The model
  34. * @param mixed $id Parameter for find or object to load
  35. */
  36. public function on_construct($model, $id)
  37. {
  38. if (($id !== NULL) AND ! is_array($id) AND ! ctype_digit($id))
  39. {
  40. if (UUID::valid($id))
  41. {
  42. $model->where($this->_guid_column, '=', $id)->find();
  43. // Prevent further record loading
  44. return FALSE;
  45. }
  46. }
  47. return TRUE;
  48. }
  49. /**
  50. * The model is updated, add a guid value if empty
  51. *
  52. * @param ORM $model The model
  53. */
  54. public function on_update($model)
  55. {
  56. $this->create_guid($model);
  57. }
  58. /**
  59. * A new model is created, add a guid value
  60. *
  61. * @param ORM $model The model
  62. */
  63. public function on_create($model)
  64. {
  65. $this->create_guid($model);
  66. }
  67. private function create_guid($model)
  68. {
  69. $current_guid = $model->get($this->_guid_column);
  70. // Try to create a new GUID
  71. $query = DB::select()->from($model->table_name())
  72. ->where($this->_guid_column, '=', ':guid')
  73. ->limit(1);
  74. while (empty($current_guid))
  75. {
  76. $random_bytes = random_bytes(16);
  77. $random_bytes[6] = chr((ord($random_bytes[6]) & 0x0f) | 0x40);
  78. $random_bytes[8] = chr((ord($random_bytes[8]) & 0x3f) | 0x80);
  79. $current_guid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($random_bytes), 4));
  80. $query->param(':guid', $current_guid);
  81. if ($query->execute()->get($model->primary_key(), FALSE) !== FALSE)
  82. {
  83. Log::instance()->add(Log::NOTICE, 'Duplicate GUID created for '.$model->table_name());
  84. $current_guid = '';
  85. }
  86. }
  87. $model->set($this->_guid_column, $current_guid);
  88. }
  89. }